aop以及自定義注解實(shí)現(xiàn)同一個(gè)對(duì)象在不同場(chǎng)景下的參數(shù)判斷,并記錄日志

這個(gè)方法寫復(fù)雜了,就日志能看,改成 validator注解驗(yàn)證了。有兩個(gè)方法,update,add。這兩個(gè)方法操作同一個(gè)對(duì)象。

在update中name不能為空,在add中name可以為空。記得導(dǎo)入aop包

1、 以兩個(gè)對(duì)象為例

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<Foo> 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<Foo> getList() {
        return list;
    }

    public void setList(List<Foo> 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<String,Object> handleMiss(MissParamException ex) {
        Map<String,Object> map = new HashMap<>();
        map.put("code",ex.getCode());
        map.put("message",ex.getMessage());
        return map;
    }
}

4、配置aop,在這個(gè)配置中,驗(yàn)證思路是:

4.1 首先判斷方法上有沒有注解,或者注解參數(shù)全不全,如果沒有注解,不驗(yàn)證,直接運(yùn)行程序,并記錄回參

4.2 如果有注解,需要驗(yàn)證。之前新建了兩個(gè)對(duì)象,在這里用到,模擬一個(gè)aop適用所有對(duì)象

4.2.1 判斷aop的要驗(yàn)證的實(shí)體類

4.2.2 根據(jù)不同的實(shí)體類,封裝不同的驗(yàn)證方法。我這里每個(gè)對(duì)象都模擬了新增和修改兩個(gè)驗(yàn)證

新建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("進(jìn)入切面了················");
        MethodSignature methodSignature = (MethodSignature) joinPoint.getSignature();
        // 獲取切點(diǎn)類型
        Method method = methodSignature.getMethod();
        Valited annotation = method.getAnnotation(Valited.class);
        if (annotation == null || StringUtils.isEmpty(annotation.type())) {
            System.out.println("沒有注解,不往下驗(yàn)證···········");
            return;
        }
        Class clazz = annotation.clazz();
        // 獲取請(qǐng)求的類名
        String classname = joinPoint.getTarget().getClass().getName();
        System.out.println("請(qǐng)求方法名" + classname);
        // 請(qǐng)求參數(shù)
        Object[] args = joinPoint.getArgs();
        // USER的判空
        if (clazz == User.class) {
            // 參數(shù)判斷
            if (annotation.type().equals("add")) {
                UserAddRule.addTest(args);
            }
            if (annotation.type().equals("update")) {
                UserUpdateRule.addTest(args);
            }
        }
        // foo的判空
        if (clazz == Foo.class) {
            // 參數(shù)判斷
            if (annotation.type().equals("add")) {
                AddTest.addTest(args);
            }
            if (annotation.type().equals("update")) {
                UpdateTest.updateTest(args);
            }
        }
        System.out.println("還會(huì)繼續(xù)執(zhí)行嗎???????");
    }

    @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新增,編輯驗(yàn)證規(guī)則類

@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新增,編輯規(guī)則類

@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、 新建測(cè)試類

@RestController
public class TestController {

    @PostMapping("/test")
    @Valited(type = "add",clazz = Foo.class)
    public String test(@RequestBody Foo foo) {
        System.out.println("注解執(zhí)行結(jié)束,執(zhí)行業(yè)務(wù)==============================");
        return "success";
    }

    @PostMapping("/test1")
    @Valited(type = "update",clazz = Foo.class)
    public String test1(@RequestBody Foo foo) {
        System.out.println("注解執(zhí)行結(jié)束,執(zhí)行業(yè)務(wù)==============================");
        return "success";
    }

    @PostMapping("/test2")
    @Valited(type = "add",clazz = User.class)
    public Object test2(@RequestBody User user) {
        System.out.println("注解執(zhí)行結(jié)束,執(zhí)行業(yè)務(wù)==============================");
        return user;
    }

    @PostMapping("/test3")
    @Valited(type = "update",clazz = User.class)
    public String test3(@RequestBody User user) {
        System.out.println("注解執(zhí)行結(jié)束,執(zhí)行業(yè)務(wù)==============================");
        return "success";
    }
}

5.1 測(cè)試沒有的注解的情況

image.png

程序正常執(zhí)行,進(jìn)入aop,發(fā)現(xiàn)沒有注解,不走接下來的判斷。直接執(zhí)行主程序,執(zhí)行完aop獲取回參

5.2 測(cè)試add操作

image.png

程序首先進(jìn)入aop判斷,參數(shù)驗(yàn)證不通過,不往下執(zhí)行主程序,并拋出異常,被異常處理類捕獲

5.3 測(cè)試update操作

image.png

首先進(jìn)入aop,通過驗(yàn)證,執(zhí)行完全部before部分,然后執(zhí)行主程序,after獲取回參


image.png

aop參數(shù)認(rèn)證不通過,終止主程序,并拋出自定義異常

5.4 測(cè)試User操作

image.png
image.png
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

友情鏈接更多精彩內(nèi)容