Spring之RequestBodyAdvice参数校验
前言
之前写了一篇 自定义starter之接口标准化。其中对requestBody做了validate统一参数校验。最近在写单元测试的时候发现body无法重复消费(正常http接口请求正常), 所以重新写了这部分逻辑。
实现逻辑
1 2 3 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 38 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
| package cn.idea360.unified;
import org.hibernate.validator.HibernateValidator; import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty; import org.springframework.core.MethodParameter; import org.springframework.core.annotation.AnnotationUtils; import org.springframework.http.HttpInputMessage; import org.springframework.http.converter.HttpMessageConverter; import org.springframework.validation.annotation.Validated; import org.springframework.web.bind.annotation.*; import org.springframework.web.servlet.mvc.method.annotation.RequestBodyAdvice;
import javax.validation.*; import java.io.IOException; import java.lang.reflect.Type; import java.util.Arrays; import java.util.Set;
@ConditionalOnProperty(value = "idea360.framework.unified.enable", havingValue = "true") @RestControllerAdvice public class ValidateRequestBodyAdvice implements RequestBodyAdvice {
private static final Validator VALIDATOR = Validation.byProvider(HibernateValidator.class).configure() .failFast(true).buildValidatorFactory().getValidator();
@Override public boolean supports(MethodParameter methodParameter, Type targetType, Class<? extends HttpMessageConverter<?>> converterType) { boolean matchValidAnnotation = Arrays.stream(methodParameter.getMethodAnnotations()) .anyMatch(t -> t.annotationType().equals(Validated.class) || t.annotationType().equals(Valid.class)); boolean matchString = methodParameter.getParameterType().isAssignableFrom(String.class); boolean matchPostOrPutMapping = Arrays.stream(methodParameter.getMethodAnnotations()).anyMatch( t -> t.annotationType().equals(PostMapping.class) || t.annotationType().equals(PutMapping.class)); boolean matchPostOrPutRequestMapping = Arrays.stream(methodParameter.getMethodAnnotations()) .anyMatch(t -> t.annotationType().equals(RequestMapping.class) && Arrays.stream(AnnotationUtils.getAnnotation(t, RequestMapping.class).method()) .anyMatch(m -> m.equals(RequestMethod.POST) || m.equals(RequestMethod.PUT))); return (matchPostOrPutMapping || matchPostOrPutRequestMapping) && !matchValidAnnotation && !matchString; }
@Override public HttpInputMessage beforeBodyRead(HttpInputMessage inputMessage, MethodParameter parameter, Type targetType, Class<? extends HttpMessageConverter<?>> converterType) throws IOException { return inputMessage; }
@Override public Object afterBodyRead(Object body, HttpInputMessage inputMessage, MethodParameter parameter, Type targetType, Class<? extends HttpMessageConverter<?>> converterType) { Set<ConstraintViolation<Object>> constraintViolations = VALIDATOR.validate(body); if (!constraintViolations.isEmpty()) { throw new ConstraintViolationException(constraintViolations); } return body; }
@Override public Object handleEmptyBody(Object body, HttpInputMessage inputMessage, MethodParameter parameter, Type targetType, Class<? extends HttpMessageConverter<?>> converterType) { return body; }
}
|
spring.factories修改
1 2 3 4
| org.springframework.boot.autoconfigure.EnableAutoConfiguration=\ cn.idea360.unified.UnifiedResponseBodyAdvice,\ cn.idea360.unified.UnifiedExceptionHandler,\ cn.idea360.unified.ValidateRequestBodyAdvice
|
最后
本文到此结束,感谢阅读。如果您觉得不错,请关注公众号【当我遇上你】,您的支持是我写作的最大动力。