应用场景举例:

当不同身份的用户请求一个接口时,用来校验用户某些身份,这样可以对单个字段数据进行精确权限控制,具体看代码注释

自定义注解

/**
* 对比请求的用户身份是否符合
* @author liuyalong
* @date 2020/9/25 16:03
*/
@Target(ElementType.PARAMETER)
@Retention(RetentionPolicy.RUNTIME)
public @interface CompareUser {
/**
* The name of the request parameter to bind .
*/
@AliasFor("name") String value() default "";
@AliasFor("value") String name() default "";
}

给controller的字段添加注解

    @ApiOperation(value = "删除用户", notes = "根据手机号来删除用户")
@PostMapping(value = "/delete_phone")
public BaseCommonResult<Integer> deletePhone(@CompareUser(value = "phone") String phone) {
int i = userService.deleteByPhone(phone);
return BaseCommonResult.success(i);
}

参数解析器

记得继承后加@Component,这里是Base...所以不用

/**
* @author liuyalong
* @date 2020/9/25 15:56
*/
public class BaseCurrentUserInterceptor implements HandlerMethodArgumentResolver {
/**
* 用于判定是否需要处理该参数注解,返回true为需要,
* 并会去调用下面的方法resolveArgument。
*/
@Override
public boolean supportsParameter(MethodParameter parameter) {
//只处理CurrentUser注解修饰的参数
return parameter.hasParameterAnnotation(CompareUser.class);
} /**
* 对比用户信息
*/
@Override
public Object resolveArgument(MethodParameter parameter, ModelAndViewContainer mavContainer, NativeWebRequest webRequest, WebDataBinderFactory binderFactory) throws Exception {
CompareUser parameterAnnotation = parameter.getParameterAnnotation(CompareUser.class); Class<?> parameterType = parameter.getParameterType();
if (parameterAnnotation == null) {
throw new IllegalArgumentException("Unknown parameter type [" + parameterType.getName() + "]");
} /*
* 获取要验证的字段名
*/ //检查是否给字段取了别名
String paramName = "".equalsIgnoreCase(parameterAnnotation.name()) ? parameterAnnotation.value() : parameterAnnotation.name();
if ("".equalsIgnoreCase(parameterAnnotation.name())) {
//从参数中获取定义的字段名
paramName = parameter.getParameter().getName();
} //获取请求字段的值
String paramValue = String.valueOf(webRequest.getParameter(paramName)); //从请求头中获取已经登录的用户
String userName = webRequest.getHeader(AuthConstant.USER_TOKEN_HEADER); //对于root用户,可以操作一切,所以直接返回
if (!AuthConstant.ROOT_USER.equals(userName)) {
//判断身份是否一致,不一致就抛出异常,让RestControllerAdvice处理
if (userName == null || !userName.equals(paramValue)) {
throw new NotSameAuthorException();
}
}
//将参数原封不动返回出去,需要还原回需要的类型
WebDataBinder binder = binderFactory.createBinder(webRequest, parameterType, paramName);
return binder.convertIfNecessary(paramValue, parameterType, parameter);
}
}

配置WebMvcConfigurer

注意这里提供了两种方式加载,因为

@Configuration
public class WebMvcConfig implements WebMvcConfigurer {
@Autowired
private HandlerInterceptor handlerInterceptor; @Autowired
private HandlerMethodArgumentResolver currentUserInterceptor; @Autowired
private RequestMappingHandlerAdapter requestMappingHandlerAdapter; @Override
public void addInterceptors(InterceptorRegistry registry) {
registry.addInterceptor(handlerInterceptor).addPathPatterns("/**");
} //参数解析器,自定义的优先级最低,所以会失效,
// 解决方案是下面的 @PostConstruct ,把优先级调最高
// 但是这样@PathParam @RequestParam就失效了,@CompareUser(value="xxx")可以完全替换@RequestParam功能
// @Override
// public void addArgumentResolvers(List<HandlerMethodArgumentResolver> resolvers) {
// resolvers.add(currentUserInterceptor);
//
// } /**
*参数解析器优先级调最高
*/
@PostConstruct
public void init() {
// 获取当前 RequestMappingHandlerAdapter 所有的 Resolver 对象
List<HandlerMethodArgumentResolver> resolvers = requestMappingHandlerAdapter.getArgumentResolvers();
List<HandlerMethodArgumentResolver> newResolvers = new ArrayList<>(resolvers.size() + 1); // 添加自定义参数解析器到集合首位
newResolvers.add(currentUserInterceptor); // 添加 已注册的 Resolver 对象集合
newResolvers.addAll(resolvers);
// 重新设置 Resolver 对象集合
requestMappingHandlerAdapter.setArgumentResolvers(newResolvers);
}
}

效果

只有特定身份人员才可以删除操作

SpringBoot 拦截器和自定义注解判断请求是否合法的更多相关文章

  1. struts2拦截器加自定义注解实现权限控制

    https://blog.csdn.net/paul342/article/details/51436565 今天结合Java的Annotation和Struts2进行注解拦截器权限控制. 功能需求: ...

  2. 拦截器和自定义注解@interface

    1 .拦截器(Interceptor): 用于在某个方法被访问之前进行拦截,然后在Handler执行之前或之后加入某些操作,其实就是AOP的一种实现策略. 拦截用户的请求并进行相应的处理,比如:判断用 ...

  3. [Java]利用拦截器和自定义注解做登录以及权限验证

    1.自定义注解 需要验证登录的注解 package com.etaofinance.wap.common; import java.lang.annotation.Documented; import ...

  4. Spring MVC基础知识整理➣拦截器和自定义注解

    概述 Spring MVC中通过注解来对方法或者类进行动态的说明或者标注,类似于配置标识文件的属性信息.当标注的类或者方式被使用时候,通过提取注解信息来达到对类的动态处理.在 MVC中,我们常用的注解 ...

  5. SpringMVC拦截器+Spring自定义注解实现权限验证

    特别提示:本人博客部分有参考网络其他博客,但均是本人亲手编写过并验证通过.如发现博客有错误,请及时提出以免误导其他人,谢谢!欢迎转载,但记得标明文章出处:http://www.cnblogs.com/ ...

  6. springboot + 拦截器 + 注解 实现自定义权限验证

    springboot + 拦截器 + 注解 实现自定义权限验证最近用到一种前端模板技术:jtwig,在权限控制上没有用springSecurity.因此用拦截器和注解结合实现了权限控制. 1.1 定义 ...

  7. 【SpringBoot】SpringBoot拦截器实战和 Servlet3.0自定义Filter、Listener

    =================6.SpringBoot拦截器实战和 Servlet3.0自定义Filter.Listener ============ 1.深入SpringBoot2.x过滤器Fi ...

  8. SpringBoot 拦截器获取http请求参数

    SpringBoot 拦截器获取http请求参数-- 所有骚操作基础 目录 SpringBoot 拦截器获取http请求参数-- 所有骚操作基础 获取http请求参数是一种刚需 定义拦截器获取请求 为 ...

  9. springboot拦截器总结

    Springboot 拦截器总结 拦截器大体分为两类 : handlerInterceptor 和 methodInterceptor 而methodInterceptor 又有XML 配置方法 和A ...

随机推荐

  1. Tomcat Web服务器与常用Web服务器

    一.常用Web服务器 Tomcat ​ 由Apache组织提供的一种Web服务器,提供对jsp和servlet的支持.它是一种轻量级的javaWeb容器服务器.也是当前应用最广的JavaWeb服务器( ...

  2. Boost命令行解释器的简单使用:Boost.Program_options

    简介 如果使用比较多的命令行程序的话,对于命令行参数的输入肯定不会陌生,大部分的程序都是通过类似下面的形式进行输入的,比如熟悉的ls ls --all -l --color=auto 这里面包含了三种 ...

  3. 精尽 MyBatis 源码分析 - 整体架构

    该系列文档是本人在学习 Mybatis 的源码过程中总结下来的,可能对读者不太友好,请结合我的源码注释(Mybatis源码分析 GitHub 地址.Mybatis-Spring 源码分析 GitHub ...

  4. 花了三天整理,Spring Cloud微服务如何设计异常处理机制?还看不懂算我输

    前言 首先说一下为什么发这篇文章,是这样的.之前和粉丝聊天的时候有聊到在采用Spring Cloud进行微服务架构设计时,微服务之间调用时异常处理机制应该如何设计的问题.我们知道在进行微服务架构设计时 ...

  5. nginx学习http_auth_basic_module模块

    对2.html页面做授权操作 先进行账号密码的生成  使用  htpasswd -c /etc/nginx/auth_conf  用户名 输入2次密码 (如果没有htpasswd,可以使用yum  - ...

  6. 关于Java里方法重载

    覆盖和重载很重要,并且比较容易混淆,所以面试中常见.基础回答:覆盖(Override),又叫重写,是指子类对父类方法的一种重写,方法名.参数列表必须相同,返回值小于父类,只能比父类抛出更少的异常,访问 ...

  7. CF453C Little Pony and Summer Sun Celebration

    如果一个点需要经过奇数次我们就称其为奇点,偶数次称其为偶点. 考虑不合法的情况,有任意两个奇点不连通(自己想想为什么). 那么需要处理的部分就是包含奇点的唯一一个连通块.先随意撸出一棵生成树,然后正常 ...

  8. Java蓝桥杯练习——杨辉三角形

    问题描述: 杨辉三角形又称Pascal三角形,它的第i+1行是(a+b)i的展开式的系数. 它的一个重要性质是:三角形中的每个数字等于它两肩上的数字相加. 下面给出了杨辉三角形的前4行: 1 1 1 ...

  9. 5. Idea集成Git

    5.1 引入本地安装的Git 5.2 本地库的初始化操作 5.3 本地库的基本操作 add与commit 控制台查看commit记录 查看Log 5.4 远程库的基本操作 远程库第一次pull到本地库 ...

  10. kafka入门之broker--通信协议

    kafka的通讯协议是基于tcp之上的二进制协议,所有类型的请求和响应都是结构化的,由不同的初始类型构成.kafka使用这组协议完成各个功能的实现. 单个kafka client通常需要同时连接多个b ...