This commit is contained in:
2025-02-13 14:31:40 +08:00
parent 8bfc885370
commit 39fea53675
2 changed files with 779 additions and 138 deletions

View File

@ -2,8 +2,6 @@
JSR303是Java为Bean数据合法性校验提供给的标准框架已经包含在 JavaEE6.0 中、JSR303通过在Bean 属性中标注类似 @NotNull @Max 等标准的注解指定校验规则并通过标准的验证接口对 Bean进行验证
### 注解
### JSR303中含有的注解
@ -36,142 +34,21 @@
HIbernate Validator是JSR303的一个参考实现除了支持所有标准的校验注解外另外HIbernate Validator还有JSR-380的实现
```
### SpringMVC中使用JSR303进行服务器端验证
### 静态工具 手动校验BEAN
ValidatorFactory factory = Validation.buildDefaultValidatorFactory();
Validator validator = factory.getValidator();
a. 添加相关依赖
<dependency>
<groupId>org.hibernate</groupId>
<artifactId>hibernate-validator</artifactId>
<version>6.0.7.Final</version>
</dependency>
b. 给校验对象的指定属性添加校验规则
public class User {
private Long userId;
@NotBlank(message = "用户名不能为空")
private String userName;
@NotBlank(message = "密码不能为空")
private String userPwd;
............
}
c. 在请求处理方法中,使用@Validated或@Valid注解要验证的对象并根据BindingResult判断校验是否通过 另外验证参数后必须紧跟BindingResult参数否则spring会在校验不通过时直接抛出异常
public String login(@Validated @ModelAttribute User user,
BindingResult bindingResult){
// 服务器端校验不通过
if (bindingResult.hasErrors()) {
return "login";
}
....
}
AirportDTO dto = new AirportDTO();
dto.setIataCode("PKX");
dto.setThroughput("-1"); // 符合条件
// data.setValue(1234567.789); // 不符合条件整数部分超过6位
// data.setValue(123456.78901); // 不符合条件小数部分超过4位
// data.setValue(-123.45); // 不符合条件小于0
注1@Valid和Validated的区别,随便使用哪个都行
@Valid是使用hibernate validation的时候使用
@Validated 是只用spring Validator校验机制使用
### 在JSP页面上通过form标签显示消息
<form:errors path="*" /> 显示表单所有错误
<form:errors path="user* /> 显示所有以user为前缀的属性对应的错误
<form:errors path="username"/> 显示特定表单对象属性的错误
delimiter如果一个属性有多个错误错误信息的分隔符。默认是换行
注1errors标签要放到form标签中才能显示错误消息
注2如果使用form:errors标签不显示错误消息请检查Model中是否已经添加了命令对象没有是不会显示错误消息的
注3注意命名规范Book-->book
@ModelAttribute
public void init(Model model) {
System.out.println("init...");
model.addAttribute("user", new User());
}
### 通过BindingResult和form:errors标签在JSP页面显示非验证消息
public String login(@Valid @ModelAttribute Yh yh, BindingResult bindingResult, Model model){
bindingResult.rejectValue("yhzh", null, "帐号错误");
...
}
bindingResult.rejectValue("email", "validate.email.empty", "邮箱不能为空");//这个函数有好几个重载的变体
它们是可以支持国际化的。 比如,上面这个例子表示, 错误的字段(filed)是“email” errorCode是“validate.email.empty” 与资源文件对应, 第三个是defaultMessage
作业1从BindingResult对象获得错误消息生成基于json字符串返回到客户端
如何实现分组校验
2.1 通过接口定义若干个分组
2.2 给校验对象的指定属性添加校验规则,并指定校验组
2.3 在请求处理方法中,使用@Validated标记要验证的对象,并指定校验组
还可以对验证进行分组(@Validated)
public class Book {
// 书本验证分组
public static interface ValidateGroups {
// 新增/修改
public static interface AddEdit {
}
// 上架/下架
public static interface DeployUndeploy {
}
// 更新封面
public static interface UpdateBookImage {
}
}
private Long bookId;
@NotBlank(message = "书名不能为空", groups = { AddEdit.class })
private String bookName;
private String bookNamePinyin;
@NotNull(message = "类别不能为空", groups = { AddEdit.class })
private Long bookCategoryId;
@NotBlank(message = "作者不能为空", groups = { AddEdit.class })
private String bookAuthor;
@NotNull(message = "价格不能为空", groups = { AddEdit.class })
@Min(value = 1, message = "价格不能为负")
private Double bookPrice;
private Long bookImage;
@NotBlank(message = "出版社不能为空", groups = { AddEdit.class })
private String publishing;
@NotBlank(message = "简介不能为空", groups = { AddEdit.class })
private String bookDesc;
private Integer bookState;
private Date deployDatetime;
private Integer salesVolume;
}
@RequestMapping("/add")
public String add(
@Validated(value = Book.BookGroups.Add.class) @ModelAttribute Book book,
BindingResult bindingResult) {
if (bindingResult.hasErrors()) {
return "admin/addBook";
}
return "admin/addBook";
}
3. 通过分组来指定顺序
@GroupSequence({First.class, Second.class, User.class})
Set<ConstraintViolation<AirportDTO>> validate = validator.validate(dto,Update.class);
for (ConstraintViolation<AirportDTO> violation : validate) {
System.out.println(violation.getMessage());
}
}