package cn.wisenergy.chnmuseum.party.common.mvc; import cn.wisenergy.chnmuseum.party.common.enums.RESPONSE_CODE_ENUM; 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); } @Pointcut("execution(* cn.wisenergy.chnmuseum.party.web.*.*.controller.*.*(..))") 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(); throw new InterfaceException(RESPONSE_CODE_ENUM.PARAM_NOT_VALID.getResultCode(), message); } } }