這個(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