基于spring boot 的登陆 接着上一篇

还是复习 接着上篇文章 让我们用spring boot的方式来写一个登陆程序 先说说spring boot是什么

   spring boot就是整合了很多优秀的框架,不用我们自己手动的去写一堆xml配置然后进行配置。

   你可以理解为框架中的框架 也可以理解为spring 快速启动方式  因为他自带service服务器

  它的优点是

  1. Spring Boot可以建立独立的Spring应用程序;
  2. 内嵌了如Tomcat,Jetty和Undertow这样的容器,也就是说可以直接跑起来,用不着再做部署工作了。
  3. 无需再像Spring那样搞一堆繁琐的xml文件的配置;
  4. 可以自动配置Spring;
  5. 提供了一些现有的功能,如量度工具,表单数据验证以及一些外部配置这样的一些第三方功能;
  6. 提供的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 记得加 好了遇见啥问题都可以留言

猜你喜欢

转载自www.cnblogs.com/hwcs/p/9104048.html
今日推荐