高并发项目-分布式Session解决方案

立山  金牌会员 | 2024-6-29 13:27:49 | 来自手机 | 显示全部楼层 | 阅读模式
打印 上一主题 下一主题

主题 580|帖子 580|积分 1740

分布式Session解决方案

1.生存Session,进入商品列表页面

1.生存Session

1.编写工具类

1.MD5Util.java

  1. package com.sxs.seckill.utils;
  2. import org.apache.commons.codec.digest.DigestUtils;
  3. /**
  4. * Description: MD5加密工具类
  5. *
  6. * @Author sun
  7. * @Create 2024/5/5 14:23
  8. * @Version 1.0
  9. */
  10. public class MD5Util {
  11.     /**
  12.      * 将一个字符串转换为MD5
  13.      * @param src
  14.      * @return
  15.      */
  16.     public static String md5(String src) {
  17.         return DigestUtils.md5Hex(src);
  18.     }
  19.     // 固定的salt
  20.     public static final String SALT = "4tIY5VcX";
  21.     // 第一次加密加盐
  22.     public static String inputPassToMidPass(String inputPass) {
  23.         // 加盐
  24.         String str = SALT.charAt(0) + inputPass + SALT.charAt(6);
  25.         return md5(str);
  26.     }
  27.     /**
  28.      * 第二次加密加盐
  29.      * @param midPass
  30.      * @param salt
  31.      * @return
  32.      */
  33.     public static String midPassToDBPass(String midPass, String salt) {
  34.         String str = salt.charAt(0) + midPass + salt.charAt(5);
  35.         return md5(str);
  36.     }
  37.     /**
  38.      * 两次加密
  39.      * @param input
  40.      * @param saltDB
  41.      * @return
  42.      */
  43.     public static String inputPassToDBPass(String input, String saltDB) {
  44.         String midPass = inputPassToMidPass(input);
  45.         String dbPass = midPassToDBPass(midPass, saltDB);
  46.         return dbPass;
  47.     }
  48. }
复制代码
2.CookieUtil.java

  1. package com.sxs.seckill.utils;
  2. import javax.servlet.http.Cookie;
  3. import javax.servlet.http.HttpServletRequest;
  4. import javax.servlet.http.HttpServletResponse;
  5. import java.io.UnsupportedEncodingException;
  6. import java.net.URLDecoder;
  7. import java.net.URLEncoder;
  8. /**
  9. * Description: Cookie工具类
  10. *
  11. * @Author sun
  12. * @Create 2024/5/6 16:04
  13. * @Version 1.0
  14. */
  15. public class CookieUtil {
  16.     /**
  17.      * 得到 Cookie 的值, 不编码
  18.      *
  19.      * @param request
  20.      * @param cookieName
  21.      * @return
  22.      */
  23.     public static String getCookieValue(HttpServletRequest request, String
  24.             cookieName) {
  25.         return getCookieValue(request, cookieName, false);
  26.     }
  27.     /**
  28.      * 得到 Cookie 的值, *
  29.      *
  30.      * @param request
  31.      * @param cookieName
  32.      * @return
  33.      */
  34.     public static String getCookieValue(HttpServletRequest request, String
  35.             cookieName, boolean isDecoder) {
  36.         Cookie[] cookieList = request.getCookies();
  37.         if (cookieList == null || cookieName == null) {
  38.             return null;
  39.         }
  40.         String retValue = null;
  41.         try {
  42.             for (int i = 0; i < cookieList.length; i++) {
  43.                 if (cookieList[i].getName().equals(cookieName)) {
  44.                     if (isDecoder) {
  45.                         retValue = URLDecoder.decode(cookieList[i].getValue(), "UTF-8");
  46.                     } else {
  47.                         retValue = cookieList[i].getValue();
  48.                     }
  49.                     break;
  50.                 }
  51.             }
  52.         } catch (UnsupportedEncodingException e) {
  53.             e.printStackTrace();
  54.         }
  55.         return retValue;
  56.     }
  57.     /**
  58.      * 得到 Cookie 的值, *
  59.      *
  60.      * @param request
  61.      * @param cookieName
  62.      * @param encodeString
  63.      * @return
  64.      */
  65.     public static String getCookieValue(HttpServletRequest request, String
  66.             cookieName, String encodeString) {
  67.         Cookie[] cookieList = request.getCookies();
  68.         if (cookieList == null || cookieName == null) {
  69.             return null;
  70.         }
  71.         String retValue = null;
  72.         try {
  73.             for (int i = 0; i < cookieList.length; i++) {
  74.                 if (cookieList[i].getName().equals(cookieName)) {
  75.                     retValue = URLDecoder.decode(cookieList[i].getValue(), encodeString);
  76.                     break;
  77.                 }
  78.             }
  79.         } catch (UnsupportedEncodingException e) {
  80.             e.printStackTrace();
  81.         }
  82.         return retValue;
  83.     }
  84.     /**
  85.      * 设置 Cookie 的值 不设置生效时间默认浏览器关闭即失效,也不编码
  86.      */
  87.     public static void setCookie(HttpServletRequest request, HttpServletResponse
  88.             response, String cookieName, String cookieValue) {
  89.         setCookie(request, response, cookieName, cookieValue, -1);
  90.     }
  91.     /**
  92.      * 设置 Cookie 的值 在指定时间内生效,但不编码
  93.      */
  94.     public static void setCookie(HttpServletRequest request, HttpServletResponse
  95.             response, String cookieName, String cookieValue, int cookieMaxage) {
  96.         setCookie(request, response, cookieName, cookieValue, cookieMaxage,
  97.                 false);
  98.     }
  99.     /**
  100.      * 设置 Cookie 的值 不设置生效时间,但编码
  101.      */
  102.     public static void setCookie(HttpServletRequest request, HttpServletResponse
  103.             response, String cookieName, String cookieValue, boolean isEncode) {
  104.         setCookie(request, response, cookieName, cookieValue, -1, isEncode);
  105.     }
  106.     /**
  107.      * 设置 Cookie 的值 在指定时间内生效, 编码参数
  108.      */
  109.     public static void setCookie(HttpServletRequest request, HttpServletResponse
  110.             response, String cookieName, String cookieValue, int cookieMaxage, boolean
  111.                                          isEncode) {
  112.         doSetCookie(request, response, cookieName, cookieValue, cookieMaxage,
  113.                 isEncode);
  114.     }
  115.     /**
  116.      * 设置 Cookie 的值 在指定时间内生效, 编码参数(指定编码)
  117.      */
  118.     public static void setCookie(HttpServletRequest request, HttpServletResponse
  119.             response, String cookieName, String cookieValue, int cookieMaxage, String
  120.                                          encodeString) {
  121.         doSetCookie(request, response, cookieName, cookieValue, cookieMaxage, encodeString);
  122.     }
  123.     /**
  124.      * 删除 Cookie 带 cookie 域名
  125.      */
  126.     public static void deleteCookie(HttpServletRequest request, HttpServletResponse response, String cookieName) {
  127.         doSetCookie(request, response, cookieName, "", -1, false);
  128.     }
  129.     /**
  130.      * 设置 Cookie 的值,并使其在指定时间内生效
  131.      *
  132.      * @param cookieMaxage cookie 生效的最大秒数
  133.      */
  134.     private static final void doSetCookie(HttpServletRequest request, HttpServletResponse response, String cookieName, String cookieValue,
  135.                                           int cookieMaxage, boolean isEncode) {
  136.         try {
  137.             if (cookieValue == null) {
  138.                 cookieValue = "";
  139.             } else if (isEncode) {
  140.                 cookieValue = URLEncoder.encode(cookieValue, "utf-8");
  141.             }
  142.             Cookie cookie = new Cookie(cookieName, cookieValue);
  143.             if (cookieMaxage > 0) {
  144.                 cookie.setMaxAge(cookieMaxage);
  145.             }
  146.             // if (null != request) {// 设置域名的 cookie
  147.             // String domainName = getDomainName(request);
  148.             // if (!"localhost".equals(domainName)) {
  149.             // cookie.setDomain(domainName);
  150.             // }
  151.             // }
  152.             cookie.setPath("/");
  153.             response.addCookie(cookie);
  154.         } catch (Exception e) {
  155.             e.printStackTrace();
  156.         }
  157.     }
  158.     /**
  159.      * 设置 Cookie 的值,并使其在指定时间内生效
  160.      *
  161.      * @param cookieMaxage cookie 生效的最大秒数
  162.      */
  163.     private static final void doSetCookie(HttpServletRequest request,
  164.                                           HttpServletResponse response, String cookieName, String cookieValue,
  165.                                           int cookieMaxage, String encodeString) {
  166.         try {
  167.             if (cookieValue == null) {
  168.                 cookieValue = "";
  169.             } else {
  170.                 cookieValue = URLEncoder.encode(cookieValue, encodeString);
  171.             }
  172.             Cookie cookie = new Cookie(cookieName, cookieValue);
  173.             if (cookieMaxage > 0) {
  174.                 cookie.setMaxAge(cookieMaxage);
  175.             }
  176.             if (null != request) {// 设置域名的 cookie
  177.                 String domainName = getDomainName(request);
  178.                 System.out.println(domainName);
  179.                 if (!"localhost".equals(domainName)) {
  180.                     cookie.setDomain(domainName);
  181.                 }
  182.             }
  183.             cookie.setPath("/");
  184.             response.addCookie(cookie);
  185.         } catch (Exception e) {
  186.             e.printStackTrace();
  187.         }
  188.     }
  189.     /**
  190.      * 得到 cookie 的域名
  191.      */
  192.     private static final String getDomainName(HttpServletRequest request) {
  193.         String domainName = null;
  194.         // 通过 request 对象获取访问的 url 地址
  195.         String serverName = request.getRequestURL().toString();
  196.         if ("".equals(serverName)) {
  197.             domainName = "";
  198.         } else {
  199.             // 将 url 地下转换为小写
  200.             serverName = serverName.toLowerCase();
  201.             // 如果 url 地址是以 http://开头 将 http://截取
  202.             if (serverName.startsWith("http://")) {
  203.                 serverName = serverName.substring(7);
  204.             }
  205.             int end = serverName.length();
  206.             // 判断 url 地址是否包含"/"
  207.             if (serverName.contains("/")) {
  208.                 // 得到第一个"/"出现的位置
  209.                 end = serverName.indexOf("/");
  210.             }
  211.             // 截取
  212.             serverName = serverName.substring(0, end);
  213.             // 根据"."进行分割
  214.             final String[] domains = serverName.split("\\.");
  215.             int len = domains.length;
  216.             if (len > 3) {
  217.                 // www.abc.com.cn
  218.                 domainName = domains[len - 3] + "." + domains[len - 2] + "." +
  219.                         domains[len - 1];
  220.             } else if (len > 1) {
  221.                 // abc.com or abc.cn
  222.                 domainName = domains[len - 2] + "." + domains[len - 1];
  223.             } else {
  224.                 domainName = serverName;
  225.             }
  226.         }
  227.         if (domainName.indexOf(":") > 0) {
  228.             String[] ary = domainName.split("\\:");
  229.             domainName = ary[0];
  230.         }
  231.         return domainName;
  232.     }
  233. }
复制代码
2.关于session和cookie关系的回顾



  • 当欣赏器请求到服务端时cookie会携带sessionid
  • 然后在服务端getSession时会得到当前用户的session
  • cookie-sessionid 连接到session
3.修改UserServiceImpl.java的doLogin方法,增长生存信息到session的逻辑


4.测试,用户票据成功生存到cookie中


2.访问到商品列表页面

1.编写GoodsController.java 验证用户登录后进入商品列表页

  1. package com.sxs.seckill.controller;
  2. import com.sxs.seckill.pojo.User;
  3. import lombok.extern.slf4j.Slf4j;
  4. import org.springframework.stereotype.Controller;
  5. import org.springframework.ui.Model;
  6. import org.springframework.web.bind.annotation.CookieValue;
  7. import org.springframework.web.bind.annotation.RequestMapping;
  8. import javax.servlet.http.HttpSession;
  9. /**
  10. * Description:
  11. *
  12. * @Author sun
  13. * @Create 2024/5/6 18:16
  14. * @Version 1.0
  15. */
  16. @Controller
  17. @Slf4j
  18. @RequestMapping("/goods")
  19. public class GoodsController {
  20.     // 进入到商品首页
  21.     @RequestMapping("/toList")
  22.     public String toList(HttpSession session, Model model, @CookieValue("userTicket") String ticket) {
  23.         // 首先判断是否有票据
  24.         if (null == ticket) {
  25.             return "login";
  26.         }
  27.         // 根据票据来获取用户信息
  28.         User user = (User) session.getAttribute(ticket);
  29.         if (null == user) {
  30.             return "login";
  31.         }
  32.         // 将用户信息存入model中,返回到前端
  33.         model.addAttribute("user", user);
  34.         return "goodsList";
  35.     }
  36. }
复制代码
2.商品列表页goodsList.html

  1. <!DOCTYPE html>
  2. <html lang="en" xmlns:th="http://www.thymeleaf.org">
  3. <head>
  4.     <meta charset="UTF-8">
  5.     <title>商品列表</title>
  6. </head>
  7. <body>
  8. <h1>商品列表</h1>
  9. <p th:text="'hi: ' + ${user.nickname}"></p>
  10. </body>
  11. </html>
复制代码
3.测试登录成功后进入商品列表页



2.分布式session解决方案

1.session绑定/粘滞(不常用)



2.session复制



3.前端存储


4.后端会合存储


3.方案一:SpringSession实现分布式Session

1.安装使用redis-desktop-manager

1.不停下一步,安装到D盘


2.起首要确保redis集群的端口是开放的并使其支持远程访问(之前配置过)

3.使用telnet指令测试某个服务是否能够连接成功

  1. telnet 140.143.164.206 7489
复制代码

4.连接Redis,先测试连接然后确定


5.在redis下令行设置两个键


6.在可视化工具检察


2.项目整合Redis并配置分布式session

1.pom.xml引入依赖

  1.         <!--spring data redis 依赖, 即 spring 整合 redis-->
  2.         <dependency>
  3.             <groupId>org.springframework.boot</groupId>
  4.             <artifactId>spring-boot-starter-data-redis</artifactId>
  5.             <version>2.4.5</version>
  6.         </dependency>
  7.         <!--pool2 对象池依赖-->
  8.         <dependency>
  9.             <groupId>org.apache.commons</groupId>
  10.             <artifactId>commons-pool2</artifactId>
  11.             <version>2.9.0</version>
  12.         </dependency>
  13.         <!--实现分布式 session, 即将 Session 保存到指定的 Redis-->
  14.         <dependency>
  15.             <groupId>org.springframework.session</groupId>
  16.             <artifactId>spring-session-data-redis</artifactId>
  17.         </dependency>
复制代码
2.application.yml配置Redis

  1. spring:
  2.   redis:
  3.     password:  # Redis服务器密码
  4.     database: 0 # 默认数据库为0号
  5.     timeout: 10000ms # 连接超时时间是10000毫秒
  6.     lettuce:
  7.       pool:
  8.         max-active: 8 # 最大活跃连接数,使用负值表示没有限制,最佳配置为核数*2
  9.         max-wait: 10000ms # 最大等待时间,单位为毫秒,使用负值表示没有限制,这里设置为10秒
  10.         max-idle: 200 # 最大空闲连接数
  11.         min-idle: 5 # 最小空闲连接数
  12.     cluster:
  13.       nodes:
  14.         -
  15.         -
复制代码

3.启动测试

1.登录


2.Redis可视化工具发现session成功存到redis



4.方案二:统一存放用户信息到Redis

1.修改pom.xml,去掉分布式springsession的依赖


2.将用户信息放到Redis

1.添加Redis配置类 com/sxs/seckill/config/RedisConfig.java

  1. package com.sxs.seckill.config;
  2. import com.fasterxml.jackson.annotation.JsonAutoDetect;
  3. import com.fasterxml.jackson.annotation.JsonTypeInfo;
  4. import com.fasterxml.jackson.annotation.PropertyAccessor;
  5. import com.fasterxml.jackson.databind.ObjectMapper;
  6. import com.fasterxml.jackson.databind.jsontype.impl.LaissezFaireSubTypeValidator;
  7. import org.springframework.cache.CacheManager;
  8. import org.springframework.cache.annotation.CachingConfigurerSupport;
  9. import org.springframework.cache.annotation.EnableCaching;
  10. import org.springframework.context.annotation.Bean;
  11. import org.springframework.context.annotation.Configuration;
  12. import org.springframework.data.redis.cache.RedisCacheConfiguration;
  13. import org.springframework.data.redis.cache.RedisCacheManager;
  14. import org.springframework.data.redis.connection.RedisConnectionFactory;
  15. import org.springframework.data.redis.core.RedisTemplate;
  16. import org.springframework.data.redis.serializer.Jackson2JsonRedisSerializer;
  17. import org.springframework.data.redis.serializer.RedisSerializationContext;
  18. import org.springframework.data.redis.serializer.RedisSerializer;
  19. import org.springframework.data.redis.serializer.StringRedisSerializer;
  20. import java.time.Duration;
  21. /**
  22. * Description:
  23. *
  24. * @Author sun
  25. * @Create 2024/4/29 21:29
  26. * @Version 1.0
  27. */
  28. @EnableCaching
  29. @Configuration
  30. public class RedisConfig extends CachingConfigurerSupport {
  31.     @Bean
  32.     public RedisTemplate<String, Object> redisTemplate(RedisConnectionFactory factory) {
  33.         RedisTemplate<String, Object> template =
  34.                 new RedisTemplate<>();
  35.         System.out.println("template=>" + template);
  36.         RedisSerializer<String> redisSerializer =
  37.                 new StringRedisSerializer();
  38.         Jackson2JsonRedisSerializer jackson2JsonRedisSerializer =
  39.                 new Jackson2JsonRedisSerializer(Object.class);
  40.         ObjectMapper om = new ObjectMapper();
  41.         om.setVisibility(PropertyAccessor.ALL, JsonAutoDetect.Visibility.ANY);
  42.         om.activateDefaultTyping(
  43.                 LaissezFaireSubTypeValidator.instance, ObjectMapper.DefaultTyping.NON_FINAL, JsonTypeInfo.As.WRAPPER_ARRAY);
  44.         jackson2JsonRedisSerializer.setObjectMapper(om);
  45.         template.setConnectionFactory(factory);
  46.         // key 序列化方式
  47.         template.setKeySerializer(redisSerializer);
  48.         // value 序列化
  49.         template.setValueSerializer(jackson2JsonRedisSerializer);
  50.         // value hashmap 序列化
  51.         template.setHashValueSerializer(jackson2JsonRedisSerializer);
  52.         return template;
  53.     }
  54.     @Bean
  55.     public CacheManager cacheManager(RedisConnectionFactory factory) {
  56.         RedisSerializer<String> redisSerializer =
  57.                 new StringRedisSerializer();
  58.         Jackson2JsonRedisSerializer jackson2JsonRedisSerializer = new
  59.                 Jackson2JsonRedisSerializer(Object.class);
  60.         // 解决查询缓存转换异常的问题
  61.         ObjectMapper om = new ObjectMapper();
  62.         om.setVisibility(PropertyAccessor.ALL, JsonAutoDetect.Visibility.ANY);
  63.         om.activateDefaultTyping(
  64.                 LaissezFaireSubTypeValidator.instance, ObjectMapper.DefaultTyping.NON_FINAL, JsonTypeInfo.As.WRAPPER_ARRAY);
  65.         jackson2JsonRedisSerializer.setObjectMapper(om);
  66.         // 配置序列化(解决乱码的问题),过期时间 600 秒
  67.         RedisCacheConfiguration config = RedisCacheConfiguration.defaultCacheConfig()
  68.                 .entryTtl(Duration.ofSeconds(600))
  69.                 .serializeKeysWith(RedisSerializationContext.SerializationPair.fromSerializer(redisSerializer))
  70.                 .serializeValuesWith(RedisSerializationContext.SerializationPair.fromSerializer(jackson2JsonRedisSerializer))
  71.                 .disableCachingNullValues();
  72.         RedisCacheManager cacheManager = RedisCacheManager.builder(factory)
  73.                 .cacheDefaults(config)
  74.                 .build();
  75.         return cacheManager;
  76.     }
  77. }
复制代码
2.修改 com/sxs/seckill/service/impl/UserServiceImpl.java

1.注入RedisTemplate


2.修改doLogin方法,将用户信息放到Redis中


3.启动测试

1.登录


2.可视化工具检察用户信息


3.实现使用Redis + Cookie实现登录,可以访问商品列表页面

1.刚才已经实现了Redis记录信息的功能,但是校验还没实现,修改GoodsController.java完成校验

1.注入RedisTemplate


2.从Redis中获取校验信息,举行校验


2.测试

1.登录成功后访问商品列表页面


5.扩展:自定义参数剖析器,直接获取User

1.修改 com/sxs/seckill/controller/GoodsController.java 使参数直接为User

  1.     // 进入到商品首页
  2.     @RequestMapping("/toList")
  3.     public String toList(Model model, User user) {
  4.         // 判断是否有用户信息
  5.         if (null == user) {
  6.             return "login";
  7.         }
  8.         // 将用户信息存入model中,返回到前端
  9.         model.addAttribute("user", user);
  10.         return "goodsList";
  11.     }
复制代码
2.service层添加方法,通过票据从Redis中获取User对象

1.UserService.java

  1.     /**
  2.      * 根据cookie获取用户
  3.      * @param userTicket
  4.      * @param request
  5.      * @param response
  6.      * @return
  7.      */
  8.     public User getUserByCookie(String userTicket, HttpServletRequest request, HttpServletResponse response);
复制代码
2.UserServiceImpl.java



  • 这里需要留意,每次获取完User,需要重新设置Cookie,来革新Cookie的时间
  • 缘故原由是,调用这个的目标是为了校验,而用户访问每个页面都要举行校验,如果每次校验之后都不革新Cookie的时间,一旦Cookie失效了,用户就要重新登岸
  1.     @Override
  2.     public User getUserByCookie(String userTicket, HttpServletRequest request, HttpServletResponse response) {
  3.         // 判断是否有票据
  4.         if (null == userTicket) {
  5.             return null;
  6.         }
  7.         // 根据票据来获取用户信息,从redis中获取
  8.         User user = (User) redisTemplate.opsForValue().get("user:" + userTicket);
  9.         if (null == user) {
  10.             return null;
  11.         }
  12.         // 重新设置cookie的有效时间
  13.         CookieUtil.setCookie(request, response, "userTicket", userTicket);
  14.         return user;
  15.     }
复制代码
3.编写自定义参数剖析器对User范例参数举行剖析 config/UserArgumentResolver.java

  1. package com.sxs.seckill.config;
  2. import com.sxs.seckill.pojo.User;
  3. import com.sxs.seckill.service.UserService;
  4. import com.sxs.seckill.utils.CookieUtil;
  5. import org.springframework.core.MethodParameter;
  6. import org.springframework.stereotype.Component;
  7. import org.springframework.web.bind.support.WebDataBinderFactory;
  8. import org.springframework.web.context.request.NativeWebRequest;
  9. import org.springframework.web.method.support.HandlerMethodArgumentResolver;
  10. import org.springframework.web.method.support.ModelAndViewContainer;
  11. import javax.annotation.Resource;
  12. import javax.servlet.http.HttpServletRequest;
  13. import javax.servlet.http.HttpServletResponse;
  14. /**
  15. * Description: 自定义参数解析器
  16. *
  17. * @Author sun
  18. * @Create 2024/5/7 14:39
  19. * @Version 1.0
  20. */
  21. @Component
  22. public class UserArgumentResolver implements HandlerMethodArgumentResolver {
  23.     @Resource
  24.     private UserService userService;
  25.     /*
  26.      * 判断是否支持要转换的参数类型,简单来说,就是在这里设置要解析的参数类型
  27.      */
  28.     @Override
  29.     public boolean supportsParameter(MethodParameter methodParameter) {
  30.         // 如果参数类型是User,则进行解析
  31.         Class<?> parameterType = methodParameter.getParameterType();
  32.         if (parameterType == User.class) {
  33.             return true;
  34.         }
  35.         return false;
  36.     }
  37.     /**
  38.      * 编写参数解析的逻辑
  39.      *
  40.      * @param methodParameter
  41.      * @param modelAndViewContainer
  42.      * @param nativeWebRequest
  43.      * @param webDataBinderFactory
  44.      * @return
  45.      * @throws Exception
  46.      */
  47.     @Override
  48.     public Object resolveArgument(MethodParameter methodParameter, ModelAndViewContainer modelAndViewContainer, NativeWebRequest nativeWebRequest, WebDataBinderFactory webDataBinderFactory) throws Exception {
  49.         // 首先获取request和response
  50.         HttpServletRequest request = nativeWebRequest.getNativeRequest(HttpServletRequest.class);
  51.         HttpServletResponse response = nativeWebRequest.getNativeResponse(HttpServletResponse.class);
  52.         // 从cookie中获取票据
  53.         String userTicket = CookieUtil.getCookieValue(request, "userTicket");
  54.         // 如果票据为空,则返回null
  55.         if (null == userTicket) {
  56.             return null;
  57.         }
  58.         // 如果票据不为空,则根据票据获取用户信息
  59.         User user = this.userService.getUserByCookie(userTicket, request, response);
  60.         return user;
  61.     }
  62. }
复制代码
4.编写config/WebConfig.java 将自定义参数剖析器放到 resolvers 才气见效

  1. package com.sxs.seckill.config;
  2. import org.springframework.context.annotation.Configuration;
  3. import org.springframework.web.method.support.HandlerMethodArgumentResolver;
  4. import org.springframework.web.servlet.config.annotation.EnableWebMvc;
  5. import org.springframework.web.servlet.config.annotation.ResourceHandlerRegistry;
  6. import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
  7. import javax.annotation.Resource;
  8. import java.util.List;
  9. /**
  10. * Description:
  11. *
  12. * @Author sun
  13. * @Create 2024/5/7 14:53
  14. * @Version 1.0
  15. */
  16. @Configuration
  17. // @EnableWebMvc 使用这个注解会导致SpringBoot的自动配置失效,一切都要自己配置,所以建议不要使用这个注解
  18. public class WebConfig implements WebMvcConfigurer {
  19.     // 注入自定义参数解析器
  20.     @Resource
  21.     private UserArgumentResolver userArgumentResolver;
  22.     /**
  23.      * 静态资源加载,静态资源放在哪里就怎么配置
  24.      * @param registry
  25.      */
  26.     @Override
  27.     public void addResourceHandlers(ResourceHandlerRegistry registry) {
  28.         registry.addResourceHandler("/**").addResourceLocations("classpath:/static/");
  29.     }
  30.     /**
  31.      * 添加自定义参数解析器到resolvers中,才能生效
  32.      * @param resolvers
  33.      */
  34.     @Override
  35.     public void addArgumentResolvers(List<HandlerMethodArgumentResolver> resolvers) {
  36.         resolvers.add(userArgumentResolver);
  37.     }
  38. }
复制代码
5.测试

1.在登录之后,可以正常访问商品列表页面



免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!更多信息从访问主页:qidao123.com:ToB企服之家,中国第一个企服评测及商务社交产业平台。

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有账号?立即注册

x
回复

使用道具 举报

0 个回复

倒序浏览

快速回复

您需要登录后才可以回帖 登录 or 立即注册

本版积分规则

立山

金牌会员
这个人很懒什么都没写!

标签云

快速回复 返回顶部 返回列表