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对象 List resolvers=requestMappingHandlerAdapter.getArgumentResolvers(); List newResolvers=newArrayList<>(resolvers.size()+1); //添加自定义参数解析器到集合首位 newResolvers.add(currentUserInterceptor); //添加已注册的Resolver对象集合 newResolvers.addAll(resolvers); //重新设置Resolver对象集合 requestMappingHandlerAdapter.setArgumentResolvers(newResolvers); } }
效果
只有特定身份人员才可以删除操作
以上就是SpringBoot拦截器和自定义注解判断请求是否合法的详细内容,更多关于SpringBoot拦截器和自定义注解的资料请关注毛票票其它相关文章!