Maven+Spring+MySql 登陆实例

时间:2023-03-10 01:18:00
Maven+Spring+MySql 登陆实例

  近来无事,复习复习Spring相关知识,从《Spring企业应用开发实战》这本书开始。

  本文为学习《Spring企业应用开发实战》总结,著作权归原作者。

一、用Maven建立web项目

  此处参考 张果 博客,在此表示感谢。原文地址:http://www.cnblogs.com/best/p/5638827.html

1.点击“File”->“New”->"Other"->输入“Maven”,新建一个“Maven Project”,如下图所示:

Maven+Spring+MySql 登陆实例

2.请勾选“Create a simple project”,创建一个简单的项目,不使用模板。也可以使用模板,选择WebApp,不过这里就不应该勾选。如下图所示:

Maven+Spring+MySql 登陆实例

3.填写好包名、项目名,选择打包类型为:war,如下图所示:

Maven+Spring+MySql 登陆实例

4.项目创建好后可能会发现有错误,选择项目,右键“属性properties”->"层面Project Facets"->"Java"修改版本号为1.8,默认为1.5;点击“Ok”保存后关闭。如下图所示:

Maven+Spring+MySql 登陆实例

5.重复上一个步骤,反勾Dynamic Web Module,将项目暂时变成非Web项目。点击“Ok”保存后关闭。

Maven+Spring+MySql 登陆实例

6.重复上一步骤,再进层面属性,勾选“Dynamic Web Module”选择Version为3.0。点击左下角的超链接“Further Configuration available...“。

Maven+Spring+MySql 登陆实例

7.勾选“Generate web.xml deployment descriptor”生成web.xml部署描述文件。点击“Ok”保存后关闭。

Maven+Spring+MySql 登陆实例

8.将生成的WebContent目录下的两个文件夹“META-INF”与“WEB-INF”复制到src/main/webapp目录下。

Maven+Spring+MySql 登陆实例

9.删除WebContent目录。

Maven+Spring+MySql 登陆实例

10.删除后会发现项目的pom.xml文件报错,是因为找不到指定位置的web.xml文件引起的。再进入项目的属性,选择“Deployment Assembly”项目部署项,删除“src/test/java”、“src/test/resources”与“WebContent”目录,因为这三项不需要部署出去。

Maven+Spring+MySql 登陆实例

11.点击“Add添加”后选择“Folder文件夹”为项目的最终部署结果指定Web内容根文件夹。

Maven+Spring+MySql 登陆实例

12.选择src\main\webapp目录为目标目录,点击“Finish完成”保存并关闭。

Maven+Spring+MySql 登陆实例

13.如果此时项目还报错,随便修改pom.xml文件后保存后应该错误会消失。

14.此后项目运行需要添加tomcat运行环境就不赘述了。

二、类包规划,添加依赖,数据库准备

1.类包规划

Maven+Spring+MySql 登陆实例

2.pom.xml中添加lib依赖

 <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>com.adam</groupId>
<artifactId>Chapter2</artifactId>
<version>0.0.1-SNAPSHOT</version>
<packaging>war</packaging>
<properties>
<!-- springframe 版本控制 -->
<spring.version>4.1.1.RELEASE</spring.version>
</properties> <dependencies>
<!-- springframe start -->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-core</artifactId>
<version>${spring.version}</version>
</dependency> <dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-web</artifactId>
<version>${spring.version}</version>
</dependency> <dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-oxm</artifactId>
<version>${spring.version}</version>
</dependency> <dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-tx</artifactId>
<version>${spring.version}</version>
</dependency> <dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-jdbc</artifactId>
<version>${spring.version}</version>
</dependency> <dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-webmvc</artifactId>
<version>${spring.version}</version>
</dependency> <dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-aop</artifactId>
<version>${spring.version}</version>
</dependency> <dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context-support</artifactId>
<version>${spring.version}</version>
</dependency> <dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-test</artifactId>
<version>${spring.version}</version>
</dependency>
<!-- springframe end --> <!--mysql数据库驱动 -->
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>5.1.38</version>
</dependency>
<!--log4j日志包 -->
<dependency>
<groupId>org.apache.logging.log4j</groupId>
<artifactId>log4j-core</artifactId>
<version>2.6.1</version>
</dependency>
<!-- JUnit单元测试工具 -->
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.10</version>
</dependency>
<!-- aspectJ AOP 织入器 -->
<dependency>
<groupId>org.aspectj</groupId>
<artifactId>aspectjweaver</artifactId>
<version>1.8.9</version>
</dependency>
<!-- jstl -->
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>jstl</artifactId>
<version>1.2</version>
</dependency>
</dependencies> <build>
<plugins>
<!-- define the project compile level -->
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>2.3.2</version>
<configuration>
<source>1.8</source>
<target>1.8</target>
</configuration>
</plugin>
</plugins>
</build>
</project>

  如果eclise没有自动下载jar包,右键“属性properties”->"Maven"->"Update Project..",强制更新。

3.数据库准备

  建立数据库sampledb,添加两张表,结构如下:

Maven+Spring+MySql 登陆实例

Maven+Spring+MySql 登陆实例

  t_user为用户信息表,t_login_log为用户登录日志表。表的引擎要指定InnoDB,因为该引擎支持事务。

Maven+Spring+MySql 登陆实例

  初始化一条数据,用户名和密码用于测试登录。

三、持久层

1.建立领域对象(实体类)

User.java

 package com.adam.domain;

 import java.io.Serializable;
import java.util.Date; public class User implements Serializable {
private int userId;
private String userName;
private String password;
private int credits;
private String lastIp;
private Date lastVisit; public int getUserId() {
return userId;
} public void setUserId(int userId) {
this.userId = userId;
} public String getUserName() {
return userName;
} public void setUserName(String userName) {
this.userName = userName;
} public String getPassword() {
return password;
} public void setPassword(String password) {
this.password = password;
} public int getCredits() {
return credits;
} public void setCredits(int credits) {
this.credits = credits;
} public String getLastIp() {
return lastIp;
} public void setLastIp(String lastIp) {
this.lastIp = lastIp;
} public Date getLastVisit() {
return lastVisit;
} public void setLastVisit(Date lastVisit) {
this.lastVisit = lastVisit;
} }

LoginLog.java

 package com.adam.domain;

 import java.io.Serializable;
import java.util.Date; public class LoginLog implements Serializable {
private int loginLogId;
private int userId;
private String ip;
private Date loginDate; public int getLoginLogId() {
return loginLogId;
} public void setLoginLogId(int loginLogId) {
this.loginLogId = loginLogId;
} public int getUserId() {
return userId;
} public void setUserId(int userId) {
this.userId = userId;
} public String getIp() {
return ip;
} public void setIp(String ip) {
this.ip = ip;
} public Date getLoginDate() {
return loginDate;
} public void setLoginDate(Date loginDate) {
this.loginDate = loginDate;
} }

2.数据处理对象

UserDao.java

 package com.adam.dao;

 import java.sql.ResultSet;
import java.sql.SQLException; import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.jdbc.core.RowCallbackHandler;
import org.springframework.stereotype.Repository; import com.adam.domain.User; @Repository
public class UserDao {
@Autowired
private JdbcTemplate jdbcTemplate; public int getMatchCount(String name, String password) {
String sql = "SELECT count(*) FROM t_user WHERE user_name = ? and password = ?";
return jdbcTemplate.queryForInt(sql, new Object[] { name, password });
} public User findUserByName(final String name) {
String sql = "select user_id,user_name,credits from t_user where user_name = ?";
final User user = new User();
jdbcTemplate.query(sql, new Object[] { name }, new RowCallbackHandler() { public void processRow(ResultSet rs) throws SQLException {
user.setUserId(rs.getInt("user_id"));
user.setUserName(name);
user.setCredits(rs.getInt("credits"));
}
});
return user;
} public void updateLoginInfo(User user) {
String sql = "update t_user set last_visit = ?,last_ip = ?, credits = ? where user_id = ?";
jdbcTemplate.update(sql,
new Object[] { user.getLastVisit(), user.getLastIp(), user.getCredits(), user.getUserId() });
}
}

LoginLogDao.java

 package com.adam.dao;

 import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.stereotype.Repository; import com.adam.domain.LoginLog; @Repository
public class LoginLogDao {
@Autowired
private JdbcTemplate jdbcTemplate; public void insertLoginLog(LoginLog loginLog) {
String sql = "insert into t_login_log(user_id, ip,login_datatime) values(?,?,?)";
Object[] pra = { loginLog.getUserId(), loginLog.getIp(), loginLog.getLoginDate() };
jdbcTemplate.update(sql, pra);
}
}

3.在spring中装配Dao

  在Dao中并没有打开或释放数据库连接,那么Dao是如何访问数据库的?而且在Dao中使用的JdbcTemplate是从哪来的?这都是spring帮我们实现的,所以需要在spring中装配Dao。

  创建spring配置文件applicationContext.xml,结构如下

 <?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:p="http://www.springframework.org/schema/p"
xmlns:aop="http://www.springframework.org/schema/aop" xmlns:context="http://www.springframework.org/schema/context"
xmlns:tx="http://www.springframework.org/schema/tx"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context-4.3.xsd
http://www.springframework.org/schema/aop
http://www.springframework.org/schema/aop/spring-aop-4.3.xsd
http://www.springframework.org/schema/tx
http://www.springframework.org/schema/tx/spring-tx.xsd">
...
</beans>

  在其中加入配置信息

 <!-- 扫描包,应用注解 -->
<context:component-scan base-package="com.adam.dao" />
<!--定义一个jdbc数据源,创建一个驱动管理数据源的bean -->
<bean id="jdbcDataSource"
class="org.springframework.jdbc.datasource.DriverManagerDataSource">
<property name="driverClassName" value="com.mysql.jdbc.Driver" />
<property name="url" value="jdbc:mysql://localhost:3306/sampledb" />
<property name="username" value="root" />
<property name="password" value="AdamJin" />
</bean>
<!-- 定义jdbc模板Bean -->
<bean id="jdbcTemplate" class="org.springframework.jdbc.core.JdbcTemplate"
p:dataSource-ref="jdbcDataSource" />

四、业务层

1.建立业务处理类

UserService.java

 package com.adam.service;

 import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service; import com.adam.dao.LoginLogDao;
import com.adam.dao.UserDao;
import com.adam.domain.LoginLog;
import com.adam.domain.User; @Service
public class UserService {
@Autowired
private UserDao userdao;
@Autowired
private LoginLogDao loginLogDao; public boolean hasMatchUser(String name, String password) {
int matchCount = userdao.getMatchCount(name, password);
return matchCount > 0;
} public User findUserByUsername(String username) {
return userdao.findUserByName(username);
} public void loginSuccess(User user) {
user.setCredits(user.getCredits() + 5);
LoginLog loginLog = new LoginLog();
loginLog.setUserId(user.getUserId());
loginLog.setIp(user.getLastIp());
loginLog.setLoginDate(user.getLastVisit());
userdao.updateLoginInfo(user);
loginLogDao.insertLoginLog(loginLog);
}
}

2.在spring中装配Service

  打开刚建立的applicationContext.xml,在其中添加

 <!-- 扫描包,应用注解 -->
<context:component-scan base-package="com.adam.service" />
<!-- 配置事务管理器 -->
<bean id="transactionManager"
class="org.springframework.jdbc.datasource.DataSourceTransactionManager"
p:dataSource-ref="jdbcDataSource" /> <!-- 通过AOP配置事务增强,让service包下所有Bean的所有方法拥有事务 -->
<aop:config proxy-target-class="true">
<aop:pointcut expression="execution(* com.adam.service..*(..))"
id="serviceMethod" />
<aop:advisor advice-ref="txAdvice" pointcut-ref="serviceMethod" />
</aop:config>
<tx:advice id="txAdvice" transaction-manager="transactionManager">
<tx:attributes>
<tx:method name="*"></tx:method>
</tx:attributes>
</tx:advice>

  至此后端就算完成了,可以进行单元测试了。

五、单元测试

  右击New->Other选择如图,创建单元测试类

Maven+Spring+MySql 登陆实例

TestUserService.java

 package com.adam.test;
import static org.junit.Assert.*; import java.util.Date; import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner; import com.adam.domain.User;
import com.adam.service.UserService; @RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(locations = { "/applicationContext.xml" })
public class TestUserService {
@Autowired
private UserService userService; @Test
public void hasMatchedUser() {
boolean b1 = userService.hasMatchUser("admin", "123456");
boolean b2 = userService.hasMatchUser("admin", "1236"); assertTrue(b1);
assertTrue(!b2);
} @Test
public void findUserByUsername(){
User user = userService.findUserByUsername("admin");
assertEquals(user.getUserName(), "admin");
user.setLastIp("192.168.11.188");
user.setLastVisit(new Date());
userService.loginSuccess(user);
} }

Run As -> JUnit Test得到以下结果,便测试成功,数据库也会多出登陆日志数据。

Maven+Spring+MySql 登陆实例

六、展示层

  业务层和持久层开发任务结束,需要界面提供展示。

1.配置Spring MVC框架

修改web.xml文件

 <?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns="http://java.sun.com/xml/ns/javaee"
xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd"
id="WebApp_ID" version="3.0">
<!-- 从类路径下载spring配置文件 -->
<context-param>
<param-name>contextConfigLocation</param-name>
<param-value>
classpath:applicationContext.xml
</param-value>
</context-param>
<!-- 负责启动spring容器监听器,将引用上面的上下文参数获取spring配置文件地址 -->
<listener>
<listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener>
<!-- springMVC主控制servlet -->
<servlet>
<servlet-name>adam</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
<init-param>
<param-name>contextConfigLocation</param-name>
<param-value>classpath:adam-servlet.xml</param-value>
</init-param>
<load-on-startup>2</load-on-startup>
</servlet>
<!-- springMVC处理的url -->
<servlet-mapping>
<servlet-name>adam</servlet-name>
<url-pattern>*.html</url-pattern>
</servlet-mapping>
</web-app>

注意:上面代码23行若不配置,spring会到WEB-INF下找*-servle.xml,*是servlet配置的name。

adam-servlet.xml

 <?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:p="http://www.springframework.org/schema/p"
xmlns:context="http://www.springframework.org/schema/context"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context.xsd"> <!-- 扫描包,应用注解 -->
<context:component-scan base-package="com.adam.web" /> <!-- 配置视图解析器 -->
<bean
class="org.springframework.web.servlet.view.InternalResourceViewResolver"
p:viewClass="org.springframework.web.servlet.view.JstlView" p:prefix="/WEB-INF/jsp/"
p:suffix=".jsp" /> </beans>

2.控制器类

LoginController.java

 package com.adam.web;

 import java.util.Date;

 import javax.servlet.http.HttpServletRequest;

 import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.servlet.ModelAndView; import com.adam.domain.User;
import com.adam.service.UserService; @Controller
public class LoginController {
@Autowired
private UserService userService; @RequestMapping(value = "/index.html")
public String loginPage() {
return "login";
} @RequestMapping(value = "/loginCheck.html")
public ModelAndView loginCheck(HttpServletRequest request, LoginCommand loginCommand){
boolean isVaildUser = userService.hasMatchUser(loginCommand.getUsername(), loginCommand.getPassword());
if(!isVaildUser){
return new ModelAndView("login", "error", "用户名或密码错误");
}else{
User user = userService.findUserByUsername(loginCommand.getUsername());
user.setLastIp(request.getLocalAddr());
user.setLastVisit(new Date());
userService.loginSuccess(user);
request.getSession().setAttribute("user", user);
return new ModelAndView("main");
}
}
}

其中需要一个表单pojo

LoginCommand.java

 package com.adam.web;

 public class LoginCommand {
private String username;
private String password; public String getUsername() {
return username;
} public void setUsername(String username) {
this.username = username;
} public String getPassword() {
return password;
} public void setPassword(String password) {
this.password = password;
} }

3.jsp视图页面

  在WEB-INF下建立文件夹jsp,并新建以下文件。

login.jsp

 <%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c"%>
<html>
<head>
<title>登陆</title>
</head>
<body>
<c:if test="${!empty error}">
<font color="red"><c:out value="${error}" /></font>
</c:if>
<form action="<c:url value="/loginCheck.html"/>" method="post">
用户名: <input type="text" name="username"> <br /> 密&nbsp;&nbsp;&nbsp;码: <input
type="password" name="password"> <br /> <input type="submit"
value="提交"> <input type="reset" value="重置">
</form>
</body>
</html>

main.jsp

 <%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c"%>
<html>
<head>
<title>首页</title>
</head>
<body>${user.userName},欢迎您,您的积分是${user.credits}。
</body>
</html>

到此,整个实例就完成了。

七、运行

Run As -> Run on Server,输入地址 http://localhost:8080/Chapter2/index.html 便会看到

Maven+Spring+MySql 登陆实例

输入正确的信息即可登录成功

Maven+Spring+MySql 登陆实例

八、源码下载

点击下载