分布式session实现
实现原理
服务器将数据保存在redis中,并将redis_key放入cookie中,返回给浏览器,其他服务器获取cookie从而得到数据
- 生成redis_key ,并将数据存入redis中,
- 将redis_key存入cookie 中,并返回给浏览器,
- 定义WebConfig,让其每次都返回需要的cookie中的数据(重点)
- 修改原本的数据获取逻辑
优点:
实现简单,获取方便
缺点:
无论需不需要每次都会返回保存的数据,增大传输时间。 同时为了保证cookie的不过期,必须每次获取后重写设置值。
每次传参数都需要HttpServletResponse,用于获取数据
代码
保存并返回数据方法
/*
* 将user信息存入redis中redis_key
* 将redis_key存入cookie中
* **/
private void addCookie(HttpServletResponse response, String token, User user) {
//保存数据到redis中token为key,user为值
redisService.set(token, user);
Cookie cookie = new Cookie(COOKI_NAME_TOKEN, token);
// 配置存活时间
cookie.setMaxAge(MiaoshaUserKey.token.expireSeconds());
// 设置根url
cookie.setPath("/");
//加入到response
response.addCookie(cookie);
}
WebConfig(设置HTTP协议每次都传输User)
@Configuration
public class WebConfig extends WebMvcConfigurationSupport {
@Autowired
UserArgumentResolver userArgumentResolver;
@Override
//增加传输User对象
public void addArgumentResolvers(List<HandlerMethodArgumentResolver> argumentResolvers) {
argumentResolvers.add(userArgumentResolver);
}
}
UserArgumentResolver(获取cookie中的User)
@Service
public class UserArgumentResolver implements HandlerMethodArgumentResolver {
@Autowired
MiaoshaUserService userService;
// 是否支持该参数
public boolean supportsParameter(MethodParameter parameter) {
Class<?> clazz = parameter.getParameterType();
return clazz==MiaoshaUser.class;
}
// 获取 实体数据
public Object resolveArgument(MethodParameter parameter, ModelAndViewContainer mavContainer,
NativeWebRequest webRequest, WebDataBinderFactory binderFactory) throws Exception {
// 获取request
HttpServletRequest request = webRequest.getNativeRequest(HttpServletRequest.class);
// 获取response
HttpServletResponse response = webRequest.getNativeResponse(HttpServletResponse.class);
// 从参数中得到
String paramToken = request.getParameter(MiaoshaUserService.COOKI_NAME_TOKEN);
// 从cookie中得到
String cookieToken = getCookieValue(request, MiaoshaUserService.COOKI_NAME_TOKEN);
if(StringUtils.isEmpty(cookieToken) && StringUtils.isEmpty(paramToken)) {
return null;
}
// 判断是从cookie中得到的还是url参数
String token = StringUtils.isEmpty(paramToken)?cookieToken:paramToken;
return userService.getByToken(response, token);
}
// 获取Cookie
private String getCookieValue(HttpServletRequest request, String cookiName) {
Cookie[] cookies = request.getCookies();
if(cookies == null || cookies.length ==0){
return null;
}
// 获取cookie中的user
for(Cookie cookie : cookies) {
if(cookie.getName().equals(cookiName)) {
return cookie.getValue();
}
}
return null;
}
}
controller获取方法
@RequestMapping("/to_list")
//前端未传输User,该user有http中得到
public String list(Model model, User user) {
model.addAttribute("user", user);
return "goods_list";
}