本文目录导读:

我来为你提供一个完整的Java全局校验封装方案,包括多种实现方式:
基于Spring框架的全局校验封装
1 自定义注解
import javax.validation.Constraint;
import javax.validation.Payload;
import java.lang.annotation.*;
@Target({ElementType.FIELD, ElementType.PARAMETER})
@Retention(RetentionPolicy.RUNTIME)
@Constraint(validatedBy = PhoneValidator.class)
@Documented
public @interface ValidPhone {
String message() default "手机号格式不正确";
Class<?>[] groups() default {};
Class<? extends Payload>[] payload() default {};
}
2 自定义校验器
import javax.validation.ConstraintValidator;
import javax.validation.ConstraintValidatorContext;
import java.util.regex.Pattern;
public class PhoneValidator implements ConstraintValidator<ValidPhone, String> {
private static final String PHONE_REGEX = "^1[3-9]\\d{9}$";
@Override
public boolean isValid(String phone, ConstraintValidatorContext context) {
if (phone == null || phone.isEmpty()) {
return true; // 交给@NotNull处理
}
return Pattern.matches(PHONE_REGEX, phone);
}
}
全局异常处理封装
1 通用响应类
import lombok.Data;
import java.io.Serializable;
@Data
public class ApiResponse<T> implements Serializable {
private Integer code;
private String message;
private T data;
private Long timestamp;
public ApiResponse() {
this.timestamp = System.currentTimeMillis();
}
public static <T> ApiResponse<T> success(T data) {
ApiResponse<T> response = new ApiResponse<>();
response.setCode(200);
response.setMessage("success");
response.setData(data);
return response;
}
public static <T> ApiResponse<T> error(Integer code, String message) {
ApiResponse<T> response = new ApiResponse<>();
response.setCode(code);
response.setMessage(message);
return response;
}
}
2 自定义异常类
import lombok.Getter;
@Getter
public class BusinessException extends RuntimeException {
private Integer code;
public BusinessException(Integer code, String message) {
super(message);
this.code = code;
}
public BusinessException(String message) {
super(message);
this.code = 500;
}
}
3 全局异常处理器
import org.springframework.http.HttpStatus;
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 javax.validation.ConstraintViolation;
import javax.validation.ConstraintViolationException;
import java.util.stream.Collectors;
@RestControllerAdvice
public class GlobalExceptionHandler {
// 处理参数校验异常
@ExceptionHandler(MethodArgumentNotValidException.class)
@ResponseStatus(HttpStatus.BAD_REQUEST)
public ApiResponse<Void> handleValidationExceptions(MethodArgumentNotValidException ex) {
String errorMessage = ex.getBindingResult().getFieldErrors()
.stream()
.map(FieldError::getDefaultMessage)
.collect(Collectors.joining(", "));
return ApiResponse.error(400, errorMessage);
}
// 处理单个参数校验异常
@ExceptionHandler(ConstraintViolationException.class)
@ResponseStatus(HttpStatus.BAD_REQUEST)
public ApiResponse<Void> handleConstraintViolation(ConstraintViolationException ex) {
String errorMessage = ex.getConstraintViolations()
.stream()
.map(ConstraintViolation::getMessage)
.collect(Collectors.joining(", "));
return ApiResponse.error(400, errorMessage);
}
// 处理业务异常
@ExceptionHandler(BusinessException.class)
@ResponseStatus(HttpStatus.BAD_REQUEST)
public ApiResponse<Void> handleBusinessException(BusinessException ex) {
return ApiResponse.error(ex.getCode(), ex.getMessage());
}
// 处理通用异常
@ExceptionHandler(Exception.class)
@ResponseStatus(HttpStatus.INTERNAL_SERVER_ERROR)
public ApiResponse<Void> handleException(Exception ex) {
return ApiResponse.error(500, "服务器内部错误: " + ex.getMessage());
}
}
参数校验工具类
import org.apache.commons.lang3.StringUtils;
import java.util.regex.Pattern;
public class ValidateUtils {
// 手机号正则
private static final String PHONE_REGEX = "^1[3-9]\\d{9}$";
// 邮箱正则
private static final String EMAIL_REGEX = "^[a-zA-Z0-9_-]+@[a-zA-Z0-9_-]+(\\.[a-zA-Z0-9_-]+)+$";
// 身份证正则
private static final String ID_CARD_REGEX = "^[1-9]\\d{5}(18|19|20)\\d{2}(0[1-9]|1[0-2])(0[1-9]|[12]\\d|3[01])\\d{3}[0-9Xx]$";
public static boolean isPhone(String phone) {
if (StringUtils.isBlank(phone)) {
return false;
}
return Pattern.matches(PHONE_REGEX, phone);
}
public static boolean isEmail(String email) {
if (StringUtils.isBlank(email)) {
return false;
}
return Pattern.matches(EMAIL_REGEX, email);
}
public static boolean isIdCard(String idCard) {
if (StringUtils.isBlank(idCard)) {
return false;
}
return Pattern.matches(ID_CARD_REGEX, idCard);
}
public static void validatePhone(String phone) {
if (!isPhone(phone)) {
throw new BusinessException(400, "手机号格式不正确");
}
}
public static void validateEmail(String email) {
if (!isEmail(email)) {
throw new BusinessException(400, "邮箱格式不正确");
}
}
}
DTO对象校验示例
1 基础校验
import lombok.Data;
import javax.validation.constraints.*;
import java.time.LocalDate;
@Data
public class UserCreateRequest {
@NotBlank(message = "用户名不能为空")
@Size(min = 2, max = 20, message = "用户名长度在2-20个字符之间")
private String username;
@NotBlank(message = "密码不能为空")
@Size(min = 6, max = 20, message = "密码长度在6-20个字符之间")
private String password;
@NotBlank(message = "手机号不能为空")
@ValidPhone(message = "手机号格式不正确")
private String phone;
@Email(message = "邮箱格式不正确")
private String email;
@NotNull(message = "年龄不能为空")
@Min(value = 1, message = "年龄最小为1")
@Max(value = 150, message = "年龄最大为150")
private Integer age;
@NotNull(message = "生日不能为空")
@Past(message = "生日必须是过去的时间")
private LocalDate birthday;
}
2 分组校验
import javax.validation.groups.Default;
public class ValidationGroups {
public interface Create extends Default {}
public interface Update extends Default {}
public interface Query extends Default {}
}
@Data
public class UserDTO {
@NotNull(groups = {Update.class}, message = "ID不能为空")
private Long id;
@NotBlank(groups = {Create.class}, message = "用户名不能为空")
private String username;
@NotBlank(groups = {Create.class}, message = "密码不能为空")
private String password;
@NotBlank(groups = {Create.class, Update.class}, message = "手机号不能为空")
@ValidPhone(groups = {Create.class, Update.class}, message = "手机号格式不正确")
private String phone;
}
Service层校验封装
import org.springframework.stereotype.Service;
import org.springframework.validation.annotation.Validated;
import javax.validation.Valid;
import javax.validation.constraints.NotNull;
@Service
@Validated
public class UserService {
public User createUser(@Valid @NotNull UserCreateRequest request) {
// 业务逻辑
return new User();
}
@Validated(ValidationGroups.Update.class)
public User updateUser(@Valid UserUpdateRequest request) {
// 业务逻辑
return new User();
}
}
高级校验器封装
import org.springframework.stereotype.Component;
import org.springframework.util.CollectionUtils;
import javax.validation.ConstraintViolation;
import javax.validation.Validator;
import java.util.Set;
import java.util.stream.Collectors;
@Component
public class ValidationHelper {
private final Validator validator;
public ValidationHelper(Validator validator) {
this.validator = validator;
}
public <T> void validate(T object) {
Set<ConstraintViolation<T>> violations = validator.validate(object);
if (!CollectionUtils.isEmpty(violations)) {
String errorMessage = violations.stream()
.map(ConstraintViolation::getMessage)
.collect(Collectors.joining(", "));
throw new BusinessException(400, errorMessage);
}
}
public <T> void validate(T object, Class<?>... groups) {
Set<ConstraintViolation<T>> violations = validator.validate(object, groups);
if (!CollectionUtils.isEmpty(violations)) {
String errorMessage = violations.stream()
.map(ConstraintViolation::getMessage)
.collect(Collectors.joining(", "));
throw new BusinessException(400, errorMessage);
}
}
}
使用示例
import org.springframework.web.bind.annotation.*;
@RestController
@RequestMapping("/users")
public class UserController {
@PostMapping
public ApiResponse<User> createUser(@Valid @RequestBody UserCreateRequest request) {
// 参数已自动校验
User user = userService.createUser(request);
return ApiResponse.success(user);
}
@GetMapping("/{id}")
public ApiResponse<User> getUser(@PathVariable @Min(value = 1, message = "ID必须大于0") Long id) {
User user = userService.getUser(id);
return ApiResponse.success(user);
}
@PostMapping("/validate")
public ApiResponse<String> manualValidate(@RequestBody UserCreateRequest request) {
// 手动调用校验
validationHelper.validate(request);
// 或者使用工具类
ValidateUtils.validatePhone(request.getPhone());
ValidateUtils.validateEmail(request.getEmail());
return ApiResponse.success("校验通过");
}
}
这个封装方案提供了:
- 声明式校验(@Valid注解)
- 自定义校验器
- 全局异常处理
- 分组校验
- 工具类支持
- 手动校验支持
可以根据项目需求选择合适的校验方式组合使用。
版权声明:足球直播
足球直播
足球直播
足球直播
足球直播
中超直播
中超直播
中超直播
中超直播
中超直播
英超直播
英超直播
英超直播
英超直播
英超直播
德甲直播
德甲直播
德甲直播
德甲直播
德甲直播
西甲直播
西甲直播
西甲直播
西甲直播
西甲直播
意甲直播
意甲直播
意甲直播
意甲直播
意甲直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
篮球直播
篮球直播
篮球直播
篮球直播
篮球直播
足球直播
足球直播
足球直播
足球直播
足球直播
中超直播
中超直播
中超直播
中超直播
中超直播
英超直播
英超直播
英超直播
英超直播
英超直播
德甲直播
德甲直播
德甲直播
德甲直播
德甲直播
西甲直播
西甲直播
西甲直播
西甲直播
西甲直播
意甲直播
意甲直播
意甲直播
意甲直播
意甲直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
篮球直播
篮球直播
篮球直播
篮球直播
篮球直播
足球直播
足球直播
足球直播
足球直播
足球直播
中超直播
中超直播
中超直播
中超直播
中超直播
英超直播
英超直播
英超直播
英超直播
英超直播
德甲直播
德甲直播
德甲直播
德甲直播
德甲直播
西甲直播
西甲直播
西甲直播
西甲直播
西甲直播
意甲直播
意甲直播
意甲直播
意甲直播
意甲直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
篮球直播
篮球直播
篮球直播
篮球直播
篮球直播