在Spring MVC中提供了驗證器可以進行服務端校驗,所有的驗證都必須先注冊校驗器,不過校驗器也是Spring MVC自動加載的,在使用Spring MVC校驗器之前首先要下載相關的jar包,下面是我的一些jar所對應的maven依賴:
1 <!-- 驗證器所需的包 --> 2 <dependency> 3 <groupId>com.fasterxml</groupId> 4 <artifactId>classmate</artifactId> 5 <version>1.4.0</version> 6 </dependency> 7 8 <dependency> 9 <groupId>org.jboss.logging</groupId> 10 <artifactId>jboss-logging</artifactId> 11 <version>3.3.2.Final</version> 12 </dependency> 13 14 <dependency> 15 <groupId>org.hibernate.validator</groupId> 16 <artifactId>hibernate-validator</artifactId> 17 <version>6.0.13.Final</version> 18 </dependency> 19 20 <dependency> 21 <groupId>javax.validation</groupId> 22 <artifactId>validation-api</artifactId> 23 <version>2.0.1.Final</version> 24 </dependency>
其中:
- validator-api-*:提供關於驗證注解的;
- hibernate-validator-*:是通過hibernate校驗規則的包,他還要依賴classmate和jboss-logging這兩個包;
Spring MVC中有兩種校驗方式,一種是使用JSR 303注解驗證輸入內容,另一種是使用校驗器。
一、使用JSR 303注解驗證輸入內容
spring提供了對bean的校驗功能,通過注解@Valid表明對哪個Bean需要啟用注解式校驗。這種方式可以用來對字段進行非空、合法性等的校驗,它還提供了一些校驗規則約束:
Bean Validate中提供的約束有以下幾種:
Hibernate中也提供了一些約束:
具體內容可參考這個網站:
https://www.ibm.com/developerworks/cn/java/j-lo-jsr303/
二、使用校驗器
有時候除了合法性校驗之外,還需要進行一些業務邏輯校驗,比如用戶名不能重復等,這就需要使用校驗器來完成。使用校驗器需要進行兩步操作:
1、完成校驗器:SpringMVC提供了一個validator接口,我們只要實現這個接口中的方法即可;
2、綁定到控制器:創建完了校驗器之后要告訴容器需要校驗哪個控制器,所以需要將校驗器和控制器綁定,綁定的方法很簡單,就是在控制器中寫一個方法並使用注解@InitBinder即可。
下面結合這兩種校驗方式寫一個例子說明。
三 、實例
1、創建一個表單
這個表單用來輸入一些信息
<form id="paramForm" action="<%=basePath%>customer/addCustomer" method="post"> <table> <tr> <td>用戶名:</td> <td><input type="text" name="cusName" id="input_cus_name" value=""></td> </tr> <tr> <td>用戶年齡:</td> <td><input type="text" name="cusAge" id="input_cus_age" value=""></td> </tr> <tr> <td>用戶性別:</td> <td><label for="input_cus_sex1">男</label><input type="radio" name="cusSex" id="input_cus_sex1" value="1"><label for="input_cus_sex0">女</label><input type="radio" name="cusSex" id="input_cus_sex0" value="0"></td> </tr> <tr> <td>手機號碼:</td> <td><input type="text" name="cusPhone" id="input_cus_phone" value=""></td> </tr> <tr> <td>郵箱地址:</td> <td><input type="text" name="cusEmail" id="input_cus_email" value=""></td> </tr> <tr> <td></td> <td style="text-align: right;"><input type="submit" value="提交" id="addCustomer"></td> </tr> </table> </form>
因為向后台傳的是個pojo對象,所以name名稱要和pojo對象屬性保持一致。
2、創建表單中數據對應的pojo,並使用JSR 303校驗字段
public class Customer { private Integer cusId; @NonNull @Pattern(regexp = "^([a-zA-Z]*[0-9_-]*$)", message = "只能包含字母、數字、下划線,且不能以數字或下划線開頭") @Size(min = 8, max = 128) private String cusName; @NotNull @Min(18) @Max(40) private Integer cusAge; @NotNull private Integer cusSex; @NotNull @Size(min = 6, max = 11) @Pattern(regexp = "^((13[0-9])|(14[5,7])|(15[0-3,5-9])|(17[0,3,5-8])|(18[0-9])|166|198|199|(147))\\d{8}$", message = "請輸入正確的手機號") private String cusPhone; @NotNull @Size(min = 10, max = 20) @Pattern(regexp = "^[a-zA-Z0-9_.-]+@[a-zA-Z0-9-]+(\\.[a-zA-Z0-9-]+)*\\.[a-zA-Z0-9]{2,6}$", message = "請輸入正確的電子郵箱") private String cusEmail; public Integer getCusId() { return cusId; } public void setCusId(Integer cusId) { this.cusId = cusId; } public String getCusName() { return cusName; } public void setCusName(String cusName) { this.cusName = cusName == null ? null : cusName.trim(); } public Integer getCusAge() { return cusAge; } public void setCusAge(Integer cusAge) { this.cusAge = cusAge; } public Integer getCusSex() { return cusSex; } public void setCusSex(Integer cusSex) { this.cusSex = cusSex; } public String getCusPhone() { return cusPhone; } public void setCusPhone(String cusPhone) { this.cusPhone = cusPhone == null ? null : cusPhone.trim(); } public String getCusEmail() { return cusEmail; } public void setCusEmail(String cusEmail) { this.cusEmail = cusEmail == null ? null : cusEmail.trim(); } }
上面紅色加粗的部分就是使用JSR 303中的約束規則。
3、創建校驗器
這個校驗器用來判斷輸入的用戶名是不是Administrator,如果是則校驗不通過,並給出提示,否則校驗成功;
public class CustomerValidator implements Validator { /** * 檢驗驗證對象是不是Customer類,如果是則進行檢驗 */ @Override public boolean supports(Class<?> target) { return Customer.class.equals(target); } /** * 校驗用戶名是否已經存在 */ @Override public void validate(Object target, Errors errors) { Customer customer = (Customer) target; String name = customer.getCusName(); if (name.equals("Administrator")) { errors.rejectValue("cusName", null, "該賬號已被使用!"); } } }
創建校驗器時只要實現Validator接口並重寫對應的方法即可,supports方法是用來判定要校驗的bean類型,validate方法用來完成校驗邏輯。
4、創建控制器
@Controller @RequestMapping("/customer") public class CustomerController { @Autowired @Qualifier("customerService") CustomerService customerServiceImpl = null; /** * 綁定驗證器 * * @param dataBinder */ @InitBinder public void bindValidator(DataBinder dataBinder) { dataBinder.setValidator(new CustomerValidator()); } /** * customer首頁 * * @param mv * @param customer * @return */ @RequestMapping("index") public ModelAndView indexCustomer(ModelAndView mv, Customer customer) { mv.addObject("customer", customer); mv.setViewName("index"); mv.addObject("customer", customer); return mv; } @RequestMapping(value = "addCustomer", method = RequestMethod.POST) public ModelAndView validByAnnotation(@Valid Customer customer, Errors errors, RedirectAttributes redirectAttributes) { ModelAndView mv = new ModelAndView(); // 判斷是否存在錯誤 if (errors.hasErrors()) { List<FieldError> errorList = errors.getFieldErrors(); for (FieldError fieldError : errorList) { System.out.println("field:" + fieldError.getField() + ";errors:" + fieldError.getDefaultMessage()); } mv.addObject("errorList", errorList); mv.setView(new MappingJackson2JsonView()); } else { boolean insert = customerServiceImpl.addCustomer(customer); redirectAttributes.addFlashAttribute("customer", customer); if (insert) { mv.setViewName("redirect:./customer/index"); } else { mv.setViewName("redirect:./customer/error"); } } return mv; } /** * 出錯頁面 * * @param mv * @param customer * @return */ @RequestMapping("error") public ModelAndView errorInfo(ModelAndView mv, Customer customer) { mv.addObject("customer", customer); mv.setViewName("customer/error"); return mv; } }
這個控制器邏輯如下:
- 首先在方法bindValidator上使用注解@InitBinder完成校驗器和控制器的綁定;
- 然后使用注解@Valid對Customer進行校驗,這樣校驗器中就能通過第一個方法的判斷;
- 通過Error對象判斷是不是有錯誤,如果有錯誤代表校驗失敗,失敗后打印出失敗的信息並返回JDON視圖;
- 如果校驗成功則將數據保存在數據庫,保存時也判斷是否成功,保存成功則返回index頁面,否則返回error頁面
5、測試
先來測試JSR 303的校驗,首先在頁面輸入以下信息,輸入信息都是不通過校驗的:
返回信息如下:
其實就是校驗失敗的提示信息,我是直接返回JSON視圖的,所以說明JSR 303校驗生效了。下面輸入一些合法數據進行測試:
點擊提交之后的結果如下:
保存成功並進入index頁面,校驗成功。
下面測試校驗器功能,需要釋放綁定邏輯,輸入以下正確信息,並讓用戶名為Administrator
提交之后的結果如下:
從提示信息看出校驗器校驗沒用通過並給出提示信息,說明校驗通過了。
以上就是Spring MVC中對表單進行服務端校驗的內容。