2.3 验证表单输入
2.3 验证表单输入
当设计一个新的
按照目前的情况,没有什么能阻止用户创建一个没有任何配料或空空如也的送货地址的玉米饼,甚至提交他们最喜欢的歌曲的歌词作为信用卡号码。这是因为还没有指定应该如何验证这些字段。
执行表单验证的一种方法是在
幸运的是,
要在
- 对要验证的类声明验证规则:特别是
Taco 类。 - 指定验证应该在需要验证的控制器方法中执行,具体来说就是:
DesignTacoController 的processDesign() 方法和OrderController 的processOrder() 方法。 - 修改表单视图以显示验证错误。
2.3.1 声明验证规则
对于
package tacos;
import java.util.List;
import javax.validation.constraints.NotNull;
import javax.validation.constraints.Size;
import lombok.Data;
@Data
public class Taco {
@NotNull
@Size(min=5, message="Name must be at least 5 characters long")
private String name;
@Size(min=1, message="You must choose at least 1 ingredient")
private List<String> ingredients;
}
你会发现,除了要求
当涉及到对提交玉米饼订单进行验证声明时,必须对
支付领域的验证是一个比较奇特的存在。你不仅需要确保
package tacos;
import javax.validation.constraints.Digits;
import javax.validation.constraints.Pattern;
import org.hibernate.validator.constraints.CreditCardNumber;
import javax.validation.constraints.NotBlank;
import lombok.Data;
@Data
public class Order {
@NotBlank(message="Name is required")
private String name;
@NotBlank(message="Street is required")
private String street;
@NotBlank(message="City is required")
private String city;
@NotBlank(message="State is required")
private String state;
@NotBlank(message="Zip code is required")
private String zip;
@CreditCardNumber(message="Not a valid credit card number")
private String ccNumber;
@Pattern(regexp="^(0[1-9]|1[0-2])([\\/])([1-9][0-9])$",
message="Must be formatted MM/YY")
private String ccExpiration;
@Digits(integer=3, fraction=0, message="Invalid CVV")
private String ccCVV;
}
可以看到,
不幸的是,没有现成的注释来验证
最后,用
所有的验证注释都包含一个消息属性,该属性定义了如果用户输入的信息不符合声明的验证规则的要求时将显示给用户的消息。
2.3.2 在表单绑定时执行验证
既然已经声明了应该如何验证
要验证提交的
@PostMapping
public String processDesign(@Valid Taco design, Errors errors) {
if (errors.hasErrors()) {
return "design";
}
// Save the taco design...
// We'll do this in chapter 3
log.info("Processing design: " + design);
return "redirect:/orders/current";
}
要对提交的
@PostMapping
public String processOrder(@Valid Order order, Errors errors) {
if (errors.hasErrors()) {
return "orderForm";
}
log.info("Order submitted: " + order);
return "redirect:/";
}
在这两种情况下,如果没有验证错误,则允许该方法处理提交的数据。如果存在验证错误,则请求将被转发到表单视图,以便用户有机会纠正其错误。
但是用户如何知道哪些错误需要改正呢?除非调出表单上的错误,否则用户将只能猜测如何成功提交表单。
2.3.3 显示验证错误
th:errors
属性提供了对
<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:if
属性来决定是否显示 。
th:errors
属性引用
如果在其他字段的订单表单周围使用类似的 标记,则在提交无效信息时可能会看到类似图
图
现在