场景
每个接口在被调用时,很可能需要调用该接口的用户信息,每次再去数据库查询该数据信息,势必会造成代码的大量重复,且还容易出错。
应用:把该次调用者用户的信息当做参数传到对应的方法。
比如:根据token获得到用户信息,将用户信息传到对应请求的method。
实现自定义参数解析器步骤:1、自定义注解 2、自定义参数解析器 3、注册
自定义注解
@Target(ElementType.PARAMETER)
@Retention(RetentionPolicy.RUNTIME)
public @interface CurrentUser {
}
自定义参数解析器
public class CurrentUserMethodArgumentResolver implements HandlerMethodArgumentResolver {
@Override
public boolean supportsParameter(MethodParameter parameter) {
//如果参数类型是UserToken并且有CurrentUser注解则支持
if (parameter.getParameterType().isAssignableFrom(UserToken.class) &&
parameter.hasParameterAnnotation(CurrentUser.class)) {
return true;
}
return false;
}
@Nullable
@Override
public Object resolveArgument(@Nullable MethodParameter parameter, ModelAndViewContainer mavContainer, @Nullable NativeWebRequest webRequest, WebDataBinderFactory binderFactory) throws Exception {
MvcAuthenticationToken authenticationToken = (MvcAuthenticationToken) SecurityContextHolder.getContext().getAuthentication();
//details里面可能存放了当前登录用户的详细信息,也可以通过cast后拿到
LoginUserDetail loginUserDetail = (LoginUserDetail) authenticationToken.getPrincipal();
return loginUserDetail.getUserToken();
}
}
注册自定义参数解析器
@Configuration
public class WebConfig implements WebMvcConfigurer {
@Bean
CurrentUserMethodArgumentResolver currentUserMethodArgumentResolver(){
return new CurrentUserMethodArgumentResolver();
}
@Override
public void addArgumentResolvers(List<HandlerMethodArgumentResolver> resolvers) {
resolvers.add(currentUserMethodArgumentResolver());
}
}
Controller
@PutMapping(value = "/test",consumes = MediaType.APPLICATION_JSON_UTF8_VALUE)
@ApiOperation(value = "获取用户", httpMethod = "PUT", response = UserToken.class)
public ReturnObject<UserToken> approve(@ApiIgnore @CurrentUser UserToken userToken) {
return ResponseUtil.ok(userToken);
}