JSR 303 - Bean Validation
Всякий раз, когда вы имеете дело с бизнес-логикой приложения, проверка данных — это то, что вы должны учитывать и сталкиваться с этим. Приложение должно иметь средства для обеспечения семантической корректности входящих данных.
В обычном случае приложение является многоуровневым, и разные слои создаются разными разработчиками.
Во многих случаях одна и та же логика проверки данных будет появляться на разных уровнях, что приведет к избыточности кода и некоторым проблемам управления, таким как семантическая согласованность.
Чтобы избежать этой ситуации, лучше всего привязать логику проверки к соответствующей модели предметной области.
тогдаJSR 303 - Bean Validation
возник.
Использование в Maven
в Мавенеpom.xml
введен вvalidation-api
<dependency>
<groupId>javax.validation</groupId>
<artifactId>validation-api</artifactId>
<version>2.0.1.Final</version>
</dependency>
validation-api
Отличное дополнение к источникуhibernate
,Несмотря на то чтоhibernate
Он ушел, но многое из его сущности осталось.
<dependency>
<groupId>org.hibernate.validator</groupId>
<artifactId>hibernate-validator</artifactId>
</dependency>
Список аннотаций
Встроенные ограничения в Bean Validation
@Null 被注释的元素必须为 null
@NotNull 被注释的元素必须不为 null
@AssertTrue 被注释的元素必须为 true
@AssertFalse 被注释的元素必须为 false
@Min(value) 被注释的元素必须是一个数字,其值必须大于等于指定的最小值
@Max(value) 被注释的元素必须是一个数字,其值必须小于等于指定的最大值
@DecimalMin(value) 被注释的元素必须是一个数字,其值必须大于等于指定的最小值
@DecimalMax(value) 被注释的元素必须是一个数字,其值必须小于等于指定的最大值
@Size(max, min) 被注释的元素的大小必须在指定的范围内
@Digits (integer, fraction) 被注释的元素必须是一个数字,其值必须在可接受的范围内
@Past 被注释的元素必须是一个过去的日期
@Future 被注释的元素必须是一个将来的日期
@Pattern(value) 被注释的元素必须符合指定的正则表达式
Дополнительные ограничения Hibernate Validator
@Email 被注释的元素必须是电子邮箱地址
@Length 被注释的字符串的大小必须在指定的范围内
@NotEmpty 被注释的字符串的必须非空
@Range 被注释的元素必须在合适的范围内
пользовательская аннотация
путем реализацииConstraintValidator
Аннотации параметров можно настраивать.
Mobile.java
@Target( {
METHOD,
FIELD,
ANNOTATION_TYPE,
CONSTRUCTOR,
PARAMETER
})
@Retention(RUNTIME)
@Documented
@Constraint(validatedBy = {MobileValidator.class})
public @interface Mobile {
String regexp() default "";
String message() default "手机号码格式不正确";
Class<?>[] groups() default {};
Class<? extends Payload>[] payload() default {};
}
MobileValidator.java
public class MobileValidator implements ConstraintValidator<Mobile, String> {
/**
* 手机号的正则表达式.
*/
private static Pattern pattern = Pattern.compile(
"^0?(13[0-9]|14[0-9]|15[0-9]|16[0-9]|17[0-9]|18[0-9]|19[0-9])[0-9]{8}$");
@Override
public boolean isValid(String value, ConstraintValidatorContext constraintValidatorContext) {
Matcher m = pattern.matcher(value);
return m.matches();
}
@Override
public void initialize(Mobile constraintAnnotation) {}
}
Таким образом, мы можем использовать аннотации в Beans.@Mobile
.
User.java
@Data
public class User {
@NotBlank
private String userName;
@Mobile
private String mobile;
}
Используется в Spring Boot
Конфигурация проверки на уровне метода
@Configuration
public class ValidateConfig {
@Bean
public MethodValidationPostProcessor methodValidationPostProcessor(){
return new MethodValidationPostProcessor();
}
}
1. Используйте@Valid
Проверьте параметры
@RequestMapping(value = "/book", method = RequestMethod.POST)
public void addBook(@RequestBody @Valid Book book) {
System.out.println(book.toString());
}
2. Используйте на уроке@Validated
Проверьте параметры
@RestController
@Validated
public class ValidateController {
// ...
}
перехват исключений
Для исключений параметровBindException
Выполнить глобальный перехват исключений.
GlobalWebExceptionHandler.java
@ControllerAdvice
public class GlobalWebExceptionHandler {
private static final Logger LOGGER = LoggerFactory.getLogger(GlobalWebExceptionHandler.class);
/**
* 定义参数异常处理器.
*
* @param e 当前平台异常参数对象.
* @return org.springframework.http.ResponseEntity
*/
@ExceptionHandler(BindException.class)
@ResponseBody
@ResponseStatus(HttpStatus.BAD_REQUEST)
public ResponseEntity<Map<String, Object>> validateErrorHandler(BindException e) {
Map<String, Object> errorMap = new HashMap<>(2);
BindingResult bindingResult = e.getBindingResult();
if (bindingResult.hasErrors()) {
List<FieldError> errorList = bindingResult.getFieldErrors();
String errorMsg = "[字段:" + errorList.get(0).getField() + "]错误,原因:" + errorList.get(0).getDefaultMessage();
errorMap.put("message", errorMsg);
errorMap.put("code", EnumError.PARAMS_ERROR.getCode());
return new ResponseEntity<>(errorMap, HttpStatus.BAD_REQUEST);
}
LOGGER.error("[服务] - [捕获参数异常。异常信息:{}]", JSON.toJSONString(bindingResult));
return new ResponseEntity<>(errorMap, HttpStatus.BAD_REQUEST);
}
}