aop以及自定义注解实现同一个对象在不同场景下的参数判断,并记录日志

这个方法写复杂了,就日志能看,改成 validator注解验证了。有两个方法,update,add。这两个方法操作同一个对象。

在update中name不能为空,在add中name可以为空。记得导入aop包

1、 以两个对象为例

Foo:

public class Foo {
    private Integer age;

    private String name;

    private String id;

    public Integer getAge() {
        return age;
    }

    public void setAge(Integer age) {
        this.age = age;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public String getId() {
        return id;
    }

    public void setId(String id) {
        this.id = id;
    }
}

User:

public class User {
    private String id;
    private String name;

    private List list;

    public String getId() {
        return id;
    }

    public void setId(String id) {
        this.id = id;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public List getList() {
        return list;
    }

    public void setList(List list) {
        this.list = list;
    }
}

2、自定义注解

@Documented
@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
public @interface Valited {
    String type() default "";
    Class clazz();
}

3、自定义异常,以及全局处理类

public class MissParamException extends RuntimeException {
    private int code = 200;


    public int getCode() {
        return code;
    }

    public void setCode(int code) {
        this.code = code;
    }

    public MissParamException(String message, int code) {
        super(message);
        this.code = code;
    }

    public MissParamException(String message) {
        super(message);
    }
}
@RestControllerAdvice
public class ExceptionHandle {

    @ExceptionHandler(value = MissParamException.class)
    public Map handleMiss(MissParamException ex) {
        Map map = new HashMap<>();
        map.put("code",ex.getCode());
        map.put("message",ex.getMessage());
        return map;
    }
}

4、配置aop,在这个配置中,验证思路是:

4.1 首先判断方法上有没有注解,或者注解参数全不全,如果没有注解,不验证,直接运行程序,并记录回参

4.2 如果有注解,需要验证。之前新建了两个对象,在这里用到,模拟一个aop适用所有对象

4.2.1 判断aop的要验证的实体类

4.2.2 根据不同的实体类,封装不同的验证方法。我这里每个对象都模拟了新增和修改两个验证

新建aop

@Aspect
@Component
public class AopConfig {

    @Pointcut("execution(public * com.example.valited.controller..*.*(..))")
    public void testaop(){}

    @Before("testaop()")
    public void testLog(JoinPoint joinPoint) {
        System.out.println("进入切面了················");
        MethodSignature methodSignature = (MethodSignature) joinPoint.getSignature();
        // 获取切点类型
        Method method = methodSignature.getMethod();
        Valited annotation = method.getAnnotation(Valited.class);
        if (annotation == null || StringUtils.isEmpty(annotation.type())) {
            System.out.println("没有注解,不往下验证···········");
            return;
        }
        Class clazz = annotation.clazz();
        // 获取请求的类名
        String classname = joinPoint.getTarget().getClass().getName();
        System.out.println("请求方法名" + classname);
        // 请求参数
        Object[] args = joinPoint.getArgs();
        // USER的判空
        if (clazz == User.class) {
            // 参数判断
            if (annotation.type().equals("add")) {
                UserAddRule.addTest(args);
            }
            if (annotation.type().equals("update")) {
                UserUpdateRule.addTest(args);
            }
        }
        // foo的判空
        if (clazz == Foo.class) {
            // 参数判断
            if (annotation.type().equals("add")) {
                AddTest.addTest(args);
            }
            if (annotation.type().equals("update")) {
                UpdateTest.updateTest(args);
            }
        }
        System.out.println("还会继续执行吗???????");
    }

    @AfterReturning(returning = "rvt",pointcut = "testaop()")
    public void testAfter(Object rvt) throws Throwable {
        getReturnParam(rvt);
}

    /**
     * 日志处理方法,存表之类的
     * @param object
     */
    public void getReturnParam(Object object) {
        System.out.println(object);
    }
}

新建Foo新增,编辑验证规则类

@Component
public class AddTest {
    public static void addTest(Object[] args) {
        for (Object arg:args) {
            Foo foo = (Foo) arg;
            if (StringUtils.isEmpty(foo.getName())) {
                throw new MissParamException("新增操作name不能为空");
            }
        }
    }
}
@Component
public class UpdateTest {
    public static void updateTest(Object[] args) {
        for (Object arg:args) {
            Foo foo = (Foo) arg;
            if (StringUtils.isEmpty(foo.getId())) {
                throw new MissParamException("编辑操作id不能为空");
            }
        }
    }
}

新建User新增,编辑规则类

@Component
public class UserAddRule {
    public static void addTest(Object[] args) {
        for (Object arg:args) {
            User user = (User) arg;
            if (StringUtils.isEmpty(user.getName())) {
                throw new MissParamException("user新增操作name不能为空",300);
            }
        }
    }
}
@Component
public class UserUpdateRule {
    public static void addTest(Object[] args) {
        for (Object arg:args) {
            User user = (User) arg;
            if (StringUtils.isEmpty(user.getId())) {
                throw new MissParamException("user编辑操作id不能为空",201);
            }
        }
    }
}

5、 新建测试类

@RestController
public class TestController {

    @PostMapping("/test")
    @Valited(type = "add",clazz = Foo.class)
    public String test(@RequestBody Foo foo) {
        System.out.println("注解执行结束,执行业务==============================");
        return "success";
    }

    @PostMapping("/test1")
    @Valited(type = "update",clazz = Foo.class)
    public String test1(@RequestBody Foo foo) {
        System.out.println("注解执行结束,执行业务==============================");
        return "success";
    }

    @PostMapping("/test2")
    @Valited(type = "add",clazz = User.class)
    public Object test2(@RequestBody User user) {
        System.out.println("注解执行结束,执行业务==============================");
        return user;
    }

    @PostMapping("/test3")
    @Valited(type = "update",clazz = User.class)
    public String test3(@RequestBody User user) {
        System.out.println("注解执行结束,执行业务==============================");
        return "success";
    }
}

5.1 测试没有的注解的情况

image.png

程序正常执行,进入aop,发现没有注解,不走接下来的判断。直接执行主程序,执行完aop获取回参

5.2 测试add操作

image.png

程序首先进入aop判断,参数验证不通过,不往下执行主程序,并抛出异常,被异常处理类捕获

5.3 测试update操作

image.png

首先进入aop,通过验证,执行完全部before部分,然后执行主程序,after获取回参


image.png

aop参数认证不通过,终止主程序,并抛出自定义异常

5.4 测试User操作

image.png
image.png

你可能感兴趣的:(aop以及自定义注解实现同一个对象在不同场景下的参数判断,并记录日志)