2-4 分布式session

1、当软件在实际运行过程中,往往有多台服务器为用户提供服务。所以有可能用户的第一次http请求落在了第一个服务器上,第二个http请求落在了第二个服务器上。如果把session保存在服务器上的话,需要服务器做同步,如果服务器有很多个的话,同步就会消耗大量资源。

这里采用将用户和一个token标记在一起,这里的“用户”是从miaosha_user表中取出的,连同生成的cookie一起放入linux中的redis数据库中,redis相当于是缓存(其中的数据以key,value的形式存放)。

redisService.set(MiaoshaUserKey.token, token, user);//分别为"tk",生成的token,用户的登陆信息

2、也就是说,user可能需要在各个页面被使用。

如何取出user? 

从redis数据库中取出,key 类似于 : "MiaoshaUserKey:tk9115b3cf113844a0aebba55b84f2c45d"。value类似于:"{\"id\":13812341234,\"lastLoginDate\":1525479947000,\"loginCount\":1,\"nickname\":\"joshua\",\"password\":\"b7797cce01b4b131b433b6acf4add449\",\"registerDate\":1522801539000,\"salt\":\"1a2b3c4d\"}"

3、可以在登陆成功的时候把token存在客户端中,以后用到的时候再取出:

redisService.set(MiaoshaUserKey.token, token, user);//分别为"tk",生成的token,用户的登陆信息
private void addCookie(HttpServletResponse response, MiaoshaUser user){
String token = UUIDUtil.uuid();//uuid()是静态方法,但是每次生成的token是不一样的。
redisService.set(MiaoshaUserKey.token, token, user);//分别为"tk",生成的token,用户的登陆信息
Cookie cookie = new Cookie(COOKIE1_NAME_TOKEN, token);
cookie.setMaxAge(MiaoshaUserKey.token.expireSeconds());
cookie.setPath("/");
response.addCookie(cookie);
}

4、如何从cookie中取出token信息?

每个页面都需要用到user对象,user对象需要根据token从redis数据库中取出。也就是说,每个页面对应的controller都需要写一些从cookie中取出token信息的代码.

    public String list(HttpServletResponse response, Model model,
    @CookieValue(value=MiaoshaUserService.COOKIE1_NAME_TOKEN, required=false) String cookieToken,
    @RequestParam(value=MiaoshaUserService.COOKIE1_NAME_TOKEN, required=false) String paramToken
    ) {
if(StringUtils.isEmpty(cookieToken) && StringUtils.isEmpty(paramToken)){
return "login";
}
String token = StringUtils.isEmpty(paramToken)?cookieToken: paramToken;
MiaoshaUser user = miaoshaUserService.getByToken(response, token);
model.addAttribute("user", user);
// model.addAttribute("token",token);
        return "goods_list";
}

这将是一件非常麻烦的事情。我们希望在每个页面中可以把user对象注入进来,而不需要在每个页面都写同样的查找user的代码。这里可以做一些处理。

5、新建类 WebConfig,其继承WebMvcConfigurerAdapter

@Configuration   //这里一定要加上这个注解,可以加载配置信息
public class WebConfig extends WebMvcConfigurerAdapter{
@Autowired
UserArgumentResolver userArgumentResolver;
/*
* 把resolver注册进来
* */
@Override
public void addArgumentResolvers(List<HandlerMethodArgumentResolver> argumentResolvers) {
argumentResolvers.add(userArgumentResolver);
}
}

然后新建类UserArgumentResolver

@Service
public class UserArgumentResolver implements HandlerMethodArgumentResolver{

@Autowired
MiaoshaUserService miaoshaUserService;
public boolean supportsParameter(MethodParameter parameter) {
Class<?> clazz = parameter.getParameterType(); 
System.out.println("---------------------");
System.out.println(clazz);
return clazz == MiaoshaUser.class;
}
public Object resolveArgument(MethodParameter parameter, ModelAndViewContainer mavContainer,
NativeWebRequest webRequest, WebDataBinderFactory binderFactory) throws Exception {
HttpServletRequest request = webRequest.getNativeRequest(HttpServletRequest.class);
HttpServletResponse response= webRequest.getNativeResponse(HttpServletResponse.class);
String paramToken = request.getParameter(MiaoshaUserService.COOKIE1_NAME_TOKEN);
String cookieToken = getCookieValue(request, MiaoshaUserService.COOKIE1_NAME_TOKEN);
if(StringUtils.isEmpty(paramToken) && StringUtils.isEmpty(cookieToken)){
return null;
}
System.out.println(paramToken);
System.out.println("---------------------");
System.out.println(cookieToken);
String token = StringUtils.isEmpty(paramToken)?cookieToken:paramToken;
MiaoshaUser user = miaoshaUserService.getByToken(response, token);//给你一个响应你才能在下一个页面查看
return user;
}
private String getCookieValue(HttpServletRequest request, String cookieName) {
Cookie[] cookies = request.getCookies();
for(Cookie cookie : cookies){
if(cookie.getName().equals(cookieName)){
return cookie.getValue();
}
}
return null;
}
}


猜你喜欢

转载自blog.csdn.net/jiuweideqixu/article/details/80428871
2-4