import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
import lombok.experimental.Accessors;
import org.hibernate.validator.constraints.Length;
import org.hibernate.validator.constraints.Range;
import javax.validation.constraints.*;
import java.util.Date;
import java.util.List;
@Data
@NoArgsConstructor
@AllArgsConstructor
//setter 返回 {@code this} 而不是 {@code void}。
@Accessors(chain = true)
public class TestDto {
@NotNull(message = "id不能为空")
private String id;
@NotBlank(message = "姓名不能为空")
@Length(min = 1,max = 4, message = "用户名不能超过4个字符")
@Pattern(regexp = "^[\u4E00-\u9FA5A-Za-z0-9\*]*$", message = "用户昵称限制:最多4个字符,包含文字、字母和数字")
private String name;
@NotBlank(message = "手机号不能为空")
@Pattern(regexp = "^[1][3,4,5,6,7,8,9][0-9]{9}$", message = "手机号格式有误")
private String mobile;
@NotBlank(message = "联系邮箱不能为空")
@Email(message = "邮箱格式不对")
private String email;
@Future(message = "时间必须是将来时间")
private Date createTime;
// 销售日期(格式:yyyy-MM-dd)
@Length(max = 20, message = "autoBoughtTime不超过{max}个字符")
@Pattern(regexp = "^\d{4}-\d{2}-\d{2}$", message = "autoBoughtTime格式必须为yyyy-MM-dd")
private String autoBoughtTime;
@Range(min = 60,max = 80,message = "年龄必须要60到80之间,60=<年龄=<80")
private int age;
@Pattern(regexp = "^(\d{18,18}|\d{15,15}|(\d{17,17}[x|X]))$", message = "身份证格式错误")
private String idCard;
@NotNull(message = "list不能为空")
@Size(min = 1, message = "list大小不可为0")
private List list;
}
依赖
hibernate-validator和validation-api
org.hibernate.validator hibernate-validator 6.0.14.Final compile javax.validation validation-api 2.0.1.Final compile
如果已经有了spring-boot-starter-web,就不用再单独引入了
构建校验器,对参数做检验
import javax.validation.ConstraintViolation;
import javax.validation.Validation;
import javax.validation.Validator;
import java.util.Iterator;
import java.util.Set;
public class ValidatorUtils {
private ValidatorUtils() { }
private static Validator validator;
static {
validator = Validation.buildDefaultValidatorFactory().getValidator();
}
public static void validateEntity(Object object, Class>... groups) throws RRException {
Set> constraintViolations = validator.validate(object, groups);
if (!constraintViolations.isEmpty()) {
Iterator> iterator = constraintViolations.iterator();
StringBuilder msg = new StringBuilder();
while (iterator.hasNext()) {
ConstraintViolation
自定义的异常类
public class RRException extends RuntimeException{
private String msg;
private int code = 500;
public RRException(String msg) {
super(msg);
this.msg = msg;
}
public RRException(String msg, Throwable e) {
super(msg, e);
this.msg = msg;
}
public RRException(String msg, int code) {
super(msg);
this.msg = msg;
this.code = code;
}
public RRException(String msg, int code, Throwable e) {
super(msg, e);
this.msg = msg;
this.code = code;
}
public String getMsg() {
return msg;
}
public void setMsg(String msg) {
this.msg = msg;
}
public int getCode() {
return code;
}
public void setCode(int code) {
this.code = code;
}
}
单元测试校验
@Test
public void validateTestDto() {
TestDto dto = new TestDto();
dto.setId("123");
dto.setName("张三李四");
dto.setAge(80);
dto.setMobile("123");
dto.setEmail("456");
dto.setList(new ArrayList<>());
ValidatorUtils.validateEntity(dto);
}
这里会根据我们的注解顺序做校验,1,不能为空2.字符串长度3.格式是否正确
post请求,参数前加上@Valid就会触发校验器校验参数
@PostMapping(value = "/validator")
public Response testValidator(@RequestBody @Valid TestDto testDto){
return Response.ok();
}
上面例子中使用的Response 以及异常的统一处理可以参考
https://blog.csdn.net/m0_51527921/article/details/125223999



