1. 程式人生 > >spring 自定義引數校驗

spring 自定義引數校驗

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;
    }
}