zoukankan      html  css  js  c++  java
  • 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;
        }
    }
    

      

  • 相关阅读:
    pku2992 Divisors
    pku3090 Visible Lattice Points
    pku3615 Cow Hurdles
    禁止 verifier.dll 监控程序
    运行ogreSDK的samples
    #pragma pack(n) 啥时候可以不再忘记?
    游戏开发流程图。
    希望可以尽快的写篇自己的成果。
    windows与OS X下的std::string
    VS2008鼠标右键不灵敏,TFS的Local Path无法打开对应文件夹
  • 原文地址:https://www.cnblogs.com/SkyeAngel/p/9226353.html
Copyright © 2011-2022 走看看