• spring boot aop 自定义注解 实现 日志检验 权限过滤


    核心代码:

      

    
    
    package com.tran.demo.aspect;
    
    import java.lang.reflect.Method;
    import java.time.LocalDateTime;
    
    import javax.servlet.http.HttpServletRequest;
    
    import org.aspectj.lang.JoinPoint;
    import org.aspectj.lang.ProceedingJoinPoint;
    import org.aspectj.lang.annotation.After;
    import org.aspectj.lang.annotation.AfterReturning;
    import org.aspectj.lang.annotation.Around;
    import org.aspectj.lang.annotation.Aspect;
    import org.aspectj.lang.annotation.Before;
    import org.aspectj.lang.annotation.Pointcut;
    import org.aspectj.lang.reflect.CodeSignature;
    import org.aspectj.lang.reflect.MethodSignature;
    import org.slf4j.Logger;
    import org.slf4j.LoggerFactory;
    import org.springframework.stereotype.Component;
    import org.springframework.util.StringUtils;
    import org.springframework.web.context.request.RequestContextHolder;
    import org.springframework.web.context.request.ServletRequestAttributes;
    
    import com.tran.demo.annotation.AuthAnnotation;
    import com.tran.demo.enums.ResultEnum;
    import com.tran.demo.exception.MyException;
    import com.tran.demo.model.User;
    
    @Component
    @Aspect
    public class MyAspect {
    
        private Logger log = LoggerFactory.getLogger(MyAspect.class);
        
         /**
         * 定义切入点,切入点为com.tran.demo.controller下的所有函数
         * 
         * // @Pointcut("@annotation(com.tran.demo.annotation.AuthAnnotation)")  对注解形式方法拦截
         */
        @Pointcut("execution(public * com.tran.demo.controller..*.*(..))")
        public void aspectLog(){}
        
        /**
         * 
         * 前置通知 ,就是到达controller之前
         * @param joinPoint
         */
        @Before("aspectLog()")
        public void doBefore(JoinPoint joinPoint){
            log.info("开始执行:{}",LocalDateTime.now());
            ServletRequestAttributes attributes = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes();
            HttpServletRequest request = attributes.getRequest();
            
            log.info("method={}", request.getMethod());
            log.info("class={} and method name = {}",joinPoint.getSignature().getDeclaringTypeName(),joinPoint.getSignature().getName());
            
            Object[] args = joinPoint.getArgs();
            String[] paramNames = ((CodeSignature)joinPoint.getSignature()).getParameterNames();
    
            for (int i = 0; i < args.length; i++) {
                log.info("参数:{},值:{}",paramNames[i],args[i]);
            }
            
        }
        
        /**
         * HTTP请求结束时的日志
         */
        @After("aspectLog()")
        public void doAfter(){
            
            log.info("结束执行:{}",LocalDateTime.now());
            
        }
    
        /**
         * 接口返回的具体内容
         * @param object
         */
        @AfterReturning(returning = "object",pointcut = "aspectLog()")
        public void doAfterReturn(Object object){
           
            log.info("返回数据:{}", object);
        }
        
        /**
         * 
         * 进行业务处理,判断是否有权限
         * 
         * @param proceedingJoinPoint
         * @return
         * @throws Throwable
         */
        @Around("aspectLog()")
        public Object doAroundAdvice(ProceedingJoinPoint proceedingJoinPoint) throws Throwable {
    
            ServletRequestAttributes attributes = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes();
            HttpServletRequest request = attributes.getRequest();
            MethodSignature methodSignature = (MethodSignature) proceedingJoinPoint.getSignature();
    
            Method method = methodSignature.getMethod();
            AuthAnnotation authAnnotation = method.getAnnotation(AuthAnnotation.class);
    
            if (null == authAnnotation) {
                log.info("该方法不需要权限,表示没有vip权限即可访问");
                return proceedingJoinPoint.proceed();
            }
    
            log.info("需要的权限:{}", authAnnotation.auth());
            String auth = request.getHeader("auth");
            log.info("请求头匹配权限:{}",auth);
            if (StringUtils.isEmpty(auth) || !auth.equals(authAnnotation.auth())) {
                log.info("该请求需要权限");
                throw new MyException(ResultEnum.PERMISSION_DENIED);
            }
            
            return proceedingJoinPoint.proceed();
        }
    }
    
    
    
     

    控制层(Controller):

    @RequestMapping("/user")
    @RestController
    public class UserController {
    
        @Autowired
        private IUserService userService;
    
        @GetMapping("/get/{userid}")
        @ResponseBody
        @AuthAnnotation(auth="vip")
        public List<User> hello(@PathVariable Integer userid) {
            Wrapper user = new EntityWrapper<User>();
            user.where("userid >= {0}", 10000).and("userid <= {0}", userid);
            return  userService.selectList(user);
        }
    }

    注解:

    @Target(ElementType.METHOD)
    @Retention(RetentionPolicy.RUNTIME)
    @Documented
    public @interface AuthAnnotation {
        
        // 非vip不能访问  user
        String auth() default "vip";
        
    }

    全局异常处理:

      

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

    枚举:

    public enum ResultEnum {
        UNKONW_ERROR(401,"未知错误"),
        SUCCESS(200,"成功"),
        ERROR(402,"失败"),
        ID_NOT_IN_SCOPE(403,"id不在范围内"),
        PERMISSION_DENIED(405,"权限不足"),
        ;
        private Integer code;
        private String msg;
        
        ResultEnum(Integer code,String msg) {
            this.code = code;
            this.msg = msg;
        }
     
        public Integer getCode() {
            return code;
        }
     
        public String getMsg() {
            return msg;
        }
    }

    测试:

    后台控制台日志:

      

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

  • 相关阅读:
    分布式与云计算有什么区别?
    多线程学习笔记
    docker解决报错WARNING: IPv4 forwarding is disabled. Networking will not work.
    Docker问题解决:Error response from daemon: Get https://registry-1.docker.io/v2/: dial tcp: lookup registry-1.docker.io: no such host
    docker学习笔记
    linux命令学习
    Xftp5提示要继续使用此程序,您必须应用最新的更新的解决方案
    Springboot学习笔记
    maven学习笔记
    Spring学习笔记(6)
  • 原文地址:https://www.cnblogs.com/1-Admin/p/10524008.html
Copyright © 2020-2023  润新知