秒杀项目之验证功能

目录

一、用户验证

1、给findByAccount方法增加 request, response两个参数:

2、cookie储存用户信息

 3、页面跳转判断

 二、redis缓存完成全局session

 1、redis缓存完成session共享

三、自定义redis实现功能

1、操作redis的类

2、编写实现全局session功能

 3、解决时间获取异常问题

 四、使用参数解析器

1、解决除访问登录界面,都需要凭证的问题(解决重复代码问题)


一、用户验证

完成必须登录才能进入商品展示界面

1、给findByAccount方法增加 request, response两个参数:

findByAccount(UserVo userVo, HttpServletRequest request, HttpServletResponse response)

(1)session保存用户信息

 如果同时几个人一起下单,会导致共用一个session,session将会修改为最后进入的那个人的信息,相当于几个人下单全部给了最后下单的那个人

2、cookie储存用户信息

(1)导入帮助类

①、CookieUtils

package com.mwy.seckill.util;

import lombok.extern.slf4j.Slf4j;

import javax.servlet.http.Cookie;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.UnsupportedEncodingException;
import java.net.URLDecoder;
import java.net.URLEncoder;

@Slf4j

public class CookieUtils {

    /**
     * @Description: 得到Cookie的值, 不编码
     */
    public static String getCookieValue(HttpServletRequest request, String cookieName) {
        return getCookieValue(request, cookieName, false);
    }

    /**
     * @Description: 得到Cookie的值
     */
    public static String getCookieValue(HttpServletRequest request, String cookieName, boolean isDecoder) {
        Cookie[] cookieList = request.getCookies();
        if (cookieList == null || cookieName == null) {
            return null;
        }
        String retValue = null;
        try {
            for (int i = 0; i < cookieList.length; i++) {
                if (cookieList[i].getName().equals(cookieName)) {
                    if (isDecoder) {
                        retValue = URLDecoder.decode(cookieList[i].getValue(), "UTF-8");
                    } else {
                        retValue = cookieList[i].getValue();
                    }
                    break;
                }
            }
        } catch (UnsupportedEncodingException e) {
            e.printStackTrace();
        }
        return retValue;
    }

    /**
     * @Description: 得到Cookie的值
     */
    public static String getCookieValue(HttpServletRequest request, String cookieName, String encodeString) {
        Cookie[] cookieList = request.getCookies();
        if (cookieList == null || cookieName == null) {
            return null;
        }
        String retValue = null;
        try {
            for (int i = 0; i < cookieList.length; i++) {
                if (cookieList[i].getName().equals(cookieName)) {
                    retValue = URLDecoder.decode(cookieList[i].getValue(), encodeString);
                    break;
                }
            }
        } catch (UnsupportedEncodingException e) {
            e.printStackTrace();
        }
        return retValue;
    }

    /**
     * @Description: 设置Cookie的值 不设置生效时间默认浏览器关闭即失效,也不编码
     */
    public static void setCookie(HttpServletRequest request, HttpServletResponse response, String cookieName, String cookieValue) {
        setCookie(request, response, cookieName, cookieValue, -1);
    }

    /**
     * @Description: 设置Cookie的值 在指定时间内生效,但不编码
     */
    public static void setCookie(HttpServletRequest request, HttpServletResponse response, String cookieName, String cookieValue, int cookieMaxage) {
        setCookie(request, response, cookieName, cookieValue, cookieMaxage, false);
    }

    /**
     * @Description: 设置Cookie的值 不设置生效时间,但编码
     * 在服务器被创建,返回给客户端,并且保存客户端
     * 如果设置了SETMAXAGE(int seconds),会把cookie保存在客户端的硬盘中
     * 如果没有设置,会默认把cookie保存在浏览器的内存中
     * 一旦设置setPath():只能通过设置的路径才能获取到当前的cookie信息
     */
    public static void setCookie(HttpServletRequest request, HttpServletResponse response, String cookieName,
                                 String cookieValue, boolean isEncode) {
        setCookie(request, response, cookieName, cookieValue, -1, isEncode);
    }

    /**
     * @Description: 设置Cookie的值 在指定时间内生效, 编码参数
     */
    public static void setCookie(HttpServletRequest request, HttpServletResponse response, String cookieName, String cookieValue, int cookieMaxage, boolean isEncode) {
        doSetCookie(request, response, cookieName, cookieValue, cookieMaxage, isEncode);
    }

    /**
     * @Description: 设置Cookie的值 在指定时间内生效, 编码参数(指定编码)
     */
    public static void setCookie(HttpServletRequest request, HttpServletResponse response, String cookieName,
                                 String cookieValue, int cookieMaxage, String encodeString) {
        doSetCookie(request, response, cookieName, cookieValue, cookieMaxage, encodeString);
    }

    /**
     * @Description: 删除Cookie带cookie域名
     */
    public static void deleteCookie(HttpServletRequest request, HttpServletResponse response,
                                    String cookieName) {
        doSetCookie(request, response, cookieName, null, -1, false);
    }


    /**
     * @Description: 设置Cookie的值,并使其在指定时间内生效
     */
    private static final void doSetCookie(HttpServletRequest request, HttpServletResponse response, String cookieName, String cookieValue, int cookieMaxage, boolean isEncode) {
        try {
            if (cookieValue == null) {
                cookieValue = "";
            } else if (isEncode) {
                cookieValue = URLEncoder.encode(cookieValue, "utf-8");
            }
            Cookie cookie = new Cookie(cookieName, cookieValue);
            if (cookieMaxage > 0)
                cookie.setMaxAge(cookieMaxage);
            if (null != request) {// 设置域名的cookie
                String domainName = getDomainName(request);
                log.info("========== domainName: {} ==========", domainName);
                if (!"localhost".equals(domainName)) {
                    cookie.setDomain(domainName);
                }
            }
            cookie.setPath("/");
            response.addCookie(cookie);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    /**
     * @Description: 设置Cookie的值,并使其在指定时间内生效
     */
    private static final void doSetCookie(HttpServletRequest request, HttpServletResponse response,
                                          String cookieName, String cookieValue, int cookieMaxage, String encodeString) {
        try {
            if (cookieValue == null) {
                cookieValue = "";
            } else {
                cookieValue = URLEncoder.encode(cookieValue, encodeString);
            }
            Cookie cookie = new Cookie(cookieName, cookieValue);
            if (cookieMaxage > 0)
                cookie.setMaxAge(cookieMaxage);
            if (null != request) {// 设置域名的cookie
                String domainName = getDomainName(request);
                log.info("========== domainName: {} ==========", domainName);
                if (!"localhost".equals(domainName)) {
                    cookie.setDomain(domainName);
                }
            }
            cookie.setPath("/");
            response.addCookie(cookie);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    /**
     * @Description: 得到cookie的域名
     */
    private static final String getDomainName(HttpServletRequest request) {
        String domainName = null;

        String serverName = request.getRequestURL().toString();
        if (serverName == null || serverName.equals("")) {
            domainName = "";
        } else {
            serverName = serverName.toLowerCase();
            serverName = serverName.substring(7);
            final int end = serverName.indexOf("/");
            serverName = serverName.substring(0, end);
            if (serverName.indexOf(":") > 0) {
                String[] ary = serverName.split("\\:");
                serverName = ary[0];
            }

            final String[] domains = serverName.split("\\.");
            int len = domains.length;
            if (len > 3 && !isIp(serverName)) {
                // www.xxx.com.cn
                domainName = "." + domains[len - 3] + "." + domains[len - 2] + "." + domains[len - 1];
            } else if (len <= 3 && len > 1) {
                // xxx.com or xxx.cn
                domainName = "." + domains[len - 2] + "." + domains[len - 1];
            } else {
                domainName = serverName;
            }
        }
        return domainName;
    }

    public static String trimSpaces(String IP) {//去掉IP字符串前后所有的空格
        while (IP.startsWith(" ")) {
            IP = IP.substring(1, IP.length()).trim();
        }
        while (IP.endsWith(" ")) {
            IP = IP.substring(0, IP.length() - 1).trim();
        }
        return IP;
    }

    public static boolean isIp(String IP) {//判断是否是一个IP
        boolean b = false;
        IP = trimSpaces(IP);
        if (IP.matches("\\d{1,3}\\.\\d{1,3}\\.\\d{1,3}\\.\\d{1,3}")) {
            String s[] = IP.split("\\.");
            if (Integer.parseInt(s[0]) < 255)
                if (Integer.parseInt(s[1]) < 255)
                    if (Integer.parseInt(s[2]) < 255)
                        if (Integer.parseInt(s[3]) < 255)
                            b = true;
        }
        return b;
    }
}

(2)修改UserServiceImpl

package com.mwy.seckill.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
import com.baomidou.mybatisplus.core.toolkit.StringUtils;
import com.mwy.seckill.exception.BusinessException;
import com.mwy.seckill.pojo.User;
import com.mwy.seckill.mapper.UserMapper;
import com.mwy.seckill.service.IUserService;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.mwy.seckill.util.CookieUtils;
import com.mwy.seckill.util.MD5Utils;
import com.mwy.seckill.util.ValidatorUtils;
import com.mwy.seckill.util.response.ResponseResult;
import com.mwy.seckill.util.response.ResponseResultCode;
import com.mwy.seckill.vo.UserVo;
import org.springframework.http.HttpRequest;
import org.springframework.stereotype.Service;

import javax.servlet.http.Cookie;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.util.Date;
import java.util.UUID;

/**
 * 

* 用户信息表 服务实现类 *

* * @author mwy * @since 2022-03-15 */ @Service public class UserServiceImpl extends ServiceImpl implements IUserService { @Override public ResponseResult findByAccount(UserVo userVo, HttpServletRequest request, HttpServletResponse response) { // 先判断信息是否符合(账号是否是手机号码,密码是不是空) if(!ValidatorUtils.isMobile(userVo.getMobile())){ throw new BusinessException(ResponseResultCode.USER_ACCOUNT_NOT_MOBLIE); } if(StringUtils.isBlank(userVo.getPassword())){ throw new BusinessException(ResponseResultCode.USER_PASSWORD_NOT_MATCH); } // 再去数据库查出对应的用户(mobile) User user=this.getOne(new QueryWrapper().eq("id",userVo.getMobile())); if(user==null){ throw new BusinessException(ResponseResultCode.USER_ACCOUNT_NOT_FIND); } // 比较密码 // 二重加密(前端->后端,后端->数据库) String salt=user.getSalt(); // 将前台的加密密码和后端的盐再次进行加密 String newPassword=MD5Utils.formPassToDbPass(userVo.getPassword(),salt); if(!newPassword.equals(user.getPassword())){ throw new BusinessException(ResponseResultCode.USER_PASSWORD_NOT_MATCH); } // 修改最后的登录时间 this.update(new UpdateWrapper().eq("id",userVo.getMobile()).set("last_login_date",new Date()).setSql("login_count=login_count+1")); // 最初的版本(session:全局共用,uuid:不可能重复) String ticket = UUID.randomUUID().toString().replace("-", ""); // request.getSession().setAttribute("user",user); request.getSession().setAttribute(ticket,user); // 将我生成的ticket给用户,用户如何验证? 使用cookie,cookie在客户端,session在服务端 // Cookie cookie=new Cookie("ticket",ticket); // response.addCookie(cookie); 这样写会导致设置时间麻烦 CookieUtils.setCookie(request,response,"ticket",ticket); return ResponseResult.success(); } }

(3)运行测试

秒杀项目之验证功能_第1张图片

 3、页面跳转判断

除了登录页面不需要身份验证,其他页面都需要身份验证

(1)修改PathController

package com.mwy.seckill.controller;


import com.mwy.seckill.exception.BusinessException;
import com.mwy.seckill.util.CookieUtils;
import com.mwy.seckill.util.response.ResponseResultCode;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.CookieValue;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;

import javax.servlet.http.HttpServletRequest;

@Controller
public class PathController {

    //    登录跳首页
    @RequestMapping("/")
    public String toPath(){
        return "login";
    }

    //    跳所有二级页面
    @RequestMapping("/{dir}/{path}")
    public String toPath(@PathVariable("dir") String dir, @PathVariable("path") String path, HttpServletRequest request) {
        String ticket= CookieUtils.getCookieValue(request,"ticket");
//       进行页面跳转之前判断用户带过来的信息是否有效
        if(ticket==null){
//            没有带信息,抛出业务异常,ticket凭据异常
            throw new BusinessException(ResponseResultCode.TICKET_ERROR);
        }
//        去session中取到ticket对应的用户,判断是否有值
        Object obj = request.getSession().getAttribute(ticket);
        if(obj==null){
//            凭据没获得取到,要么是已失效,同样抛出凭证异常
            throw new BusinessException(ResponseResultCode.TICKET_ERROR);
        }


        return dir+"/"+path;
    }

}

(2)运行测试

①、没有登录访问首页

秒杀项目之验证功能_第2张图片

 二、redis缓存完成全局session

现在的session还是有问题的,只存在一个服务器中,如果搭建了集群,只有第一个A获得凭证的才能访问,后面的获取不到,同时也访问不到,

秒杀项目之验证功能_第3张图片

 1、redis缓存完成session共享

(1)需要第三者(redis缓存),将凭证放入第三者中,需要就去拿

秒杀项目之验证功能_第4张图片

(2)导入pom依赖

        
        
            org.apache.commons
            commons-pool2
        
        
        
            org.springframework.session
            spring-session-data-redis
        

(3)配置redis缓存

①、application.yml

    redis:
        host: 127.0.0.1
        password: 123
        database: 0
        port: 6379

秒杀项目之验证功能_第5张图片

(4)运行测试

秒杀项目之验证功能_第6张图片

 session的值进入了缓存: 

秒杀项目之验证功能_第7张图片

三、自定义redis实现功能

1、操作redis的类

(1)新建config软件包,在建RedisConfig类

①、RedisConfig:

package com.mwy.seckill.config;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.data.redis.connection.RedisConnectionFactory;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.serializer.GenericJackson2JsonRedisSerializer;
import org.springframework.data.redis.serializer.StringRedisSerializer;
@Configuration
public class RedisConfig {

    @Bean
    public RedisTemplate redisTemplate(RedisConnectionFactory factory){
        //新建一个
        RedisTemplate redisTemplate = new RedisTemplate();
        //设置一下使用连接工厂
        redisTemplate.setConnectionFactory(factory);
        //额外设置(string)
        redisTemplate.setKeySerializer(new StringRedisSerializer());
        redisTemplate.setValueSerializer(new GenericJackson2JsonRedisSerializer());
        //额外设置(hash 就是 map 集合)
        redisTemplate.setHashKeySerializer(new StringRedisSerializer());
        redisTemplate.setHashValueSerializer(new GenericJackson2JsonRedisSerializer());
        //让设置生效
        redisTemplate.afterPropertiesSet();
        return redisTemplate;
    }
}

2、编写实现全局session功能

(1)取消原本写的全局session

①、UserServiceImpl

秒杀项目之验证功能_第8张图片

 (2)编写service层

①、IRedisService 

package com.mwy.seckill.service;

import com.mwy.seckill.pojo.User;


public interface IRedisService {

//    得到凭据放用户的方法
    void putUserByTicket(String ticket, User user);

//    取凭据的方法
    User getUserByTicket(String ticket);

}

②、实现接口类(RedisServiceImpl)

package com.mwy.seckill.service.impl;
import com.mwy.seckill.pojo.User;
import com.mwy.seckill.service.IRedisService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;
import java.util.concurrent.TimeUnit;
@Service
public class RedisServiceImpl implements IRedisService {

//    缓存参数
    @Autowired
    private RedisTemplate redisTemplate;

    @Override
    public void putUserByTicket(String ticket, User user) {
        redisTemplate.opsForValue().set("user:"+ticket,user,2L, TimeUnit.HOURS);
    }

    @Override
    public User getUserByTicket(String ticket) {
        Object obj = redisTemplate.opsForValue().get("user:"+ticket);
        if(obj==null|| !(obj instanceof User)){
            return null;
        }
        return (User) obj;
    }
}

(3)获取凭据跳转页面

①、PathController

package com.mwy.seckill.controller;
import com.mwy.seckill.exception.BusinessException;
import com.mwy.seckill.pojo.User;
import com.mwy.seckill.service.IRedisService;
import com.mwy.seckill.util.CookieUtils;
import com.mwy.seckill.util.response.ResponseResultCode;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.CookieValue;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import javax.servlet.http.HttpServletRequest;
@Controller
public class PathController {

    @Autowired
    private IRedisService redisService;

    //    登录跳首页
    @RequestMapping("/")
    public String toPath(){
        return "login";
    }
    //    跳所有二级页面
    @RequestMapping("/{dir}/{path}")
    public String toPath(@PathVariable("dir") String dir, @PathVariable("path") String path, HttpServletRequest request) {
//       获取用户的ticket
        String ticket= CookieUtils.getCookieValue(request,"ticket");
//       进行页面跳转之前判断用户带过来的信息是否有效
        if(ticket==null){
//            没有带信息,抛出业务异常,ticket凭据异常
            throw new BusinessException(ResponseResultCode.TICKET_ERROR);
        }
//        去session中取到ticket对应的用户,判断是否有值
//        Object obj = request.getSession().getAttribute(ticket);
//        去缓存中拿
        User user = redisService.getUserByTicket(ticket);
        if(user==null){
//            凭据没获得取到,要么是已失效,同样抛出凭证异常
            throw new BusinessException(ResponseResultCode.TICKET_ERROR);
        }
        return dir+"/"+path;
    }
}

(4)将凭证放入缓存

①、UserServiceImpl

package com.mwy.seckill.service.impl;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
import com.baomidou.mybatisplus.core.toolkit.StringUtils;
import com.mwy.seckill.exception.BusinessException;
import com.mwy.seckill.pojo.User;
import com.mwy.seckill.mapper.UserMapper;
import com.mwy.seckill.service.IRedisService;
import com.mwy.seckill.service.IUserService;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.mwy.seckill.util.CookieUtils;
import com.mwy.seckill.util.MD5Utils;
import com.mwy.seckill.util.ValidatorUtils;
import com.mwy.seckill.util.response.ResponseResult;
import com.mwy.seckill.util.response.ResponseResultCode;
import com.mwy.seckill.vo.UserVo;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.HttpRequest;
import org.springframework.stereotype.Service;
import javax.servlet.http.Cookie;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.util.Date;
import java.util.UUID;
/**
 * 

* 用户信息表 服务实现类 *

* * @author mwy * @since 2022-03-15 */ @Service public class UserServiceImpl extends ServiceImpl implements IUserService { @Autowired private IRedisService redisService; @Override public ResponseResult findByAccount(UserVo userVo, HttpServletRequest request, HttpServletResponse response) { // 先判断信息是否符合(账号是否是手机号码,密码是不是空) if(!ValidatorUtils.isMobile(userVo.getMobile())){ throw new BusinessException(ResponseResultCode.USER_ACCOUNT_NOT_MOBLIE); } if(StringUtils.isBlank(userVo.getPassword())){ throw new BusinessException(ResponseResultCode.USER_PASSWORD_NOT_MATCH); } // 再去数据库查出对应的用户(mobile) User user=this.getOne(new QueryWrapper().eq("id",userVo.getMobile())); if(user==null){ throw new BusinessException(ResponseResultCode.USER_ACCOUNT_NOT_FIND); } // 比较密码 // 二重加密(前端->后端,后端->数据库) String salt=user.getSalt(); // 将前台的加密密码和后端的盐再次进行加密 String newPassword=MD5Utils.formPassToDbPass(userVo.getPassword(),salt); if(!newPassword.equals(user.getPassword())){ throw new BusinessException(ResponseResultCode.USER_PASSWORD_NOT_MATCH); } // 修改最后的登录时间 this.update(new UpdateWrapper().eq("id",userVo.getMobile()).set("last_login_date",new Date()).setSql("login_count=login_count+1")); // 最初的版本(session:全局共用,uuid:不可能重复) String ticket = UUID.randomUUID().toString().replace("-", ""); // request.getSession().setAttribute("user",user); // 放入全局或者单个服务器的session // request.getSession().setAttribute(ticket,user); // 放入缓存中去 redisService.putUserByTicket(ticket,user); // 将我生成的ticket给用户,用户如何验证? 使用cookie,cookie在客户端,session在服务端 // Cookie cookie=new Cookie("ticket",ticket); // response.addCookie(cookie); 这样写会导致设置时间麻烦 CookieUtils.setCookie(request,response,"ticket",ticket); return ResponseResult.success(); } }

(5)运行测试

秒杀项目之验证功能_第9张图片

秒杀项目之验证功能_第10张图片

 3、解决时间获取异常问题

解决登录后进去首页出错问题

秒杀项目之验证功能_第11张图片

(1)配置解析器,声明解析规则才能获得时间

(2)修改实体类时间类型

①、将类型改为时间戳

 秒杀项目之验证功能_第12张图片

 (3)运行测试

秒杀项目之验证功能_第13张图片

 秒杀项目之验证功能_第14张图片

直接进去首页

秒杀项目之验证功能_第15张图片

 四、使用参数解析器

1、解决除访问登录界面,都需要凭证的问题(解决重复代码问题)

(1)修改PathController

package com.mwy.seckill.controller;
import com.mwy.seckill.exception.BusinessException;
import com.mwy.seckill.pojo.User;
import com.mwy.seckill.service.IRedisService;
import com.mwy.seckill.util.CookieUtils;
import com.mwy.seckill.util.response.ResponseResultCode;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.CookieValue;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import javax.servlet.http.HttpServletRequest;
@Controller
public class PathController {

    //    登录跳首页
    @RequestMapping("/")
    public String toPath(){
        return "login";
    }

    //   单纯做登录验证使用拦截器,这里为了给参数赋值,所以使用参数解析器
    @RequestMapping("/{dir}/{path}")
    public String toPath(@PathVariable("dir") String dir, @PathVariable("path") String path,User user) {
        return dir+"/"+path;
    }
}

(2)新增参数解析器

①、UserArgumentResolvers

package com.mwy.seckill.config;
import com.mwy.seckill.exception.BusinessException;
import com.mwy.seckill.pojo.User;
import com.mwy.seckill.service.IRedisService;
import com.mwy.seckill.util.CookieUtils;
import com.mwy.seckill.util.response.ResponseResultCode;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.core.MethodParameter;
import org.springframework.stereotype.Component;
import org.springframework.web.bind.support.WebDataBinderFactory;
import org.springframework.web.context.request.NativeWebRequest;
import org.springframework.web.method.support.HandlerMethodArgumentResolver;
import org.springframework.web.method.support.ModelAndViewContainer;
import javax.servlet.http.HttpServletRequest;
//声明为组件
@Component
public class UserArgumentResolvers implements HandlerMethodArgumentResolver {

    //supportsParameter决定了resolveArgument是否运行
    
    @Autowired
    private IRedisService redisService;

    @Override
    public boolean supportsParameter(MethodParameter methodParameter) {
        return methodParameter.getParameterType() == User.class;
    }

    @Override
    public Object resolveArgument(MethodParameter methodParameter, ModelAndViewContainer modelAndViewContainer, NativeWebRequest nativeWebRequest, WebDataBinderFactory webDataBinderFactory) throws Exception {
        //参数解析User 因为很多地方需要做登录验证
        HttpServletRequest request=(HttpServletRequest)nativeWebRequest.getNativeRequest();
        //获取用户的ticket
        String ticket= CookieUtils.getCookieValue(request, "ticket");
        if(ticket == null){
            throw new BusinessException(ResponseResultCode.TICKET_ERROR);
        }
        //去session中取到ticket对应的用户 判断是否有值
        //Object obj = request.getSession().getAttribute(ticket);
        //去缓存中拿
        User user = redisService.getUserByTicket(ticket);
        if(user==null){
            throw new BusinessException(ResponseResultCode.TICKET_ERROR);
        }
        //经过了参数解析之后  参数会变成你这个地方返回的值
        return user;
    }
}

(3)配置类

①、WebConfig

package com.mwy.seckill.config;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.method.support.HandlerMethodArgumentResolver;
import org.springframework.web.servlet.config.annotation.EnableWebMvc;
import org.springframework.web.servlet.config.annotation.ResourceHandlerRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
import java.util.List;
//配置类
@Configuration
//打开WebMvc的功能
@EnableWebMvc
public class WebConfig implements WebMvcConfigurer {

//    引用参数解析器
    @Autowired
    private UserArgumentResolvers userArgumentsResolvers;

    @Override
    public void addArgumentResolvers(List resolvers) {
        resolvers.add(userArgumentsResolvers);
    }
    @Override
    public void addResourceHandlers(ResourceHandlerRegistry registry) {
        //静态资源访问映射  映射路径 -> 本地资源路径
        registry.addResourceHandler("/static/**")
                .addResourceLocations("classpath:/static/");
    }
}

(4)运行测试

①、user的值是解析器里面来的

秒杀项目之验证功能_第16张图片

 秒杀项目之验证功能_第17张图片

秒杀项目之验证功能_第18张图片

结束!!!

你可能感兴趣的:(java,webview,开发语言)