SSR场景下,使用SpringValidation完成属性验证
个人之前接触的都是前后端分离的架构,Validation的工作是直接在前端完成的。在Spring实战这本书中作者一开始做的是SSR项目,其使用了SpringValidation完成属性验证。这是我第一次看到这种方式,所以记录一下。
步骤
- 添加依赖
- 在需要验证的类上添加注解,声明验证的规则
- 在需要实施验证的地方添加@Valid注解
- 在SRR的页面上添加错误信息
书本中的SSR项目 TacoCloud的例子
添加依赖
1
2
3
4
5
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-validation</artifactId>
</dependency>
在Taco和TacoOrder上添加注解
代码太多了,就不贴了,主要用到了这几个注解
- @NotNull, @NotBlank 两者都是用来验证字符串的,但是@NotBlank会忽略空格
- @Size 用来验证元素的个数,例如String的字符数,List的元素个数
- @Digits 用来验证数字的位数,可以细分到整数位数和小数位数
- @Pattern 用来验证字符串的格式,可以使用正则表达式
还有一个是@CreditCardNumber,用来验证信用卡号的,但是这个注解是hibernate-validator提供的拓展注解,不属于JavaBean Validation规范的一部分。不过SpringValidation默认添加了hibernate-validator的实现,所以可以直接使用,不需要额外添加依赖。
在Controller接受Taco和TacoOrder的地方添加@Valid注解
这一步骤是必要的,不然不会触发验证
具体的代码如下
1
2
3
4
5
6
7
8
9
10
11
@PostMapping
public String processTaco(@Valid @ModelAttribute("taco") Taco taco, Errors errors) {
if (errors.hasErrors()) {
return "design";
}
// Save the taco...
// We'll do this in chapter 3
log.info("Processing taco: " + taco);
return "redirect:/orders/current";
}
在方法参数中,Taco前面添加了@Valid注解,这样Spring就会在调用这个方法之前,对Taco进行验证。验证的结果会被放到Errors对象中,然后我们可以根据Errors对象中的hasErrors() 方法来判断是否有错误。
在页面模板上显示错误信息
在之前的控制器中,如果验证失败,还是会返回到design页面,所以我们需要在design页面上显示错误信息.
SSR的页面模板是Thymeleaf,所以我们用到了Thymeleaf的错误信息显示功能 th:errors
1
2
3
4
5
<label for="ccNumber">Credit Card #: </label>
<input type="text" th:field="*{ccNumber}"/>
<span class="validationError"
th:if="${#fields.hasErrors('ccNumber')}"
th:errors="*{ccNumber}">CC Num Error</span>
th:errors 属性引用 ccNumber 字段,并且假设该字段存在错误,它将用验证消息替换 元素的占位符内容。
思考,这种方式的问题
其实本质上还是SSR的问题,不管参数合法与否,请求都会被发送,Validation都会在后端进行验证,这样会增加服务器的压力。
TradeOff换来的优点是否值得我还不清楚, 当然,这不是最佳实践的讨论,这只是书中的教学案例,我目前还没看到书中后面的地方,不知道作者是怎么处理的。
This post is licensed under CC BY 4.0 by the author.