核心代码:

  

  1.  
  1. package com.tran.demo.aspect;
  2.  
  3. import java.lang.reflect.Method;
  4. import java.time.LocalDateTime;
  5.  
  6. import javax.servlet.http.HttpServletRequest;
  7.  
  8. import org.aspectj.lang.JoinPoint;
  9. import org.aspectj.lang.ProceedingJoinPoint;
  10. import org.aspectj.lang.annotation.After;
  11. import org.aspectj.lang.annotation.AfterReturning;
  12. import org.aspectj.lang.annotation.Around;
  13. import org.aspectj.lang.annotation.Aspect;
  14. import org.aspectj.lang.annotation.Before;
  15. import org.aspectj.lang.annotation.Pointcut;
  16. import org.aspectj.lang.reflect.CodeSignature;
  17. import org.aspectj.lang.reflect.MethodSignature;
  18. import org.slf4j.Logger;
  19. import org.slf4j.LoggerFactory;
  20. import org.springframework.stereotype.Component;
  21. import org.springframework.util.StringUtils;
  22. import org.springframework.web.context.request.RequestContextHolder;
  23. import org.springframework.web.context.request.ServletRequestAttributes;
  24.  
  25. import com.tran.demo.annotation.AuthAnnotation;
  26. import com.tran.demo.enums.ResultEnum;
  27. import com.tran.demo.exception.MyException;
  28. import com.tran.demo.model.User;
  29.  
  30. @Component
  31. @Aspect
  32. public class MyAspect {
  33.  
  34. private Logger log = LoggerFactory.getLogger(MyAspect.class);
  35.  
  36. /**
  37. * 定义切入点,切入点为com.tran.demo.controller下的所有函数
  38. *
  39. * // @Pointcut("@annotation(com.tran.demo.annotation.AuthAnnotation)") 对注解形式方法拦截
  40. */
  41. @Pointcut("execution(public * com.tran.demo.controller..*.*(..))")
  42. public void aspectLog(){}
  43.  
  44. /**
  45. *
  46. * 前置通知 ,就是到达controller之前
  47. * @param joinPoint
  48. */
  49. @Before("aspectLog()")
  50. public void doBefore(JoinPoint joinPoint){
  51. log.info("开始执行:{}",LocalDateTime.now());
  52. ServletRequestAttributes attributes = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes();
  53. HttpServletRequest request = attributes.getRequest();
  54.  
  55. log.info("method={}", request.getMethod());
  56. log.info("class={} and method name = {}",joinPoint.getSignature().getDeclaringTypeName(),joinPoint.getSignature().getName());
  57.  
  58. Object[] args = joinPoint.getArgs();
  59. String[] paramNames = ((CodeSignature)joinPoint.getSignature()).getParameterNames();
  60.  
  61. for (int i = 0; i < args.length; i++) {
  62. log.info("参数:{},值:{}",paramNames[i],args[i]);
  63. }
  64.  
  65. }
  66.  
  67. /**
  68. * HTTP请求结束时的日志
  69. */
  70. @After("aspectLog()")
  71. public void doAfter(){
  72.  
  73. log.info("结束执行:{}",LocalDateTime.now());
  74.  
  75. }
  76.  
  77. /**
  78. * 接口返回的具体内容
  79. * @param object
  80. */
  81. @AfterReturning(returning = "object",pointcut = "aspectLog()")
  82. public void doAfterReturn(Object object){
  83.  
  84. log.info("返回数据:{}", object);
  85. }
  86.  
  87. /**
  88. *
  89. * 进行业务处理,判断是否有权限
  90. *
  91. * @param proceedingJoinPoint
  92. * @return
  93. * @throws Throwable
  94. */
  95. @Around("aspectLog()")
  96. public Object doAroundAdvice(ProceedingJoinPoint proceedingJoinPoint) throws Throwable {
  97.  
  98. ServletRequestAttributes attributes = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes();
  99. HttpServletRequest request = attributes.getRequest();
  100. MethodSignature methodSignature = (MethodSignature) proceedingJoinPoint.getSignature();
  101.  
  102. Method method = methodSignature.getMethod();
  103. AuthAnnotation authAnnotation = method.getAnnotation(AuthAnnotation.class);
  104.  
  105. if (null == authAnnotation) {
  106. log.info("该方法不需要权限,表示没有vip权限即可访问");
  107. return proceedingJoinPoint.proceed();
  108. }
  109.  
  110. log.info("需要的权限:{}", authAnnotation.auth());
  111. String auth = request.getHeader("auth");
  112. log.info("请求头匹配权限:{}",auth);
  113. if (StringUtils.isEmpty(auth) || !auth.equals(authAnnotation.auth())) {
  114. log.info("该请求需要权限");
  115. throw new MyException(ResultEnum.PERMISSION_DENIED);
  116. }
  117.  
  118. return proceedingJoinPoint.proceed();
  119. }
  120. }
  1.  
  1.  

控制层(Controller):

  1. @RequestMapping("/user")
  2. @RestController
  3. public class UserController {
  4.  
  5. @Autowired
  6. private IUserService userService;
  7.  
  8. @GetMapping("/get/{userid}")
  9. @ResponseBody
  10. @AuthAnnotation(auth="vip")
  11. public List<User> hello(@PathVariable Integer userid) {
  12. Wrapper user = new EntityWrapper<User>();
  13. user.where("userid >= {0}", 10000).and("userid <= {0}", userid);
  14. return userService.selectList(user);
  15. }
  16. }

注解:

  1. @Target(ElementType.METHOD)
  2. @Retention(RetentionPolicy.RUNTIME)
  3. @Documented
  4. public @interface AuthAnnotation {
  5.  
  6. // 非vip不能访问 user
  7. String auth() default "vip";
  8.  
  9. }

全局异常处理:

  

  1.  
  1. @ControllerAdvice
  2. @ResponseBody
  3. public class MyAdvice {
  4.  
  5. private Logger log = LoggerFactory.getLogger(MyAdvice.class);
  6.  
  7. //声明要捕获的异常
  8. @ExceptionHandler(MyException.class)
  9. public Object defultExcepitonHandler(HttpServletRequest request,Exception e) {
  10. log.info("进入增强异常处理:{}",LocalDateTime.now());
  11. log.info("异常信息:{}",e.getMessage());
  12. return e.getMessage();
  13. }
  14. }
  1. 这里可以多定义一些常见异常 。。。。。。。。。

枚举:

  1. public enum ResultEnum {
  2. UNKONW_ERROR(401,"未知错误"),
  3. SUCCESS(200,"成功"),
  4. ERROR(402,"失败"),
  5. ID_NOT_IN_SCOPE(403,"id不在范围内"),
  6. PERMISSION_DENIED(405,"权限不足"),
  7. ;
  8. private Integer code;
  9. private String msg;
  10.  
  11. ResultEnum(Integer code,String msg) {
  12. this.code = code;
  13. this.msg = msg;
  14. }
  15.  
  16. public Integer getCode() {
  17. return code;
  18. }
  19.  
  20. public String getMsg() {
  21. return msg;
  22. }
  23. }

测试:

后台控制台日志:

  

这里需要注意的是 必须around通过之后才会走 before 注解

spring boot aop 自定义注解 实现 日志检验 权限过滤的更多相关文章

  1. redis分布式锁-spring boot aop+自定义注解实现分布式锁

    接这这一篇redis分布式锁-java实现末尾,实现aop+自定义注解 实现分布式锁 1.为什么需要 声明式的分布式锁 编程式分布式锁每次实现都要单独实现,但业务量大功能复杂时,使用编程式分布式锁无疑 ...

  2. 利用Spring AOP自定义注解解决日志和签名校验

    转载:http://www.cnblogs.com/shipengzhi/articles/2716004.html 一.需解决的问题 部分API有签名参数(signature),Passport首先 ...

  3. spring AOP自定义注解 实现日志管理

    今天继续实现AOP,到这里我个人认为是最灵活,可扩展的方式了,就拿日志管理来说,用Spring AOP 自定义注解形式实现日志管理.废话不多说,直接开始!!! 关于配置我还是的再说一遍. 在appli ...

  4. (转)利用Spring AOP自定义注解解决日志和签名校验

    一.需解决的问题 部分API有签名参数(signature),Passport首先对签名进行校验,校验通过才会执行实现方法. 第一种实现方式(Origin):在需要签名校验的接口里写校验的代码,例如: ...

  5. Spring Boot中自定义注解+AOP实现主备库切换

    摘要: 本篇文章的场景是做调度中心和监控中心时的需求,后端使用TDDL实现分表分库,需求:实现关键业务的查询监控,当用Mybatis查询数据时需要从主库切换到备库或者直接连到备库上查询,从而减小主库的 ...

  6. 【Spring】每个程序员都使用Spring(四)——Aop+自定义注解做日志拦截

    一.前言 上一篇博客向大家介绍了Aop的概念,对切面=切点+通知 .连接点.织入.目标对象.代理(jdk动态代理和CGLIB代理)有所了解了.理论很强,实用就在这篇博客介绍. 这篇博客中,小编向大家介 ...

  7. spring boot通过自定义注解和AOP拦截指定的请求

    一 准备工作 1.1 添加依赖 通过spring boot创建好工程后,添加如下依赖,不然工程中无法使用切面的注解,就无法对制定的方法进行拦截 <dependency> <group ...

  8. Spring Boot实现自定义注解

    在Spring Boot项目中可以使用AOP实现自定义注解,从而实现统一.侵入性小的自定义功能. 实现自定义注解的过程也比较简单,只需要3步,下面实现一个统一打印日志的自定义注解: 1. 引入AOP依 ...

  9. 通过AOP自定义注解实现日志管理

    前言: 通过自定义注解和AOP结合的方式,实现日志的记录功能 大致流程:项目运行->用户操作调用业务处理类->通过自定义的注解(我理解为一个切点)->进入到AOP切面类(在这里可以获 ...

随机推荐

  1. informix 常见系统表

    systables:描述数据库中的每张表:syscolumns:描述数据库中表的列:sysindexes:描述数据库中列的索引:sysfragments:存储了分段索引的片段信息:sysfragaut ...

  2. Java I/O输入输出流

    IO流的复习总结 ------注:蓝色背景段落是例子:红色背景的字段IO流的功能类. 编码问题 String s = "威力锅ABC";  //utf-8编码中文占用三个字节,英文 ...

  3. Postman 使用方法详解

    转自:https://blog.csdn.net/fxbin123/article/details/80428216 一.Postman背景介绍 用户在开发或者调试网络程序或者是网页B/S模式的程序的 ...

  4. IPv6实验1_IPv6地址配置

    IPv6地址配置 实验任务 (1)掌握如何在路由器及PC上配置IPv6地址 (2)掌握如何用IPv6 ping命令进行IPv6地址可达性检查 (3)掌握如何用命令来查看IPv6地址配置 实验过程 在R ...

  5. Comedi的学习过程

    1.介绍Comedi 1.1Comedi是一个设备驱动开发的软件工具,它采用了一种3层组织模型:上层是用户层,Comedi提供了在用户控件编写程序的接口Comedilib,通过系统调用来控制硬件设备: ...

  6. guava学习,集合专题

    lists //JDKList<String> list = new ArrayList<String>();list.add("a");list.add( ...

  7. maven+eclipse+jboss+oracle 12c+memcached+AngularJS

    Maven 参考梁总的: Eclipse Java EE IDE for Web Developers集成的Maven 3 指向自己安装的 Maven Maven下载.安装和配置(二) 在本地配置ma ...

  8. Linux updatedb命令详解

    Linux updatedb命令 updatedb 命令用来创建或更新 locate 命令所必需的数据库文件. updatedb 命令的执行过程较长,因为在执行时它会遍历整个系统的目录树,并将所有的文 ...

  9. Spring常用的三种注入方式

    好文要收藏,摘自:https://blog.csdn.net/a909301740/article/details/78379720 Spring通过DI(依赖注入)实现IOC(控制反转),常用的注入 ...

  10. MQTT研究之EMQ:【基础研究】

    EMQ版本V2, emqttd-centos7-v2.3.11-1.el7.centos.x86_64.rpm 下载地址:http://emqtt.com/downloads/2318/centos7 ...