SpringBoot 拦截器和自定义注解判断请求是否合法
应用场景举例:
当不同身份的用户请求一个接口时,用来校验用户某些身份,这样可以对单个字段数据进行精确权限控制,具体看代码注释
自定义注解
/**
*对比请求的用户身份是否符合
*@authorliuyalong
*@date2020/9/2516:03
*/
@Target(ElementType.PARAMETER)
@Retention(RetentionPolicy.RUNTIME)
public@interfaceCompareUser{
/**
*Thenameoftherequestparametertobind.
*/
@AliasFor("name")Stringvalue()default"";
@AliasFor("value")Stringname()default"";
}
给controller的字段添加注解
@ApiOperation(value="删除用户",notes="根据手机号来删除用户") @PostMapping(value="/delete_phone") publicBaseCommonResultdeletePhone(@CompareUser(value="phone")Stringphone){ inti=userService.deleteByPhone(phone); returnBaseCommonResult.success(i); }
参数解析器
记得继承后加@Component,这里是Base...所以不用
/**
*@authorliuyalong
*@date2020/9/2515:56
*/
publicclassBaseCurrentUserInterceptorimplementsHandlerMethodArgumentResolver{
/**
*用于判定是否需要处理该参数注解,返回true为需要,
*并会去调用下面的方法resolveArgument。
*/
@Override
publicbooleansupportsParameter(MethodParameterparameter){
//只处理CurrentUser注解修饰的参数
returnparameter.hasParameterAnnotation(CompareUser.class);
}
/**
*对比用户信息
*/
@Override
publicObjectresolveArgument(MethodParameterparameter,ModelAndViewContainermavContainer,NativeWebRequestwebRequest,WebDataBinderFactorybinderFactory)throwsException{
CompareUserparameterAnnotation=parameter.getParameterAnnotation(CompareUser.class);
Class>parameterType=parameter.getParameterType();
if(parameterAnnotation==null){
thrownewIllegalArgumentException("Unknownparametertype["+parameterType.getName()+"]");
}
/*
*获取要验证的字段名
*/
//检查是否给字段取了别名
StringparamName="".equalsIgnoreCase(parameterAnnotation.name())?parameterAnnotation.value():parameterAnnotation.name();
if("".equalsIgnoreCase(parameterAnnotation.name())){
//从参数中获取定义的字段名
paramName=parameter.getParameter().getName();
}
//获取请求字段的值
StringparamValue=String.valueOf(webRequest.getParameter(paramName));
//从请求头中获取已经登录的用户
StringuserName=webRequest.getHeader(AuthConstant.USER_TOKEN_HEADER);
//对于root用户,可以操作一切,所以直接返回
if(!AuthConstant.ROOT_USER.equals(userName)){
//判断身份是否一致,不一致就抛出异常,让RestControllerAdvice处理
if(userName==null||!userName.equals(paramValue)){
thrownewNotSameAuthorException();
}
}
//将参数原封不动返回出去,需要还原回需要的类型
WebDataBinderbinder=binderFactory.createBinder(webRequest,parameterType,paramName);
returnbinder.convertIfNecessary(paramValue,parameterType,parameter);
}
}
配置WebMvcConfigurer
注意这里提供了两种方式加载,因为
@Configuration
publicclassWebMvcConfigimplementsWebMvcConfigurer{
@Autowired
privateHandlerInterceptorhandlerInterceptor;
@Autowired
privateHandlerMethodArgumentResolvercurrentUserInterceptor;
@Autowired
privateRequestMappingHandlerAdapterrequestMappingHandlerAdapter;
@Override
publicvoidaddInterceptors(InterceptorRegistryregistry){
registry.addInterceptor(handlerInterceptor).addPathPatterns("/**");
}
//参数解析器,自定义的优先级最低,所以会失效,
//解决方案是下面的@PostConstruct,把优先级调最高
//但是这样@PathParam@RequestParam就失效了,@CompareUser(value="xxx")可以完全替换@RequestParam功能
//@Override
//publicvoidaddArgumentResolvers(Listresolvers){
//resolvers.add(currentUserInterceptor);
//
//}
/**
*参数解析器优先级调最高
*/
@PostConstruct
publicvoidinit(){
//获取当前RequestMappingHandlerAdapter所有的Resolver对象
Listresolvers=requestMappingHandlerAdapter.getArgumentResolvers();
ListnewResolvers=newArrayList<>(resolvers.size()+1);
//添加自定义参数解析器到集合首位
newResolvers.add(currentUserInterceptor);
//添加已注册的Resolver对象集合
newResolvers.addAll(resolvers);
//重新设置Resolver对象集合
requestMappingHandlerAdapter.setArgumentResolvers(newResolvers);
}
}
效果
只有特定身份人员才可以删除操作
以上就是SpringBoot拦截器和自定义注解判断请求是否合法的详细内容,更多关于SpringBoot拦截器和自定义注解的资料请关注毛票票其它相关文章!