10月12 HandlerMethodArgumentResolver的使用 | 简单生成token

一、基本实现

1.1 实现接口

import org.apache.commons.lang3.StringUtils;
import org.springframework.core.MethodParameter;
import org.springframework.web.bind.support.WebDataBinderFactory;
import org.springframework.web.context.request.NativeWebRequest;
import org.springframework.web.method.support.HandlerMethodArgumentResolver;
import org.springframework.web.method.support.ModelAndViewContainer;

import com.longge.utils.Constant;
import com.longge.utils.RedisCacheUtils;

/**
 * 获取用户的session dto
 */
public class LoginUserInfoMethodArgumentResolver implements HandlerMethodArgumentResolver {

    @Override
    public Object resolveArgument(MethodParameter arg0, ModelAndViewContainer arg1, NativeWebRequest arg2,
            WebDataBinderFactory arg3) throws Exception {
        String token = arg2.getHeader(Constant.TOKEN_KEY);
        if(StringUtils.isNotBlank(token)) {
            return RedisCacheUtils.getUserInfo(token);
        }
        return null;
    }

    @Override
    public boolean supportsParameter(MethodParameter arg0) {
        return arg0.getParameterType().equals(UserInfo.class);
    }

}

 

1.2 注册

@SpringBootApplication
public class MyBootApplication extends WebMvcConfigurerAdapter{
    public static void main(String[] args) {
        SpringApplication.run(MyBootApplication.class, args);
    }
    
    @Override
    public void addArgumentResolvers(List<HandlerMethodArgumentResolver> argumentResolvers) {
        super.addArgumentResolvers(argumentResolvers);
        argumentResolvers.add(new LoginUserInfoMethodArgumentResolver());
    }
}

这里是启动类继承WebMvcConfigurerAdapter

另外写一个@Configuration注解的来继承WebMvcConfigurerAdapter(推荐)

 

1.3 使用

@ApiOperation("新增")
@PutMapping("add")
public ResponseResult<SupplierDto> add(UserInfo userInfo, @Valid @RequestBody SupplierDto supplierDto) {
    // 这里的UserInfo不需要加任何注解,因为LoginUserInfoMethodArgumentResolver是对class的类型来解析的
}

 

二、和拦截器使用获取用户信息

2.1 

 

/**
 * 登录用户信息

 */
@Target(ElementType.PARAMETER)
@Retention(RetentionPolicy.RUNTIME)
public @interface LoginUser {

}

 

 

2.2 拦截器

@Component
public class AuthorizationInterceptor extends HandlerInterceptorAdapter {
    @Autowired
    private TokenService tokenService;

    public static final String LOGIN_USER_KEY = "LOGIN_USER_KEY";


    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {

        //从header中获取token
        String token = request.getHeader(LOGIN_TOKEN_KEY);
        //如果header中不存在token,则从参数中获取token
        if (StringUtils.isBlank(token)) {
            token = request.getParameter(LOGIN_TOKEN_KEY);
        }//设置userId到request里,后续根据userId,获取用户信息
        request.setAttribute(LOGIN_USER_KEY, tokenEntity.getUserId());

        return true;
    }
}

把用户id 设置到attribute里面

 

LoginUserHandlerMethodArgumentResolver

import com.platform.annotation.LoginUser;
import com.platform.entity.UserVo;
import com.platform.interceptor.AuthorizationInterceptor;
import com.platform.service.ApiUserService;
import org.springframework.core.MethodParameter;
import org.springframework.web.bind.support.WebDataBinderFactory;
import org.springframework.web.context.request.NativeWebRequest;
import org.springframework.web.context.request.RequestAttributes;
import org.springframework.web.method.support.HandlerMethodArgumentResolver;
import org.springframework.web.method.support.ModelAndViewContainer;

/**
 * 有@LoginUser注解的方法参数,注入当前登录用户
 */
public class LoginUserHandlerMethodArgumentResolver implements HandlerMethodArgumentResolver {
    private ApiUserService userService;

    public void setUserService(ApiUserService userService) {
        this.userService = userService;
    }

    @Override
    public boolean supportsParameter(MethodParameter parameter) {
        return parameter.getParameterType().isAssignableFrom(UserVo.class) && parameter.hasParameterAnnotation(LoginUser.class);
    }

    @Override
    public Object resolveArgument(MethodParameter parameter, ModelAndViewContainer container,
                                  NativeWebRequest request, WebDataBinderFactory factory) throws Exception {
        //获取用户ID
        Object object = request.getAttribute(AuthorizationInterceptor.LOGIN_USER_KEY, RequestAttributes.SCOPE_REQUEST);
        if (object == null) {
            return null;
        }

        //获取用户信息
        UserVo user = userService.queryObject((Long) object);

        return user;
    }
}

在supportsParameter方法中判断请求参数是否被HandlerMethodArgumentResolver所支持

这里有两个条件1个是 LoginUser 注解一个是 UserVo

然后才会执行 resolveArgument 方法

从attribute里得到userid 然后得到用户信息

 

2.3 使用

 

@ApiOperation(value = "添加商品到购物车")
    @PostMapping("add")
    public Object add(@LoginUser UserVo loginUser) {
}

 

参考

https://blog.csdn.net/a18716374124/article/details/79208990

https://www.cnblogs.com/yangzhilong/p/7605889.html

 

 

二、生成token

token三要素

userid 、过期时间 、token字符串

 

 //12小时后过期
    private final static int EXPIRE = 3600 * 12;


    public Map<String, Object> createToken(long userId) {
        //生成一个token
        String token = CharUtil.getRandomString(32);
        //当前时间
        Date now = new Date();

        //过期时间
        Date expireTime = new Date(now.getTime() + EXPIRE * 1000);

        //判断是否生成过token
        TokenEntity tokenEntity = queryByUserId(userId);
        if (tokenEntity == null) {
            tokenEntity = new TokenEntity();
            tokenEntity.setUserId(userId);
            tokenEntity.setToken(token);
            tokenEntity.setUpdateTime(now);
            tokenEntity.setExpireTime(expireTime);

            //保存token
            save(tokenEntity);
        } else {
            tokenEntity.setToken(token);
            tokenEntity.setUpdateTime(now);
            tokenEntity.setExpireTime(expireTime);

            //更新token
            update(tokenEntity);
        }

        Map<String, Object> map = new HashMap<>();
        map.put("token", token);
        map.put("expire", EXPIRE);

        return map;
    }

 

posted @ 2018-10-12 15:39  lyon♪♫  阅读(367)  评论(0编辑  收藏  举报