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 注解

原文地址:https://www.cnblogs.com/1-Admin/p/10524008.html