Java秒杀系统--3.用户登录模块

简介:实现用户的登录功能。

1.前端页面使用thymeleaf技术,下面为引入的依赖和添加的配置。

 <parent>
   <groupId>org.springframework.boot</groupId>
   <artifactId>spring-boot-starter-parent</artifactId>
   <version>1.5.8.RELEASE</version>
   <relativePath/>
  <!-- lookup parent from repository -->
 </parent>


<!--引入支持thymeleaf技术的依赖-->
<dependency>   <groupId>org.springframework.boot</groupId>   <artifactId>spring-boot-starter-thymeleaf</artifactId> </dependency>
 <!--支持web开发-->
 <dependency>
  <groupId>org.springframework.boot</groupId>
  <artifactId>spring-boot-starter-web</artifactId>
 </dependency>
 <!--支持使用application.properties配置文件-->
<dependency>
  <groupId>org.springframework.boot</groupId>
  <artifactId>spring-boot-configuration-processor</artifactId>
  <optional>true</optional>
</dependency>

  上面这些都是自动配置依赖模块,全都不需要手动配置。下面是一些自动配置的参数,如需更改,可在application.prioperties文件中添加相同的参数进行覆盖。

  各种自动配置参数:https://docs.spring.io/spring-boot/docs/1.5.6.RELEASE/reference/htmlsingle/#appendix

  spring-boot-starter-parent:提供了很多默认的配置为开发提供很多的方便。

  spring-boot-starter-web:该模块为我们提供了一个包含嵌入式的Tomcat的web应用,我们只需完成一个Controller来处理web请求就可以了。

  该模块的自动配置:

    /src/main/resources/static:指定了静态文件的存放位置。

    自动配置SpringMVC必要组件,自动配置tomcat的各种参数。

  spring-boot-starter-thymeleaf:提供thymeleaf技术支持并且默认将模板文件放到classpath:/templates/

  该模块需要更改的配置项

    spring.thymeleaf.cache=false      本地开发条件下关闭模板的缓存功能,否则每次更改html都要重启整个项目才能生效;其它条件开启缓存。 

2.登录接口

  用户通过http://localhost:8080/login/to_login来访问登录端口,

  使用一个Controller为上面的url返回一个前端页面

1 @RequestMapping("/to_login")
2     public String toLogin(){
3         return "login";
4     }

 

3.在前端页面获取用户输入的登录信息,并使用异步提交。

  

 1 <script>
 2 
 3     function login() {
 4         $("#loginForm").validate({
 5             submitHandler: function (form) {                                    //点击提交button会触发该函数。
 6                 doLogin();
 7             }
 8         });
 9     }
10 
11 
12 
13     function doLogin() {
14         var inputPass = $("#password").val();
15         var salt = salt1;
16         var pass = ""+salt.charAt(0)+salt.charAt(4)+inputPass+salt.charAt(2)+salt.charAt(6); //13  24
17         var password = md5(pass);                                                //将用户提交的明文密码做一次MD5运算。
18 
19 
20         $.ajax({
21             url: "/login/do_login",
22             type: "POST",
23             data: {
24                 mobile: $("#mobile").val(),
25                 password: password
26             },
27             success: function (data) {
28                 layer.closeAll();
29                 if (data.code == 0) {
30                     layer.msg("成功");
31                     window.location.href = "/goods/to_list";                     //访问url(/goods/to_list)
32                 } else {
33                     layer.msg(data.msg);
34                 }
35             },
36             error: function () {
37                 layer.closeAll();
38             }
39         });
40 
41 
42 
43     }
44 </script>

  在前端要为用户提交的密码进行一次MD5加密。该功能实现由下面三步完成。

  1.通过jQuery实现异步提交的功能。submitHandler:function(form){ doLogin() },点击登录按钮会触发doLogin()函数。

  2.在doLogin()函数中,对用户输入的password做一次MD5的操作  。var password = md5(pass);   在文件中引入了md5.min.js(网上下载)所以可以调用md5方法。

  3.使用$.ajax({url:,type:,data:,success:,error:}),向后端提交数据,在提交成功后访问/goods/to_list。

4.后端对登录用户信息进行验证

   后端使用类LoginVo.class来接收前端传来的数据:

   1.格式验证:手机号,密码的输入不能为空,手机号码格式为:1+10个正整数。

   2.通过手机号在redis或MySQL中获取用户对象。                                //可能抛出用户不存在的异常

   3.比较密码是否正确:再一次对用户提交的密码进行MD5,然后与查询出的用户对象进行比较。           //可能抛出密码错误异常

5.分布式session功能

   分布式session:用户的一些重要信息,需要被保存在服务器端,这些信息在用户离开网站后才能被清除;但是网站可能有多台服务器,用户产生的多次请求不保证被同一台服务器所相应,此时就要求所有的服务器都能得到用户的这些保存到服务器的重要信息,这就是分布式session。

  解决方案:将这些重要信息保存到,redis中,key为token,值为重要信息。用户访问中有一个token,服务器通过该token在redis中获取重要信息。

   1.为用户生成token,并以token值为key,user对象(重要信息)为值保存在redis,然后将token值保存到request的cookie中。

   

1 private void addCookie(HttpServletResponse httpResponse,String token,MiaoshaUser miaoshaUser){
2         redisService.set(MiaoshaUserPrefix.getBytoken,token,miaoshaUser);
3                                                                                                                         //将token值返回给浏览器端
4         Cookie cookie = new Cookie(TOKEN_NAME,token);
5         cookie.setMaxAge(MiaoshaUserPrefix.getBytoken.expireSeconds);
6         cookie.setPath("/");                                                       
7         httpResponse.addCookie(cookie);
8     }

  setPath("/");对项目根路径下的访问都携带cookie。

  2.服务器通过token在redis中获取保存的重要信息(本项目中为MiaoshaUser对象)。

  

 1  /**
 2      * 通过request提供的cookie获得MiaoShaUser对象
 3      */
 4     private MiaoshaUser getMiaoshaUser(HttpServletRequest request, HttpServletResponse response){
 5         String paramToken = request.getParameter(MiaoshaUserService.TOKEN_NAME);
 6         String cookieToken = getCookieValue(request,MiaoshaUserService.TOKEN_NAME);
 7         //使用cookie得到对象
 8         if (StringUtils.isEmpty(cookieToken)&&StringUtils.isEmpty(paramToken)) {
 9             return null;
10         }
11         String token = StringUtils.isEmpty(paramToken)?cookieToken:paramToken;   //优先取paraToken
12         MiaoshaUser user = miaoshaUserService.getByToken(token,response);
13         return user;
14     }
 1 /*
 2      *   获得request中的cookie值
 3     */
 4     private String getCookieValue(HttpServletRequest request, String tokenName) {
 5         Cookie[] cookies = request.getCookies();
 6         if(cookies==null || cookies.length<=0){
 7             return null;
 8         }
 9         for (Cookie c:cookies
10         ) {
11             if (c.getName().equals(tokenName)) {
12                 return c.getValue();
13             }
14         }
15         return null;
16     }

 

6.对象缓存

   将用户对象保存到redis中,下次用户登录时,直接通过用户id在redis中获取用户对象。

   用户第一次登录通过用户id在MySQL中获取用户对象,并将用户对象缓存到redis中,下次登录就可以直接在redis中获得用户。

    

 1 public MiaoshaUser getById(String id){
 2         MiaoshaUser user = redisService.get(MiaoshaUserPrefix.getById,""+id,MiaoshaUser.class);
 3         if (user != null) {
 4             return user;
 5         }
 6         user = miaoshaUserDao.selectUserById(id);
 7         if (user != null) {
 8             redisService.set(MiaoshaUserPrefix.getById,user.getId()+"",user);
 9         }
10         return user;
11     }

 

 

  

posted on 2020-04-09 14:32  hello,bdiskl  阅读(551)  评论(0编辑  收藏  举报

导航