这个方法写复杂了,就日志能看,改成 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 测试没有的注解的情况
程序正常执行,进入aop,发现没有注解,不走接下来的判断。直接执行主程序,执行完aop获取回参
5.2 测试add操作
程序首先进入aop判断,参数验证不通过,不往下执行主程序,并抛出异常,被异常处理类捕获
5.3 测试update操作
首先进入aop,通过验证,执行完全部before部分,然后执行主程序,after获取回参
aop参数认证不通过,终止主程序,并抛出自定义异常