1.简介
JSR 303 是 Java Specification Request 303 的简称,它定义了一套 Java Bean Validation API,用于对 Java 应用中的 Bean(通常是指 POJOs,即 Plain Old Java Objects)进行声明式校验。JSR 303 为 Java 开发者提供了一套标准的校验注解,使得开发者可以非常方便地在 Bean 属性上声明校验规则,而不需要编写大量的校验代码。
JSR 303 的主要特点和组件包括:
-
校验注解:JSR 303 定义了一系列的校验注解,如
@NotNull
、@Size
、@Min
、@Max
、@Pattern
等,这些注解可以直接应用于 Java Bean 的属性上,以声明校验规则。 -
约束Violation:当校验失败时,JSR 303 会生成一系列的
ConstraintViolation
对象,每个对象包含有关违反约束的详细信息,如属性路径、违规值、错误消息等。 -
校验器(Validator):JSR 303 提供了一个
Validator
接口,用于执行实际的校验操作。开发者可以通过Validator
对象对 Bean 进行校验,并获取校验结果。 -
校验组(Validation Groups):JSR 303 支持校验组的概念,允许开发者将校验规则分组,以便在不同的场景下应用不同的校验规则。
-
自定义约束:除了使用标准的校验注解外,JSR 303 还允许开发者定义自己的校验注解和约束。
2实战
2.1 引入依赖
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-validation</artifactId>
</dependency>
2.2 创建exception类
2.2.1 CommonError通用异常处理类
package com.etc.shop.exception;
public enum CommonError {
UNKOWN_ERROR("执行过程异常,请重试。"),
PARAMS_ERROR("非法参数"),
OBJECT_NULL("对象为空"),
QUERY_NULL("查询结果为空"),
REQUEST_NULL("请求参数为空");
private String errMessage;
public String getErrMessage(){
return errMessage;
}
CommonError(String errMessage) {
this.errMessage = errMessage;
}
}
2.2.2 该系统的异常类ShopSystem
package com.etc.shop.exception;
public class ShopSystemException extends RuntimeException{
private String errMessage;
public ShopSystemException(){
super();
}
public ShopSystemException(String errMessage){
super(errMessage);
this.errMessage = errMessage;
}
public String getErrMessage(){
return errMessage;
}
public static void cast(CommonError commonError){
throw new ShopSystemException(commonError.getErrMessage());
}
public static void cast(String errMessage){
throw new ShopSystemException(errMessage);
}
}
2.2.3 响应请求的错误类
package com.etc.shop.exception;
import java.io.Serializable;
public class RestErrorResponse implements Serializable {
private String errMessage;
public RestErrorResponse(String errMessage){
this.errMessage = errMessage;
}
public String getErrMessage(){
return errMessage;
}
public void setErrMessage(String errMessage){
this.errMessage = errMessage;
}
}
2.2.4 GlobalException全局异常处理类
package com.etc.shop.exception;
import lombok.extern.slf4j.Slf4j;
import org.springframework.http.HttpStatus;
import org.springframework.web.bind.annotation.*;
@Slf4j
@ControllerAdvice
public class GlobalExceptionHandler {
@ResponseBody
@ExceptionHandler(ShopSystemException.class)
@ResponseStatus(HttpStatus.INTERNAL_SERVER_ERROR)
public RestErrorResponse customException(ShopSystemException e){
log.error("系统异常:{}",e.getErrMessage(),e);
String errMessage = e.getErrMessage();
RestErrorResponse restErrorResponse = new RestErrorResponse(errMessage);
return restErrorResponse;
}
@ResponseBody
@ExceptionHandler(Exception.class)
@ResponseStatus(HttpStatus.INTERNAL_SERVER_ERROR)
public RestErrorResponse exception(Exception e){
log.error("系统异常:{}",e.getMessage(),e);
RestErrorResponse restErrorResponse = new RestErrorResponse(CommonError.UNKOWN_ERROR.getErrMessage());
return restErrorResponse;
}
}
2.2.5 设置异常分组类
public class ValidationGroups {
public interface Insert{};
public interface Update{};
public interface Delete{};
}
2.3 对实体添加异常处理注解示例,以及分组示例
@Data
public class OrderDTO {
@NotEmpty(message = "订单上的商品不能为空")
private List<OrderItem> orderItems;
@NotEmpty(message = "订单上的总金额不能为空")
private BigDecimal totalAmount;
@NotEmpty(message = "接收人的姓名不能为空",groups = {ValidationGroups.Insert.class})
@NotEmpty(message = "更改后的接收人的姓名不能为空",groups = {ValidationGroups.Update.class})
private String receiverName;
@NotEmpty(message = "接收地址不能为空",groups = {ValidationGroups.Insert.class})
@NotEmpty(message = "更改后的接收地址不能为空",groups = {ValidationGroups.Update.class})
private String receiverAddress;
@NotEmpty(message = "接收人的手机号不能为空",groups = {ValidationGroups.Insert.class})
@NotEmpty(message = "更改后的接收人的手机号不能为空",groups = {ValidationGroups.Update.class})
private String receiverPhone;
}