还是复习 接着上篇文章 让我们用spring boot的方式来写一个登陆程序 先说说spring boot是什么
spring boot就是整合了很多优秀的框架,不用我们自己手动的去写一堆xml配置然后进行配置。
你可以理解为框架中的框架 也可以理解为spring 快速启动方式 因为他自带service服务器
它的优点是
- Spring Boot可以建立独立的Spring应用程序;
- 内嵌了如Tomcat,Jetty和Undertow这样的容器,也就是说可以直接跑起来,用不着再做部署工作了。
- 无需再像Spring那样搞一堆繁琐的xml文件的配置;
- 可以自动配置Spring;
- 提供了一些现有的功能,如量度工具,表单数据验证以及一些外部配置这样的一些第三方功能;
- 提供的POM可以简化Maven的配置;
OK废话不多说让我开始部署 这次配置还是idea+maven
它的prom.xml配置文件如下
<?xml version="1.0" encoding="UTF-8"?> <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.java</groupId> <artifactId>SpBoot</artifactId> <version>1.0-SNAPSHOT</version> <packaging>war</packaging> <name>SpBoot Maven Webapp</name> <!-- FIXME change it to the project's website --> <url>http://www.example.com</url> <parent> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-parent</artifactId> <version>1.3.3.RELEASE</version> </parent> <properties> <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding> <maven.compiler.source>1.7</maven.compiler.source> <maven.compiler.target>1.7</maven.compiler.target> </properties>
<dependencies>
<!--核心包--> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> </dependency>
<!--jdbc--> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-jdbc</artifactId> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-actuator</artifactId> </dependency> <dependency> <groupId>mysql</groupId> <artifactId>mysql-connector-java</artifactId> <version>${mysql.version}</version> </dependency> <dependency> <groupId>org.apache.tomcat.embed</groupId> <artifactId>tomcat-embed-jasper</artifactId> <scope>provided</scope> </dependency> <dependency> <groupId>javax.servlet</groupId> <artifactId>jstl</artifactId> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-test</artifactId> <scope>test</scope> </dependency> </dependencies> <build> <finalName>SpBoot</finalName> <pluginManagement><!-- lock down plugins versions to avoid using Maven defaults (may be moved to parent pom) --> <plugins> <plugin> <artifactId>maven-clean-plugin</artifactId> <version>3.0.0</version> </plugin> <plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-surefire-plugin</artifactId> <configuration> <useSystemClassLoader>false</useSystemClassLoader> </configuration> </plugin> </plugins> </pluginManagement> </build> </project>
综上所诉配置ok后我们在resuorces文件下找到application.properties没有的就自己新建一下
写入数据库配置信息
# Available levels are: TRACE, DEBUG, INFO, WARN, ERROR, FATAL, OFF logging.level.com.smart = DEBUG logging.level.org.springframework.web = DEBUG #logging.file = /var/netgloo_blog/logs/spring-boot-logging.log #server.contextPath=/ #server.port=8080 #自定义连接池
#spring.datasource.type=org.apache.commons.dbcp2.BasicDataSource #配置数据库连接信息 spring.datasource.name=sampleDs spring.datasource.url=jdbc:mysql://localhost:3306/ow?useUnicode=true&characterEncoding=utf-8&useSSL=false spring.datasource.username=root spring.datasource.password=1024 spring.datasource.driver-class-name=com.mysql.jdbc.Driver #配置JNDL数据源 生产环境通常会采用这种
#spring.datasource.jndi-name=java:comp/env/jdbc/sampleDs
#连接池配置信息 spring.datasource.max-wait=10000 spring.datasource.max-active=50 spring.datasource.max-idle=10 spring.datasource.min-idle=8 spring.datasource.test-on-borrow=true spring.datasource.validation-query=select 1
#初始化数据库脚本 #spring.datasource.initialize=true #spring.datasource.platform=mysql #spring.datasource.data=data #spring.datasource.schema=schema #应用磁盘空间检查 #management.health.db.enabled=true #management.health.defaults.enabled=true #management.health.diskspace.enabled=true #management.health.diskspace.path=D:/masterSpring/code #management.health.diskspace.threshold=0
然后User 类 和 LoginLog类 我这里就贴一下 属性然后自己去完成set get方法 还有引入接口
Serializable
User类
private int userId; private String userName; private String password; private int credits; private String lastIp; private Date lastVisit;
LoginLog类
private int loginLogId; private int userId; private String ip; private Date loginDate;
开始写dao层 写法和上文一样
UserDao
package com.java.dao; import com.java.domain.User; 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 java.sql.ResultSet; import java.sql.SQLException; @Repository public class UserDao { private JdbcTemplate jdbcTemplate; private final static String MATCH_COUNT_SQL = " SELECT count(*) FROM t_user " + " WHERE user_name =? and password=? "; private final static String UPDATE_LOGIN_INFO_SQL = " UPDATE t_user SET " + " last_visit=?,last_ip=?,credits=? WHERE user_id =?"; public int getMatchCount(String userName, String password) { return jdbcTemplate.queryForObject(MATCH_COUNT_SQL, new Object[]{userName, password}, Integer.class); } public User findUserByUserName(final String userName) { String sqlStr = " SELECT user_id,user_name,credits " + " FROM t_user WHERE user_name =? "; final User user = new User(); jdbcTemplate.query(sqlStr, new Object[]{userName}, new RowCallbackHandler() { public void processRow(ResultSet rs) throws SQLException { user.setUserId(rs.getInt("user_id")); user.setUserName(userName); user.setCredits(rs.getInt("credits")); } }); return user; } public void updateLoginInfo(User user) { jdbcTemplate.update(UPDATE_LOGIN_INFO_SQL, new Object[]{user.getLastVisit(), user.getLastIp(), user.getCredits(), user.getUserId()}); } @Autowired public void setJdbcTemplate(JdbcTemplate jdbcTemplate) { this.jdbcTemplate = jdbcTemplate; } }
这里区别就来了 写好dao之后我们只需要标注相应的注解然后就不用去spring容器装配DAo了 这让我们专注业务的实现而不用去过多的在意装配
LoginLogDao
package com.java.dao; import com.java.domain.LoginLog; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.jdbc.core.JdbcTemplate; import org.springframework.stereotype.Repository; @Repository public class LoginLogDao { @Autowired private JdbcTemplate jdbcTemplate; //保存登陆日志SQL private final static String INSERT_LOGIN_LOG_SQL= "INSERT INTO t_login_log(user_id,ip,login_datetime) VALUES(?,?,?)"; public void insertLoginLog(LoginLog loginLog) { Object[] args = { loginLog.getUserId(), loginLog.getIp(), loginLog.getLoginDate() }; jdbcTemplate.update(INSERT_LOGIN_LOG_SQL, args); } }
dao两个类我们就写完了现在开始写业务类 他的作用就是将dao层玩起来 至于怎么玩 看好咯
下面重点是事务 等下一对比你就知道了
package com.java.service; import com.java.dao.LoginLogDao; import com.java.dao.UserDao; import com.java.domain.LoginLog; import com.java.domain.User; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; @Service public class UserService { private UserDao userDao; private LoginLogDao loginLogDao; //用户登陆 public boolean hasMatchUser(String userName, String password) { int matchCount =userDao.getMatchCount(userName, password); return matchCount > 0; }
//通过用户名拿去用户相关数据 public User findUserByUserName(String userName) { return userDao.findUserByUserName(userName); }
//看看这个开的事务 记录登陆详情 ip 时间 积分 @Transactional public void loginSuccess(User user) { user.setCredits( 5 + user.getCredits()); LoginLog loginLog = new LoginLog(); loginLog.setUserId(user.getUserId()); loginLog.setIp(user.getLastIp()); loginLog.setLoginDate(user.getLastVisit()); userDao.updateLoginInfo(user); loginLogDao.insertLoginLog(loginLog); } @Autowired public void setUserDao(UserDao userDao) { this.userDao = userDao; } @Autowired public void setLoginLogDao(LoginLogDao loginLogDao) { this.loginLogDao = loginLogDao; } }
上面说到的事务 是这样的 在springboot中我们需要一个主类 叫做
Application
你把他放到和dao domain这样的包同一级目录下就好了
如果你要用他配置事务 那么你必须使用
EnableTransactionManagement 这个注解来开启事务支持效果如下
package com.java; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; import org.springframework.boot.builder.SpringApplicationBuilder; import org.springframework.boot.context.web.SpringBootServletInitializer; import org.springframework.context.annotation.Bean; import org.springframework.jdbc.datasource.DataSourceTransactionManager; import org.springframework.transaction.PlatformTransactionManager; import org.springframework.transaction.annotation.EnableTransactionManagement; import org.springframework.web.WebApplicationInitializer; import javax.sql.DataSource; /** * 这个是主类 用法是 EnableTransactionManagement 这个家伙就事务 * 就不用去配置xml了 配置spring mvc也在这里 * */ //@Configuration //@ComponentScan //@EnableAutoConfiguration @SpringBootApplication @EnableTransactionManagement public class Application { //自定义事务管理器 如果你想自定义事务管理器的话就这样做 我这里定义了datasource @Bean public PlatformTransactionManager txManager(DataSource dataSource) { return new DataSourceTransactionManager(dataSource); }public static void main(String[] args) throws Exception { SpringApplication.run(Application.class, args); } }
这就相当于spring 框架 xml配置文件里面的txManager() 标注bean就行了 这是针对事务这方面的
好 现在来到展示层 由于使用的是jsp作为视图 所以需要jstl标签 你可以在prom.xml里这样配置
<dependency> <groupId>org.apache.tomcat.embed</groupId> <artifactId>tomcat-embed-jasper</artifactId> </dependency> <dependency> <groupId>javax.servlet</groupId> <artifactId>jstl</artifactId> </dependency>
不过通常情况下都是不用配置的 = = 除非你报错
搞完之后我们还需要配置spring mvc框架 这个时候你要让前面的 Application主类
extends SpringBootServletInitializer implements WebApplicationInitializer 继承那货和实现这货
并且你要在类里面 加入
protected SpringApplicationBuilder configure(SpringApplicationBuilder application) { return application.sources(Application.class); }
这样做的目的呢就是重写springBootServletInitializaer里面的configure方法
写完之后 我们处理登陆请求同上文章 一下不变
LoginCommand类
private String userName; private String password;
LoginController类
package com.java.web; import com.java.domain.User; import com.java.service.UserService; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RestController; import org.springframework.web.servlet.ModelAndView; import javax.servlet.http.HttpServletRequest; import java.util.Date; @RestController public class LoginController{ private UserService userService; @RequestMapping(value = {"/","/index.html"}) public ModelAndView loginPage(){ return new ModelAndView("login"); } @RequestMapping(value = "/loginCheck.html") public ModelAndView loginCheck(HttpServletRequest request, LoginCommand loginCommand){ boolean isValidUser = userService.hasMatchUser(loginCommand.getUserName(), loginCommand.getPassword()); if (!isValidUser) { 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"); } } @Autowired public void setUserService(UserService userService) { this.userService = userService; } }
这些都写完后就随便写两个前台页面测试一下 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> 密 码: <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" %> <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"> <html> <head> <meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1"> <title>小春论坛</title> </head> <body> ${user.userName},欢迎您进入小春论坛,您当前积分为${user.credits}; </body> </html>
hello.jsp
<%@ page contentType="text/html;charset=UTF-8" language="java" %> <html> <head> <title>Simple jsp page</title> </head> <body> <h1>Hello ${name}, How are you?</h1> </body> </html>
启动项目的方式呢最好实在maven里面启动 为了避免找不到路径和一些蛋疼的问题 当然你也可以用appliaction主类启动
来说说我遇见的几个蛋疼问题
第一个就是prom.xml里的
<parent> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-parent</artifactId> <version>1.3.3.RELEASE</version> </parent>
这个配置问题 当时用的是2.0的一直启动报错,气死哦列 后续兼容2.0的版本我会放上来
第二个 问题你就是连接数据库SSL信息安全问题 = =就是application.properties 的这个
spring.datasource.name=sampleDs spring.datasource.url=jdbc:mysql://localhost:3306/xxxxx?useUnicode=true&characterEncoding=utf-8&useSSL=false spring.datasource.username=root spring.datasource.password=xxxx spring.datasource.driver-class-name=com.mysql.jdbc.Driver
很多人写完数据库名字后就不管了233 这里如果不设定
?useUnicode=true&characterEncoding=utf-8&useSSL=false
是会报错的2333 记得加 好了遇见啥问题都可以留言