- Published on
优雅的新增和更新实例
- Authors

- Name
- lzs39
优雅的新增和更新实例
使用 Hibernate Validator(Bean Validation 实现)对 DTO 参数进行校验的步骤如下:
1. 添加依赖(Maven)
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-validation</artifactId>
</dependency>
2. 在 DTO 字段上添加校验注解
import javax.validation.constraints.*;
import java.util.List;
public class UserDTO {
@NotBlank(message = "用户名不能为空")
@Size(min = 3, max = 20, message = "用户名长度需在3-20之间")
private String username;
@Email(message = "邮箱格式不正确")
private String email;
@NotNull(message = "年龄不能为空")
@Min(value = 18, message = "年龄需满18岁")
@Max(value = 100, message = "年龄不能超过100岁")
private Integer age;
@Pattern(regexp = "^(?=.*[A-Za-z])(?=.*\\d)[A-Za-z\\d]{8,}$",
message = "密码需至少8字符,包含字母和数字")
private String password;
@AssertTrue(message = "必须接受条款")
private Boolean acceptedTerms;
@NotEmpty(message = "角色不能为空")
private List<@NotBlank String> roles; // 嵌套校验
// 自定义对象校验(AddressDTO需有自己的校验注解)
@Valid
private AddressDTO address;
// Lombok 或手动生成 getter/setter
}
3. 在 Controller 方法中启用校验
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;
import javax.validation.Valid;
@RestController
@RequestMapping("/users")
public class UserController {
@PostMapping
public ResponseEntity<?> createUser(@RequestBody @Valid UserDTO userDTO) {
// 业务逻辑
return ResponseEntity.ok("校验通过");
}
// 校验路径变量
@GetMapping("/{id}")
public ResponseEntity<?> getUser(
@PathVariable @Min(1) Long id, // 直接校验基本类型
@RequestParam @NotBlank String token) {
return ResponseEntity.ok("校验通过");
}
}
4. 处理校验异常(全局异常处理)
import org.springframework.validation.FieldError;
import org.springframework.web.bind.MethodArgumentNotValidException;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.ResponseStatus;
import org.springframework.web.bind.annotation.RestControllerAdvice;
import org.springframework.http.HttpStatus;
@RestControllerAdvice
public class GlobalExceptionHandler {
@ResponseStatus(HttpStatus.BAD_REQUEST)
@ExceptionHandler(MethodArgumentNotValidException.class)
public Map<String, String> handleValidationExceptions(
MethodArgumentNotValidException ex) {
Map<String, String> errors = new HashMap<>();
ex.getBindingResult().getAllErrors().forEach(error -> {
String fieldName = ((FieldError) error).getField();
String errorMessage = error.getDefaultMessage();
errors.put(fieldName, errorMessage);
});
return errors;
}
}
5. 自定义校验器(示例:手机号校验)
// 自定义注解
@Target({FIELD})
@Retention(RUNTIME)
@Constraint(validatedBy = PhoneValidator.class)
public @interface ValidPhone {
String message() default "手机号格式不正确";
Class<?>[] groups() default {};
Class<? extends Payload>[] payload() default {};
}
// 校验逻辑实现
public class PhoneValidator implements ConstraintValidator<ValidPhone, String> {
private static final Pattern PHONE_PATTERN = Pattern.compile("^1[3-9]\\d{9}$");
@Override
public boolean isValid(String phone, ConstraintValidatorContext context) {
return phone != null && PHONE_PATTERN.matcher(phone).matches();
}
}
// 在DTO中使用
public class UserDTO {
@ValidPhone
private String phone;
}
6. 分组校验(按场景区分规则)
// 定义分组接口
public interface CreateGroup {}
public interface UpdateGroup {}
// DTO中使用分组
public class UserDTO {
@Null(groups = CreateGroup.class, message = "创建时ID必须为空")
@NotNull(groups = UpdateGroup.class, message = "更新时ID不能为空")
private Long id;
}
// Controller指定分组
@PostMapping("/create")
public ResponseEntity<?> create(@RequestBody @Validated(CreateGroup.class) UserDTO dto) {...}
常用校验注解:
| 注解 | 作用 |
| ------------------- | ------------------------------ |
| @NotNull | 值不能为 null |
| @NotBlank | 字符串不能为空(trim后长度>0) |
| @NotEmpty | 集合/数组不能为空 |
| @Size(min, max) | 检查字符串/集合大小 |
| @Min(value) | 数字最小值 |
| @Max(value) | 数字最大值 |
| @Email | 邮箱格式校验 |
| @Pattern(regexp) | 正则表达式匹配 |
| @Past / @Future | 日期过去/未来时间 |
| @Valid | 级联校验关联对象 |
注意事项:
- 嵌套校验:对嵌套对象使用
@Valid触发级联校验 - 集合校验:使用
List<@Valid YourDTO> list校验集合元素 - 分组校验:通过
@Validated(Group.class)实现不同场景不同规则 - 手动校验:非Controller层可用
Validator工具@Autowired Validator validator; Set<ConstraintViolation<Object>> violations = validator.validate(object);
提示:Spring Boot 2.3+ 需显式引入
spring-boot-starter-validation,旧版本已自动包含。