SpringBoot AOP 自定义注解

亦凉 2023-09-30 09:46 121阅读 0赞

自定义注解

  • 对请求进行访问权限校验
  • 日志收集

对请求进行访问权限校验

自定义一个忽略校验的注解

  1. import java.lang.annotation.ElementType;
  2. import java.lang.annotation.Retention;
  3. import java.lang.annotation.RetentionPolicy;
  4. import java.lang.annotation.Target;
  5. /**
  6. * 忽略验证
  7. *
  8. * @author Administrator
  9. * @version V1.0
  10. * @date 2022/3/16
  11. */
  12. @Target({
  13. ElementType.METHOD, ElementType.TYPE})
  14. @Retention(RetentionPolicy.RUNTIME)
  15. public @interface NotVerify {
  16. boolean required() default true;
  17. }

创建拦截器

  1. import com.ddz.project.common.aop.annotation.NotVerify;
  2. import com.ddz.project.common.utils.JWTUtil;
  3. import org.springframework.web.method.HandlerMethod;
  4. import org.springframework.web.servlet.HandlerInterceptor;
  5. import org.springframework.web.servlet.ModelAndView;
  6. import javax.servlet.http.HttpServletRequest;
  7. import javax.servlet.http.HttpServletResponse;
  8. import java.io.PrintWriter;
  9. import java.lang.reflect.Method;
  10. /**
  11. * @author Administrator
  12. * @version V1.0
  13. * @date 2022/3/16
  14. */
  15. public class TokenInterceptor implements HandlerInterceptor {
  16. @Override
  17. public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object object) throws Exception {
  18. try {
  19. // 如果不是映射到方法直接通过
  20. if (!(object instanceof HandlerMethod)) {
  21. return true;
  22. }
  23. HandlerMethod handlerMethod = (HandlerMethod) object;
  24. Method method = handlerMethod.getMethod();
  25. //检查是否有NotVerify注释,有则跳过认证
  26. if (method.isAnnotationPresent(NotVerify.class)) {
  27. NotVerify annotation = method.getAnnotation(NotVerify.class);
  28. if (annotation.required()) {
  29. return true;
  30. }
  31. }
  32. String token = request.getHeader("token");
  33. boolean verify = JWTUtil.verify(token);
  34. if (verify) {
  35. return true;
  36. }
  37. } catch (Exception e) {
  38. return false;
  39. }
  40. response.setCharacterEncoding("UTF-8");
  41. response.setContentType("application/json; charset=utf-8");
  42. PrintWriter writer = response.getWriter();
  43. writer.println("token验证失败");
  44. writer.close();
  45. return false;
  46. }
  47. @Override
  48. public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {
  49. HandlerInterceptor.super.postHandle(request, response, handler, modelAndView);
  50. }
  51. @Override
  52. public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {
  53. HandlerInterceptor.super.afterCompletion(request, response, handler, ex);
  54. }
  55. }

在控制器的方法上加上注解就不需要验证权限了

  1. @NotVerify
  2. @ApiOperation(value = "login")
  3. @PostMapping("login")
  4. public String login(HttpServletRequest request, HttpServletResponse response, String id, String userName) {
  5. System.out.println("id = " + id + ", userName = " + userName);
  6. return JWTUtil.jwtCreateExpired(userName, id, 10);
  7. }

日志收集

创建自定义注解

  1. package com.ddz.project.common.aop.annotation;
  2. import java.lang.annotation.*;
  3. /**
  4. * @author Administrator
  5. * @version V1.0
  6. * @date 2022/3/16
  7. */
  8. @Target({
  9. ElementType.TYPE, ElementType.METHOD})
  10. @Retention(RetentionPolicy.RUNTIME)
  11. @Documented
  12. public @interface Log {
  13. String value() default "ddz log";
  14. }

定义AOP

  1. import cn.hutool.core.date.DateUtil;
  2. import com.alibaba.fastjson.JSON;
  3. import com.ddz.project.common.aop.annotation.Log;
  4. import com.ddz.project.common.utils.IPUtils;
  5. import lombok.SneakyThrows;
  6. import org.aspectj.lang.ProceedingJoinPoint;
  7. import org.aspectj.lang.Signature;
  8. import org.aspectj.lang.annotation.*;
  9. import org.aspectj.lang.reflect.MethodSignature;
  10. import org.springframework.stereotype.Component;
  11. import org.springframework.web.context.request.RequestContextHolder;
  12. import org.springframework.web.context.request.ServletRequestAttributes;
  13. import javax.servlet.http.HttpServletRequest;
  14. import javax.servlet.http.HttpServletResponse;
  15. import java.util.ArrayList;
  16. import java.util.Arrays;
  17. import java.util.List;
  18. /**
  19. * 顺序
  20. * around => doBefore => after
  21. *
  22. * @author Administrator
  23. * @version V1.0
  24. * @date 2022/3/16
  25. */
  26. @Aspect
  27. @Component
  28. public class LogAop {
  29. /**
  30. * 定义切面
  31. */
  32. @Pointcut(value = "@annotation(com.ddz.project.common.aop.annotation.Log)&&execution(com.ddz.project.common.aop.aspect.LogAop)")
  33. public void access() {
  34. }
  35. // @Before("access()")
  36. // public void doBefore() {
  37. // System.out.println("aop 日志启动");
  38. // }
  39. /**
  40. * 定义切面 并携带log注解的才会被收集
  41. * @param pjp 入参
  42. * @param logger 注解
  43. */
  44. @SneakyThrows
  45. @Around("execution(public * com.ddz.project.controller.*.*(..)) && @annotation(log)")
  46. public Object around(ProceedingJoinPoint pjp, Log log) {
  47. System.out.println("****aop 日志环绕阶段****" + DateUtil.today());
  48. ServletRequestAttributes attributes = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes();
  49. HttpServletRequest request = attributes.getRequest();
  50. // GET 请求其实可以从request里获取出参数
  51. // Map<String,String[]> map=request.getParameterMap();
  52. // System.out.println("获取参数:"+map.get("username")[0])
  53. String url = request.getRequestURL().toString();
  54. String ip = IPUtils.getIpAddr(request);
  55. String logTrackValue = logger.value();
  56. Object[] pipArrary = pjp.getArgs();
  57. if (pipArrary.length > 1) {
  58. //多参,不是Map/JsonObject方式
  59. List<Object> argList = new ArrayList<>();
  60. for (Object arg : pjp.getArgs()) {
  61. // request/response无法使用toJSON
  62. if (arg instanceof HttpServletRequest) {
  63. argList.add("request");
  64. } else if (arg instanceof HttpServletResponse) {
  65. argList.add("response");
  66. } else {
  67. argList.add(JSON.toJSON(arg));
  68. }
  69. }
  70. Signature signature = pjp.getSignature();
  71. // 参数名数组
  72. String[] parameterNames = ((MethodSignature) signature).getParameterNames();
  73. System.out.println("参数名数组:" + new ArrayList<>(Arrays.asList(parameterNames)));
  74. System.out.println("参数是:" + argList);
  75. System.out.println("logTrackValue:" + logTrackValue);
  76. System.out.println("url:" + url);
  77. System.out.println("ip:" + ip);
  78. return pjp.proceed();
  79. }
  80. Object param = pipArrary[0];
  81. System.out.println("logTrackValue:" + logTrackValue);
  82. System.out.println("url:" + url);
  83. System.out.println("ip:" + ip);
  84. System.out.println("param:" + param);
  85. return pjp.proceed();
  86. }
  87. // @After("access()")
  88. // public void after() {
  89. // System.out.println("aop 日志结束");
  90. // }
  91. }

在控制器里面添加注解就会被收集日志

  1. @Log("测试的")
  2. @ApiOperation(value = "get")
  3. @RequestMapping("get")
  4. @NotVerify
  5. public String get(@RequestBody Map<String, Object> map) {
  6. System.out.println("map = " + map);
  7. return "not token";
  8. }

发表评论

表情:
评论列表 (有 0 条评论,121人围观)

还没有评论,来说两句吧...

相关阅读