spring 自定義引數校驗
阿新 • • 發佈:2019-01-08
Spring bean校驗
public abstract class GenericValidator {
public abstract void validate(ProceedingJoinPoint pjp);
protected String errorHandler(Map<String,Object> errors) {
return new JSONObject(errors).toString();
}
}
public class BeanValidator extends GenericValidator{
private static final Logger logger = LoggerFactory.getLogger(BeanValidator.class);
private final Validator validator = Validation.buildDefaultValidatorFactory().getValidator();
public void validate(ProceedingJoinPoint pjp) {
Object[] objs = pjp.getArgs();
for(int i = 0;i < objs.length;i++) {
validator(objs[i],new Class<?>[0]);
}
}
/**
* @Description: 驗證器
* @param object 驗證物件
* @param groups
*/
protected <T> void validator(T object, Class<?>... groups) {
Map<String,Object> errorMaps = new HashMap<String,Object>();
Set<ConstraintViolation<T>> constraintViolationSet = validator.validate(object, groups);
if (CollectionUtils.isNotEmpty(constraintViolationSet)) {
for(Iterator<ConstraintViolation<T>> iterator = constraintViolationSet.iterator(); iterator.hasNext();) {
ConstraintViolation<T> error = iterator.next();
errorMaps.put(((PathImpl)error.getPropertyPath()).getLeafNode().getName(), error.getMessage());
}
}
if(MapUtils.isNotEmpty(errorMaps)) {
logger.debug("【validator】:引數校驗結果"+errorMaps);
throw new ParamException(errorHandler(errorMaps));
}
}
}
spring 方法級校驗
public abstract class GenericValidator {
public abstract void validate(ProceedingJoinPoint pjp);
protected String errorHandler(Map<String,Object> errors) {
return new JSONObject(errors).toString();
}
}
public class ParamValidator extends GenericValidator{
private static final Logger logger = LoggerFactory.getLogger(ParamValidator.class);
private final ExecutableValidator executableValidator = Validation.buildDefaultValidatorFactory()
.getValidator().forExecutables();
public void validate(ProceedingJoinPoint pjp) {
Map<String,Object> errorMaps = new HashMap<String,Object>();
Object object = pjp.getTarget();// 目標物件
MethodSignature methodSignature = ((MethodSignature) pjp.getSignature());// 方法簽名
Object[] parameterValues = pjp.getArgs();// 引數
Set<ConstraintViolation<Object>> constraintViolations = validator(object,
methodSignature.getMethod(),
parameterValues);
if(CollectionUtils.isNotEmpty(constraintViolations)) {
Iterator<ConstraintViolation<Object>> constraintViolationIterator = constraintViolations.iterator();
while(constraintViolationIterator.hasNext()) {
ConstraintViolation<Object> constraintViolation = constraintViolationIterator.next();
errorMaps.put(getMethodParamName(methodSignature, constraintViolation), constraintViolation.getMessage());
}
if(MapUtils.isNotEmpty(errorMaps)) {
logger.debug("【validator】:引數校驗結果"+errorMaps);
throw new ParamException(errorHandler(errorMaps));
}
}
}
protected <T> Set<ConstraintViolation<T>> validator(T object,
Method method,
Object[] parameterValues,
Class<?>... groups) {
Set<ConstraintViolation<T>> set = executableValidator.validateParameters(object,
method,
parameterValues,
groups);
return set;
}
protected <T> Set<ConstraintViolation<T>> validator(T object,
Method method,
Object[] parameterValues) {
return validator(object, method, parameterValues, new Class<?>[0]);
}
/**
* 獲得方法引數名稱
* @param methodSignature
* @param constraintViolation
* @return
*/
private static String getMethodParamName(MethodSignature methodSignature,
ConstraintViolation<Object> constraintViolation) {
String[] parameterNames = methodSignature.getParameterNames();
PathImpl pathImpl = (PathImpl) constraintViolation.getPropertyPath(); // 獲得校驗的引數路徑資訊
int paramIndex = pathImpl.getLeafNode().getParameterIndex(); // 獲得校驗的引數位置
if(parameterNames == null || parameterNames.length == 0 || parameterNames.length <= paramIndex) {
return "";
} else {
return parameterNames[paramIndex];
}
}
}
框架整合
利用aop對方法進行攔截
@Component
@Aspect
public class ParamValidAspect {
/*驗證com.gz.controller及其子包中以update開頭和insert開頭的方法*/
/*驗證com.gz.controller及其子包中以BeanValid結尾的方法*/
@Pointcut("execution(* com.gz.controller..*.insert* (..)) || execution(* com.gz.controller..*.update* (..)) || execution(* com.gz.controller..*.*BeanValid(..))")
public void beanValidatorPointcut(){}
/*驗證com.gz.controller及其子包中以ParamValid結尾的方法*/
@Pointcut("execution(* com.gz.controller..*.*ParamValid(..))")
public void paramValidatorPointcut(){}
@Around("beanValidatorPointcut()")
public ResponseRel beanValidatorAdvice(ProceedingJoinPoint pjp) throws Throwable {
GenericValidator validator = new BeanValidator();
validator.validate(pjp);
Object[] args = pjp.getArgs();
Object result = pjp.proceed(args);
return (ResponseRel)result;
}
@Around("paramValidatorPointcut()")
public ResponseRel paramValidatorPointcut(ProceedingJoinPoint pjp) throws Throwable {
GenericValidator validator = new ParamValidator();
validator.validate(pjp);
Object[] args = pjp.getArgs();
Object result = pjp.proceed(args);
return (ResponseRel)result;
}
}