SSM和SpringBoot--分布式session
生成cookie
生成随机token,
使用UUID
public class UUIDUtil { public static String uuid(){ return String.valueOf(UUID.randomUUID()).replace("-", ""); } }
然后将token写到session,传递给客户端。
前提是将用户信息写入redis
用户登录时,将用户信息写入redis,key=user_ 加一个随机的token
然后,将这个token保存到cookie中,之后从cookie中获取。
@Override public LocalUser getLocalUserByUserNameAndPwd(HttpServletResponse response, String username, String password) { LocalUser localuser = localUserDao.queryLocalUserByUserNameAndPWd( username, MD5.getMd5(password) ); addCookie(response, localuser); return localuser; }
addCookie,将用户信息存入redis,同时将作为键的token存入redis中
private void addCookie(HttpServletResponse response, LocalUser localuser){ //生成cookie String token = UUIDUtil.uuid(); redisUtil.set(UserKey.userKey, token, localuser); Cookie cookie = new Cookie(COOKI_NAME_TOKEN, token); cookie.setMaxAge(UserKey.userKey.getExpireSeconds()); //将cookie放到网站的根目录 cookie.setPath("/"); //加入cookie到客户端 response.addCookie(cookie); }
当从redis中获取用户信息时,使用getByToken
@Override public Object getByToken(HttpServletResponse response, String token) { if(token == null || token.length() <= 0){ return null; } Object obj = redisUtil.get(UserKey.userKey, token); if(obj instanceof LocalUser){ LocalUser user = (LocalUser)obj; //重新设置过期时间 addCookie(response, user); return user; } return null; }
RedisUtil工具类 Spring配置redis(自定义方法)
中的读取和写入缓存
/** * 读取缓存 * * @param key * @return */ public Object get(KeyPrefix prefix, String key) { Object result = null; String realKey = prefix.getPrefix() + key; ValueOperations<Serializable, Object> operations = redisTemplate .opsForValue(); result = operations.get(realKey); return result; } /** * 写入缓存 * * @param key * @param value * @return */ public boolean set(KeyPrefix prefix, String key, Object value) { boolean result = false; try { String realKey = prefix.getPrefix() + key; ValueOperations<Serializable, Object> operations = redisTemplate .opsForValue(); operations.set(realKey, value); result = true; } catch (Exception e) { e.printStackTrace(); } return result; }
生成key的工具类
KeyPrefix接口
public interface KeyPrefix { int getExpireSeconds(); String getPrefix(); }
BasePrefix类
public class BasePrefix implements KeyPrefix { //0代表永不过期 private int expireSeconds; private String prefix; public BasePrefix(String prefix) { this(0, prefix); } public BasePrefix(int expireSeconds, String prefix) { this.expireSeconds = expireSeconds; this.prefix = prefix; } public int getExpireSeconds() { return expireSeconds; } public String getPrefix() { return prefix; } }
UserKey
public class UserKey extends BasePrefix{ public static final int TOKEN_EXPIRE = 3600*24*2; public UserKey(int expireSeconds, String prefix) { super(expireSeconds, prefix); } public static UserKey userKey = new UserKey(TOKEN_EXPIRE, "user_"); }
后面从cookie中获取时,需要使用request从传入的cookie中获取
/** * 实现分页查询店铺,通过条件组合,来筛选出条件范围内的店铺列表 * @param cookieToken * @param paramToken * @return */ @RequestMapping(value="/getshoplist", method=RequestMethod.GET) @ResponseBody public Map<String, Object> getShopList(HttpServletResponse response, @CookieValue(value = LocalUserServiceImpl.COOKI_NAME_TOKEN, required = false) String cookieToken, @RequestParam(value = LocalUserServiceImpl.COOKI_NAME_TOKEN, required = false) String paramToken){ Map<String, Object> modelMap = new HashMap<>(); if((cookieToken == null && cookieToken.length() <= 0) && (paramToken == null && paramToken.length() <= 0)){ modelMap.put( "success", false ); modelMap.put( "errMsg", "用户未登录" ); } String token = (paramToken != null && paramToken.length() > 0) ? paramToken : cookieToken; LocalUser user = (LocalUser)localUserService.getByToken(response, token); ShopExecution shopExecution = null; try{ Shop shopCondition = new Shop(); shopCondition.setOwner( user.getPersonInfo() ); shopExecution = shopService.getShopList( shopCondition, 1, 100 ); modelMap.put( "shopList", shopExecution.getShopList() ); modelMap.put( "user", user); modelMap.put( "success", true ); } catch(Exception e){ modelMap.put( "success", false ); modelMap.put( "errMsg", e.toString() ); } return modelMap; }
上面是SSM实现cookie的方法
化简:因为搞不定在SSM中用配置xml形式是怎么进行解析的,所以剩下的待定。
<mvc:annotation-driven> <mvc:argument-resolvers> <bean class="com.shop.config.UserArgumentResolver"/> </mvc:argument-resolvers> </mvc:annotation-driven>
在SpringBoot中下面利用 WebMvcConfigurerAdapter 做参数解析器,通过解析其中的参数,来将其中的request和response参数去掉,直接转换成LocalUser实体类,传递到Controller层
@Configuration @EnableWebMvc @ComponentScan public class WebConfig extends WebMvcConfigurerAdapter { @Autowired UserArgumentResolver userArgumentResolver; public void addArgumentResolvers(List<HandlerMethodArgumentResolver> argumentResolvers) { argumentResolvers.add(userArgumentResolver); } }
@Service public class UserArgumentResolver implements HandlerMethodArgumentResolver { @Autowired LocalUserService localUserService; @Override public boolean supportsParameter(MethodParameter methodParameter) { Class<?> clazz = methodParameter.getContainingClass(); return clazz == LocalUser.class; } @Override public Object resolveArgument(MethodParameter methodParameter, ModelAndViewContainer modelAndViewContainer, NativeWebRequest nativeWebRequest, WebDataBinderFactory webDataBinderFactory) throws Exception { HttpServletRequest request = nativeWebRequest.getNativeRequest(HttpServletRequest.class); HttpServletResponse response = nativeWebRequest.getNativeResponse(HttpServletResponse.class); String paramToken = request.getParameter(LocalUserServiceImpl.COOKI_NAME_TOKEN); System.out.println(paramToken + "-----------------"); String cookieToken = getCookieValue(request, LocalUserServiceImpl.COOKI_NAME_TOKEN); System.out.println("-----------------" + cookieToken); if(paramToken == null && paramToken.length() <= 0 && cookieToken == null && cookieToken.length() <= 0){ return null; } String token = (paramToken != null && paramToken.length() > 0) ? paramToken : cookieToken; return localUserService.getByToken(response, token); } private String getCookieValue(HttpServletRequest request, String cookiNameToken) { Cookie[] cookies = request.getCookies(); for(Cookie c : cookies){ if(c.getName().equals(cookiNameToken)){ return c.getValue(); } } return null; } }