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;
    }
}

  

原文地址:https://www.cnblogs.com/SkyeAngel/p/9226353.html