Spring Validation
基本概念
一般的web application都是靠View進行輸入的驗證,然而,前端的驗證可能會因為瀏覽器的版本或java script被使用者停用而失效,所以,需要伺服器端的驗證,Spring Validation就是屬於伺服器端的驗證。
設定
要使用Spring Validation,請在pom.xml中的<dependencies></dependencies>中加入以下的設定,加完之後,就可以了。(Thymeleaf的設定請參閱Spring View)
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-validation</artifactId>
</dependency>
驗證規則
首先,驗證的規則在Model裡設定,例如,可以設定name與address不可以是空白且至少輸weight入一個字,最小值為0。請注意:如果變數的資料型態是文字,不能用Min或Max,如果變數的資料型態是數字,不能用Size。
package com.example.demo.entity;
import javax.validation.constraints.Min;
import javax.validation.constraints.NotNull;
import javax.validation.constraints.Size;
public class Customer {
@NotNull
@Size(min=1)
private String name;
@NotNull
@Size(min=1)
private String address;
@Min(0)
private int weight;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getAddress() {
return address;
}
public void setAddress(String address) {
this.address = address;
}
public int getWeight() {
return weight;
}
public void setWeight(int weight) {
this.weight = weight;
}
}
接下來,在Controller中,必須設定要去使用Model裡的validation,可以在model前(或@ModelAttribute前)加入@Valid,就會啟動model中的validation,另外,為了要取得驗證後的結果,加入BindingResult bindingResult。可以使用hasErrors()來處理錯誤。以下面的範例而言,就是將使用者導回原本的表單。
package com.example.demo.controller;
import javax.validation.Valid;
import org.springframework.stereotype.Controller;
import org.springframework.validation.BindingResult;
import org.springframework.web.bind.annotation.ModelAttribute;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.servlet.ModelAndView;
import com.example.demo.entity.Customer;
@Controller
public class CustomerController {
@RequestMapping(value = "/customerCreate", method = RequestMethod.GET)
public ModelAndView openForm(Customer customer) {
ModelAndView model = new ModelAndView("customerCreate");
model.addObject(customer);
return model;
}
@RequestMapping(value = "/customerCreate", method = RequestMethod.POST)
public ModelAndView processForm(@Valid @ModelAttribute Customer customer, BindingResult bindingResult) {
ModelAndView model = new ModelAndView("customerDone");
if (bindingResult.hasErrors()) {
model = new ModelAndView("customerCreate");
return model;
}
model.addObject(customer);
return model;
}
}
前面的View (表單),可以顯示錯誤訊息。可以使用fields.hasErrors('name'),了解是否name這個欄位有錯誤,利用errors="*{name}",可以顯示這個欄位的錯誤訊息。因為前面的controller將所有變數包在customer中,為了不需要一直指定customer,thymeleaf可以使用th:object="${customer}",後面就可以直接使用*{name},否則就必須使用${customer.name},如以下範例。
<!DOCTYPE html>
<html lang="en" xmlns:th="http://www.thymeleaf.org">
<head>
<meta charset="UTF-8"/>
<title>Create New Customer</title>
</head>
<body>
<form action="customerCreate" th:object="${customer}" method ="post">
name:<input type="text" name="name" th:field="*{name}"/><br/>
<div th:if="${#fields.hasErrors('name')}" th:errors="*{name}"></div>
address:<input type="text" name = "address" th:field="*{address}"/><br/>
<div th:if="${#fields.hasErrors('address')}" th:errors="*{address}"></div>
weight:<input type="text" name ="weight" th:field="*{weight}"/><br/>
<div th:if="${#fields.hasErrors('weight')}" th:errors="*{weight}"></div>
<input type="submit" value="Submit"/>
</form>
</body>
</html>
客製訊息
Spring Validation會提供標準的錯誤訊息,這些訊息也可以被客製,如以下範例。不過,為了能提供多語系功能,建議利用message.properties (詳參:http://spr.com/part-4-internationalization-in-spring-boot/ )
@NotNull
@Size(min=1, message="不能是空白")
private String name;
@NotNull
@Size(min=1, message="不能是空白")
private String address;
@Min(value=0, message="必須大於0")
private int weight;
當我們在應該輸入數字的欄位中留空白時,會產生typeMismatch的錯誤,如果要客製那部份的錯誤訊息,可以進行以下的設定。
在application.properties裡新增:
spring.messages.basename=messages
spring.messages.encoding=UTF-8
新增/src/main/resource/messages.properties,並放入以下內容 (對應的中文字內容是「 必須是個整數」) (詳參: https://en.wikipedia.org/wiki/.properties )。
typeMismatch.int=\u5FC5\u9808\u662F\u500B\u6574\u6578
typeMismatch.java.lang.Integer=\u5FC5\u9808\u662F\u500B\u6574\u6578
參考資料
- https://spring.io/guides/gs/validating-form-input/
- http://www.thymeleaf.org/doc/tutorials/2.1/thymeleafspring.html#validation-and-error-messages
- https://docs.spring.io/spring/docs/current/spring-framework-reference/html/validation.html
- https://teamtreehouse.com/library/displaying-validation-messages
- REST