基于javax.validation
结合Spring
的最佳实践,主要是利用Spring
框架提供的Validator
和DataBinder
接口以及javax.validation
提供的注解和API对请求参数和数据模型进行合法性校验,来保证应用程序的数据输入和输出的正确性。
下面是基于Spring Boot
的完整攻略:
1. 引入依赖
在pom.xml
文件中引入以下依赖:
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-validation</artifactId>
</dependency>
</dependencies>
注:spring-boot-starter-validation
依赖会自动引入hibernate-validator
和javax.el
依赖。
2. 创建校验器
创建一个MyValidator
类,继承javax.validation.ConstraintValidator
接口:
public class MyValidator implements ConstraintValidator<MyConstraint, Object> {
@Override
public void initialize(MyConstraint constraintAnnotation) {
// 初始化
}
@Override
public boolean isValid(Object value, ConstraintValidatorContext context) {
// 校验逻辑
}
}
其中MyConstraint
是自定义注解,定义如下:
@Documented
@Constraint(validatedBy = MyValidator.class)
@Target({ElementType.TYPE, ElementType.FIELD, ElementType.PARAMETER})
@Retention(RetentionPolicy.RUNTIME)
public @interface MyConstraint {
String message() default "自定义校验错误";
Class<?>[] groups() default {};
Class<? extends Payload>[] payload() default {};
}
3. 在数据模型上添加校验注解
在数据模型上添加javax.validation.constraints
包下的注解,比如:
public class User {
@NotNull(message = "用户名不能为空")
@Size(min = 5, max = 10, message = "用户名长度必须在5到10之间")
private String username;
@Email(message = "邮箱格式不正确")
private String email;
@MyConstraint
private Object obj;
// getter和setter方法
}
其中,@NotNull
注解表示不能为空,@Size
注解表示长度限制,@Email
注解表示邮箱格式,@MyConstraint
表示自定义注解。
4. 在控制器中进行校验
在控制器中使用@Valid
注解对请求参数进行校验,比如:
@RestController
public class UserController {
@PostMapping("/users")
public String addUser(@Valid User user) {
// 如果校验失败,会抛出MethodArgumentNotValidException异常
// 处理异常的方式可以在全局使用@ControllerAdvice注解进行统一处理
return "success";
}
}
5. 自定义错误消息
可以在ValidationMessages.properties
文件中自定义错误消息,例如:
javax.validation.constraints.NotNull.message=用户名不能为空
javax.validation.constraints.Size.message=用户名长度必须在{0}到{1}之间
javax.validation.constraints.Email.message=邮箱格式不正确
com.example.demo.validation.constraints.MyConstraint.message=自定义校验错误
其中,{0}
和{1}
表示占位符,将在实际校验时被替换成注解中的参数。
示例一:校验请求参数
下面是一个校验请求参数的例子:
控制器:
@RestController
public class UserController {
@GetMapping("/users")
public String getUser(@RequestParam("id") @NotNull(message = "用户ID不能为空") Long id) {
return "success";
}
}
请求:
GET /users?id=
响应:
{
"timestamp": "2021-11-24T05:24:50.647+00:00",
"status": 400,
"error": "Bad Request",
"message": "参数错误",
"path": "/users"
}
示例二:校验数据模型
下面是一个校验数据模型的例子:
控制器:
@RestController
public class UserController {
@PostMapping("/users")
public String addUser(@Valid User user) {
return "success";
}
}
数据模型:
public class User {
@NotNull(message = "用户名不能为空")
@Size(min = 5, max = 10, message = "用户名长度必须在5到10之间")
private String username;
@Email(message = "邮箱格式不正确")
private String email;
// getter和setter方法
}
请求:
POST /users
{
"username": "test",
"email": "test"
}
响应:
{
"timestamp": "2021-11-24T05:34:32.690+00:00",
"status": 400,
"error": "Bad Request",
"message": "参数错误",
"path": "/users"
}
注:建议在控制器中使用javax.validation.ConstraintViolationException
类捕获校验失败的异常,并将异常信息返回到响应体中。可以自定义一个异常处理类,实现ResponseEntityExceptionHandler
接口,在其中重写handleMethodArgumentNotValid
方法,返回包含统一格式的响应体。
本站文章如无特殊说明,均为本站原创,如若转载,请注明出处:基于javax.validation结合spring的最佳实践 - Python技术站