首先为啥会有这种需求,因为@valid的返回太不友好,一般项目中的返回都是固定格式,为了达到返回格式统一,又能做自动化参数检校。
1,首先加在方法上加入口注解
import java.lang.annotation.*;
@Target({ElementType.METHOD})
@Retention(RetentionPolicy.RUNTIME)
@Inherited
@Documented
public @interface ParamCheck {
String value() default "";
}
2,其次在方法入参地方加上注解
import java.lang.annotation.*;
@Target({ElementType.PARAMETER})
@Retention(RetentionPolicy.RUNTIME)
@Inherited
@Documented
public @interface Check {
Class<?>[] value() default {};
}
3,配置切点和逻辑
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
import org.aspectj.lang.annotation.Pointcut;
import org.aspectj.lang.reflect.MethodSignature;
import org.springframework.core.annotation.Order;
import javax.validation.ConstraintViolation;
import javax.validation.Validator;
import java.lang.annotation.Annotation;
import java.lang.reflect.Method;
import java.util.Set;
@Aspect
@Order(1008)
public class ValidAspect {
private Validator validator;
public ValidAspect(Validator validator) {
this.validator = validator;
}
@Pointcut("@annotation(coo.cn.自定义参数检校.ParamCheck) " +
"|| @annotation(org.springframework.web.bind.annotation.RequestMapping)+" +
" || @annotation(org.springframework.web.bind.annotation.GetMapping)+" +
" || @annotation(org.springframework.web.bind.annotation.PostMapping)")
public void cut() {
}
@Before("cut() && execution(* coo.cn.自定义参数检校..*.*(..))")
public void before(JoinPoint point) throws Exception {
Object[] args = point.getArgs();
if (args == null || args.length == 0) {
return;
}
MethodSignature signature = (MethodSignature) point.getSignature();
Method method = signature.getMethod();
Annotation[][] parameterAnnotations = method.getParameterAnnotations();
for (int i = 0; i < parameterAnnotations.length; i++) {
Object param = args[i];
Annotation[] annotations = parameterAnnotations[i];
if (annotations != null && annotations.length > 0) {
for (Annotation ann : annotations) {
if (Check.class.equals(ann.annotationType())) {
Set<ConstraintViolation<Object>> set = this.validator.validate(param, ((Check) ann).value());
if (set.size()>0){
ConstraintViolation<Object> next = set.iterator().next();
throw new Exception(next.getMessage());
}
}
}
}
}
}
}
4,配置Bean
import org.hibernate.validator.HibernateValidator;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import javax.validation.Validation;
import javax.validation.ValidatorFactory;
@Configuration
public class ValidConfig {
@Bean
public ValidAspect validAspect(){
try (ValidatorFactory validatorFactory = Validation.byProvider(HibernateValidator.class)
.configure()
.failFast(true)
.buildValidatorFactory()) {
return new ValidAspect(validatorFactory.getValidator());
}
}
}
5,测试
import coo.cn.pojo.TtInfo;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
@RestController
@RequestMapping("valid")
public class ValidController {
@ParamCheck
@RequestMapping("valid")
public String t1(@RequestBody @Check TtInfo info) {
System.out.println(info);
return "OK";
}
}