RequestParamValidAspect.java 4.13 KB
Newer Older
liqin's avatar
liqin committed
1
package cn.chnmuseum.party.common.mvc;
liqin's avatar
liqin committed
2

liqin's avatar
liqin committed
3
import cn.chnmuseum.party.common.enums.RESPONSE_CODE_ENUM;
liqin's avatar
liqin committed
4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37
import lombok.extern.slf4j.Slf4j;
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.hibernate.validator.internal.engine.path.PathImpl;
import org.springframework.core.LocalVariableTableParameterNameDiscoverer;
import org.springframework.core.ParameterNameDiscoverer;
import org.springframework.stereotype.Component;

import javax.validation.ConstraintViolation;
import javax.validation.Validation;
import javax.validation.ValidatorFactory;
import javax.validation.executable.ExecutableValidator;
import java.lang.reflect.Method;
import java.util.Set;

/**
 * 参数校验切面
 */
@Slf4j
@Aspect
@Component
public class RequestParamValidAspect {

    private final ParameterNameDiscoverer parameterNameDiscoverer = new LocalVariableTableParameterNameDiscoverer();
    private final ValidatorFactory factory = Validation.buildDefaultValidatorFactory();
    private final ExecutableValidator validator = factory.getValidator().forExecutables();

    private <T> Set<ConstraintViolation<T>> validMethodParams(T obj, Method method, Object[] params) {
        return validator.validateParameters(obj, method, params);
    }

liqin's avatar
liqin committed
38
    @Pointcut("execution(* cn.chnmuseum.party.web.*.*.controller.*.*(..))")
liqin's avatar
liqin committed
39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91
    public void controllerBefore() {
    }

    @Before("controllerBefore()")
    public void before(JoinPoint point) {
        // 获得切入方法参数
        Object[] args = point.getArgs();
        if (args.length == 0) {
            return;
        }

        /**************************校验封装好的javabean**********************/
        //寻找带BindingResult参数的方法,然后判断是否有error,如果有则是校验不通过
//            for (Object arg : args) {
//                if (arg instanceof BeanPropertyBindingResult) {
//                    //有校验
//                    BeanPropertyBindingResult result = (BeanPropertyBindingResult) arg;
//                    if (result.hasErrors()) {
//                        List<ObjectError> list = result.getAllErrors();
//                        for (ObjectError error : list) {
//                            log.info(error.getCode() + "---" + Arrays.toString(error.getArguments()) + "--" + error.getDefaultMessage());
//                            //返回第一条校验失败信息。也可以拼接起来返回所有的
//                            return error.getDefaultMessage();
//                        }
//                    }
//                }
//            }

        /**************************校验普通参数*************************/
        Object target = point.getThis();
        // 获得切入的方法
        Method method = ((MethodSignature) point.getSignature()).getMethod();

        // 执行校验,获得校验结果
        Set<ConstraintViolation<Object>> validResult = validMethodParams(target, method, args);
        //如果有校验不通过的
        if (!validResult.isEmpty()) {
            // 获得方法的参数名称
            String[] parameterNames = parameterNameDiscoverer.getParameterNames(method);

            for (ConstraintViolation<Object> constraintViolation : validResult) {
                // 获得校验的参数路径信息
                PathImpl pathImpl = (PathImpl) constraintViolation.getPropertyPath();
                // 获得校验的参数位置
                int paramIndex = pathImpl.getLeafNode().getParameterIndex();
                assert parameterNames != null;
                // 获得校验的参数名称
                String paramName = parameterNames[paramIndex];
                //校验信息
                log.info(paramName + ": " + constraintViolation.getMessage());
            }
            //返回第一条校验失败信息,也可以拼接起来返回所有的
            String message = validResult.iterator().next().getMessage();
wzp's avatar
wzp committed
92
            throw new InterfaceException(RESPONSE_CODE_ENUM.PARAM_NOT_VALID.getResultCode(), message);
liqin's avatar
liqin committed
93 94 95 96
        }
    }

}