注解实现接口拦截功能

方式一

我们在Spring boot项目中时候,一般会采用token作为身份验证,这样也方便前端做免登录功能

  1. 一般方式:我们会自定义一个拦截器,继承WebMvcConfigurer类,重写addInterceptors方法,效果如下:
@Configuration
public class InterceptorConfig implements WebMvcConfigurer {@Overridepublic void addInterceptors(InterceptorRegistry registry) {// 不需要拦截校验的urlString[] clientUserApiArrays = {Constants.CLIENT_URI_V1 + "/users/token",Constants.CLIENT_URI_V1 + "/users/we_chat_login"};registry.addInterceptor(clientUserApiInterceptor).addPathPatterns("/api/v*/client/**").excludePathPatterns(clientUserApiArrays);}
}

将不用token验证的接口地址过滤掉,这样也是很不错的做法

Github地址

  1. 第二种方式

采用注解的方式

  1. 先看下在代码中的应用,看看是不是你要的效果,不需要验证默认是不用加的
@ApiOperation(value = "获取推荐商户列表", notes = "获取推荐商户列表")@GetMapping("/getMerchantList")@UserTokenpublic BaseResult<List<MerchantVO>> getMerchantList() {return BaseResult.success(iMerchantService.getMerchantList());}
  1. 先定义两个注解用来区分需要token验证和不需要token验证
PassToken注解(对方法使用)
@Target({ElementType.METHOD, ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
public @interface PassToken {boolean required() default true;
}
UserToken注解(对方法使用)
@Target({ElementType.METHOD, ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
public @interface UserToken {boolean required() default true;}
  1. 我们对刚才继承WebMvcConfigurer类改造一下
@Configuration
public class UserApiInterceptorConfig implements WebMvcConfigurer {@Overridepublic void addInterceptors(InterceptorRegistry registry) {registry.addInterceptor(authenticationInterceptor()).addPathPatterns(Constants.APP_URI_V1 + "/**");// 对所有的接口进行拦截,判断是否包含有上面的验证注解}// UserApiInterceptor拦截器@Beanpublic UserApiInterceptor authenticationInterceptor() {return new UserApiInterceptor();}@Overridepublic void addArgumentResolvers(List<HandlerMethodArgumentResolver> resolvers) {// 注册@CurrentUser注解的实现类resolvers.add(new CurrentUserHandlerMethodArgResolver());}
}

UserApiInterceptor类(用于拦截区分带UserToken的注解或者PassToken的注解)

@Slf4j
@Component
public class UserApiInterceptor implements HandlerInterceptor {@AutowiredIUserService iUserService;@Overridepublic boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object object) throws Exception {log.info("请求地址[{}], 请求参数[{}]", request.getRequestURI(), JSONObject.toJSON(request.getParameterMap()));String token = request.getHeader(JwtTokenUtil.HEADER_STRING);// 如果不是映射到方法直接通过if (!(object instanceof HandlerMethod)) {return true;}HandlerMethod handlerMethod = (HandlerMethod) object;Method method = handlerMethod.getMethod();// 检查是否有passToken注释,有则跳过认证if (method.isAnnotationPresent(PassToken.class)) {PassToken passToken = method.getAnnotation(PassToken.class);if (passToken.required()) {return true;}}// 检查有没有需要用户权限的注解if (method.isAnnotationPresent(UserToken.class)) {UserToken userToken = method.getAnnotation(UserToken.class);if (userToken.required()) {// 执行认证if (StringUtils.isEmpty(token)) {throw new TokenValidException(300, "token校验失败!未获取到token");}Boolean valid = JwtTokenUtil.validateJWTToken(token);if (!valid) {throw new TokenValidException(300, "token校验失败!请检查");}User user = iUserService.getById(JwtTokenUtil.getJwtUserId(request));if (user == null) {throw new BusinessException(300, "用户信息为空");}UserInfoVO userInfoVO = new UserInfoVO();BeanUtils.copyProperties(user, userInfoVO);//我们将解析的用户结果先放入session中request.getSession().setAttribute("currentUser",userInfoVO);}}return true;}}

CurrentUserHandlerMethodArgResolver类(用于获取CurrentUser注解对象的值,后面会介绍)

@Slf4j
@Component
public class CurrentUserHandlerMethodArgResolver implements HandlerMethodArgumentResolver {/*** 判断是否支持使用@CurrentUser注解的参数*/@Overridepublic boolean supportsParameter(MethodParameter methodParameter) {// 如果该参数注解有@CurrentUser且参数类型是Userreturn methodParameter.getParameterAnnotation(CurrentUser.class) != null && methodParameter.getParameterType() == UserInfoVO.class;}/*** 注入参数值*/@Overridepublic Object resolveArgument(MethodParameter methodParameter, ModelAndViewContainer modelAndViewContainer, NativeWebRequest nativeWebRequest, WebDataBinderFactory webDataBinderFactory) throws Exception {// 取得HttpServletRequestHttpServletRequest request = (HttpServletRequest) nativeWebRequest.getNativeRequest();// 取出session中的UserUserInfoVO userInfoVO = (UserInfoVO) request.getSession().getAttribute("currentUser");log.info("currentUser id:{}", userInfoVO.getId());return userInfoVO;}}
  1. 这时候便可以使用这个上面PassToken和UserToken注解了(有些代码工具缺失,最后有源码包可供参考)

    @ApiOperation(value = "获取推荐商户列表", notes = "获取推荐商户列表")@GetMapping("/getMerchantList")@UserTokenpublic BaseResult<List<MerchantVO>> getMerchantList() {return BaseResult.success(iMerchantService.getMerchantList());}
    
  2. 我们来看下CurrentUser的注解的用途

    项目中我们一般通过token验证来验证某个用户是否是登录状态,我们只验证登录状态,不去获取这个用户的信息吗,一般情况下,我们也可以通过Request这种方式,将token(id)传入每个方法中,然后用该token获取获取id,在通过id获取一些信息,这样也是可以的,这边我们tokenCurrentUser注解,直接将用户信息拿到,供后面开发使用,即加即用,先看效果:

@ApiOperation(value = "获取轮播图列表", notes = "获取轮播图列表接口")@GetMapping("/getBannerList")@UserTokenpublic BaseResult<List<BannerVO>> getBannerList(@CurrentUser UserInfoVO userInfoVO) {// 测试CurrentUser注解log.info("UserInfoVo" + userInfoVO.toString());return BaseResult.success(iBannerService.getBannerList());}

打印结果:

2020-12-29 16:41:13.788  INFO 12632 --- [nio-8081-exec-3] com.llayjun.millet.api.BannerController  : UserInfoVoUserInfoVO{id='1319550471008100353', name='1', sex=0, mobile='1', passWord='1'}

CurrentUser注解类(对对象使用)

@Target({ElementType.PARAMETER}) // Annotation所修饰的对象范围:方法参数
@Retention(RetentionPolicy.RUNTIME) // Annotation被保留时间:运行时保留(有效)
@Documented
public @interface CurrentUser {}
  1. 源代码

Github地址

注解实现接口拦截功能相关推荐

  1. Springmvc借助SimpleUrlHandlerMapping实现接口开关功能

    一.接口开关功能 1.可配置化,依赖配置中心 2.接口访问权限可控 3.springmvc不会扫描到,即不会直接的将接口暴露出去 二.接口开关使用场景 和业务没什么关系,主要方便查询系统中的一些状态信 ...

  2. 用 Java 实现拦截器 Interceptor 的拦截功能

    Java 里的拦截器是动态拦截 action 调用的对象,它提供了一种机制可以使开发者可以定义在一个 action 执行的前后执行的代码,也可以在一个 action 执行前阻止其执行,同时也提供了一种 ...

  3. Android手机安全软件之电话拦截功能浅析

    目前中国市场,骚扰电话大量的充斥手机用户的生活,因此手机安全软件的电话拦截功能受到广泛关注和使用.但第三方应用级电话拦截功能的效果并不理想,比如拦截电话时已经响了一声.或出现短暂的来电界面,多款安全软 ...

  4. 学生信息管理系统----登录拦截功能

    过滤器的相关概念 Filter是什么   Filter 是java下的一种过滤器 ,能实现对java web程序 客户端和服务器端消息的过滤,也就是在服务器段接受request之前,可以预先对requ ...

  5. WiFi万能钥匙发布iOS4.0新增骚扰电话拦截功能

    近日,连尚网络旗下产品WiFi万能钥匙发布了iOS4.0最新版本.根据用户的需求反馈,WiFi万能钥匙iOS4.0新增了骚扰电话拦截等多个功能.版本更新后,WiFi万能钥匙在连接成功率和使用流畅程度上 ...

  6. Scala特质trait具备Java中类和接口的功能

    特质trait具备Java中类和接口的功能

  7. java 拦截指定jsp_详解Struts2中对未登录jsp页面实现拦截功能

    struts2中拦截器大家都很经常使用,但是拦截器只能拦截action不能拦截jsp页面.这个时候就有点尴尬了,按道理来说没登录的用户只能看login界面不能够通过输入url进行界面跳转,这显然是不合 ...

  8. JAVA8给我带了什么——并流行和接口新功能

    JAVA8给我带了什么--并流行和接口新功能 流,确定是笔者内心很向往的天堂,有他之后JAVA在处理数据就变更加的灵动.加上lambda表达不喜欢都不行.JAVA8也为流在提供另一个功能--并行流.即 ...

  9. 接口测试-接口定义功能-前端-实现动态增删表单

    基于 springboot+vue 的测试平台开发继续更新. 目前已经进入到接口定义功能的开发阶段,首先我还是直接在前段画了个大概的页面,先预览下: 不过目前只是画了这个页面都主要功能,细节未尽事宜待 ...

  10. C#实现调取钉钉考勤接口的功能

    C#实现调取钉钉考勤接口的功能 公司需要做一个钉钉考勤的页面,让我去写这个功能.结果却比我想象的要麻烦一些!具体是怎么个麻烦呢,下面直入正题. 首先我们找到获取钉钉考勤结果的接口.结果发现请求参数里有 ...

最新文章

  1. springBoot 在线心理咨询管理系统
  2. python流程控制语句-【Python学习之三】流程控制语句
  3. stm32串口学习(一)
  4. reactjs css modules解决组件间样式覆盖问题
  5. 《机器学习实战》朴素贝叶斯
  6. 离散数学反对称关系_【离散数学】1.2&1.3集合与元素,集合与集合之间的关系...
  7. [问题解决]基于注解配置dubbo遇到ConnectionLoss for /dubbo/xxx问题解决
  8. 【知云】第十二期:处于风口浪尖上的直播视频网站,如何快速部署直播监管?...
  9. 设为首页、加入收藏 兼容代码
  10. nioqrc oracle,程序停在 readnocancel () from -lib-tls-libpthread.so.0
  11. vue 组件不受全局样式影响_组件库引入全局样式lib/style/index.css,会污染全局基础样式...
  12. c# msi中加入驱动_MSI微星:给你的CPU装上热交换气缸活塞,不用电也能驱动风扇降温...
  13. http://blog.csdn.net/x86android/article/details/16980967
  14. SimpleGIS在线地图插件
  15. php代码,IP地址归属地批量查询功能
  16. 安捷伦or是德信号源+频谱仪操作: 从程控到自动测试 (五)频谱仪截屏到U盘的程控实现
  17. python正则表达式和数据库
  18. 使用PHP求解二元一次方程,二元一次方程求解
  19. 小程序京东首页底部导航栏代码
  20. c语言程序的上标怎么打出来,c上标2下标5怎么算

热门文章

  1. zebra 的Thread机制 -- 003
  2. IOMMU 虚拟IO地址和物理地址相关联
  3. Ubuntu下使用VI编辑文件必知的常用命令
  4. SylixOS 内存管理源代码分析--phyPage.c
  5. 实况足球2020修改服务器,实况足球2020指令一览,最近的指令更改你知道吗
  6. tensorflow手动实现算法之三逻辑回归
  7. scala 入门初探
  8. ajax中res和req,表达式是否为每个请求提供了不同的req和res对象?
  9. 2020电信最新套餐一览表_最新!2020年宁波中学排名一览表
  10. windows平台上编写的python无法在unix_在Windows平台上编写的Python程序无法在Unix平台运行?...