SpringBoot 自定义注解AOP统一处理入参加解密脱敏等方法(二)

基于AOP实现,针对GET和POST请求分别作不同的处理。

1、定义需要处理的入参类型

/**
 * 要处理的字段数据类型
 */
public enum FieldTypeEnum {
  DEFAULT,
  PLATE_NUM,//车牌号

  ID_CARD,//身份证号

  PHONE;//手机号
}

2、定义注解

/**
 * 需重新赋值的注解
 */
@Documented
@Inherited
@Target({ElementType.FIELD, ElementType.PARAMETER})
@Retention(RetentionPolicy.RUNTIME)
public @interface Reassign {

  FieldTypeEnum type() default FieldTypeEnum.DEFAULT;
}

3、基于Aspect,实现入参的处理

@Aspect
@Component
public class ParamProcessAspect {

  @Pointcut("@annotation(org.springframework.web.bind.annotation.PostMapping) "
      + "|| @annotation(org.springframework.web.bind.annotation.GetMapping) "
      + "|| @annotation(org.springframework.web.bind.annotation.RequestMapping)")
  public void pointCut() {
  }

  @Around("pointCut()")
  public Object paramProcess(ProceedingJoinPoint joinPoint) throws Throwable {
    MethodSignature methodSignature = (MethodSignature) joinPoint.getSignature();
    Parameter[] parameters = methodSignature.getMethod().getParameters();
    paramProcess(joinPoint, parameters);
    Object obj = joinPoint.proceed(joinPoint.getArgs());

    return obj;
  }

  /**
   * 入参处理
   *
   * @param joinPoint
   * @param parameters
   * @throws IllegalAccessException
   */
  private void paramProcess(ProceedingJoinPoint joinPoint, Parameter[] parameters)
      throws IllegalAccessException {

    if (parameters.length > 0) {
      for (int i = 0; i < parameters.length; i++) {
        Parameter parameter = parameters[i];
        Object parameterValue = joinPoint.getArgs()[i];
        if (parameter.isAnnotationPresent(RequestParam.class) && parameter
            .isAnnotationPresent(Reassign.class)) {
          Reassign requestReassign = parameter.getAnnotation(Reassign.class);
          switch (requestReassign.type()) {
            case PHONE:
              joinPoint.getArgs()[i] = parameterValue + "phone";
              break;
            case ID_CARD:
              joinPoint.getArgs()[i] = parameterValue + "id";
              break;
            default:
              break;
          }
          continue;
        }

        if (parameter.isAnnotationPresent(RequestBody.class)) {
          Field[] fields = parameterValue.getClass().getDeclaredFields();
          for (Field field : fields) {
            if (field.isAnnotationPresent(Reassign.class)) {
              field.setAccessible(true);
              Reassign requestReassign = field.getAnnotation(Reassign.class);
              Object fieldValue = field.get(parameterValue);
              switch (requestReassign.type()) {
                case PHONE:
                  field.set(parameterValue, fieldValue + "phone");
                  break;
                case ID_CARD:
                  field.set(parameterValue, fieldValue + "id");
                  break;
                default:
                  break;
              }
            }
          }
        }
      }
    }
  }
}

4、controller层使用

  @PostMapping("/testPost")
  @ResponseBody
  public ApiResponse testPost(@RequestBody @Reassign User user) {
    return ApiResponse.success(user.getMobile());
  }

  @GetMapping("/testGet")
  @ResponseBody
  public ApiResponse testGet(
      @RequestParam @Reassign(type = FieldTypeEnum.PHONE) String phone,
      @RequestParam @Reassign(type = FieldTypeEnum.ID_CARD) String id) {
    return ApiResponse.success(phone + "," + id);
  }

总结:
此方法实现了controller层参数统一处理,RequestBody,RequestParam和RequestReassign一起使用,推荐使用。

也可修改切点,稍作改动,对其他想要拦截的方法使用。

你可能感兴趣的:(springboot技巧,java,spring)