3.3 數據驗證
前端傳入後端的數據需要進行驗證,前端的數據在Web界面中需要進行完全的驗證,那麼,還需要在後端進行驗證嗎?答案是需要的,因爲很容易繞過前端的驗證,如果這樣的數據被提交到後端,必然會產生相應的問題,因此,數據驗證,除了前端的驗證外,還需要在後端進行。
SpringMVC提供了驗證參數的機制,一方面,它可以支持JSR-303註解驗證,在默認的情況下,SpringBoot會引入關於Hibernate Validator機制來支持JSR-303驗證規範;另一方面,也可以自定義驗證規則。
3.3.1 JSR-303註解驗證
JSR-303驗證主要是通過註解的方式進行的,這裏在控制器開發的項目中,即上一次的項目中,在com.example.mybatisdemo.entity包下新建一個名稱爲Student的POJO,然後在其相關的屬性上添加註解。
1.首先在pom文件中添加依賴
<!--JSR-303依賴--> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-validation</artifactId> </dependency>
2.常用註解
@Null 被註釋的元素必須爲null @NotNull 被註釋的元素不能爲null @AssertTrue 被註釋的元素必須爲true @AssertFalse 被註釋的元素必須爲false @Min(value) 被註釋的元素必須是一個數字,其值必須大於等於指定的最小值 @Max(value) 被註釋的元素必須是一個數字,其值必須小於等於指定的最大值 @DecimalMin(value) 被註釋的元素必須是一個數字,其值必須大於等於指定的最小值 @DecimalMax(value) 被註釋的元素必須是一個數字,其值必須小於等於指定的最大值 @Size(max,min) 被註釋的元素的大小必須在指定的範圍內。 @Digits(integer,fraction) 被註釋的元素必須是一個數字,其值必須在可接受的範圍內 @Past 被註釋的元素必須是一個過去的日期 @Future 被註釋的元素必須是一個將來的日期 @Pattern(value) 被註釋的元素必須符合指定的正則表達式。 @Email 被註釋的元素必須是電子郵件地址 @Length 被註釋的字符串的大小必須在指定的範圍內 @NotEmpty 被註釋的字符串必須非空 @Range 被註釋的元素必須在合適的範圍內
3.在Student的類上添加相應的註解
package com.example.mybatisdemo.entity; import org.hibernate.validator.constraints.Range; import org.springframework.format.annotation.DateTimeFormat; import javax.validation.constraints.*; import java.util.Date; public class Student { @NotNull(message = "id不能爲空") private Integer id; @Size(min = 2,max = 8,message = "姓名長度要求2到8之間") private String name; @Size(max=30,message = "地址長度不能超過30") private String address; @Email(message = "郵箱格式錯誤") private String email; @Past(message = "日期錯誤")//只能是過去的日期 @DateTimeFormat(pattern = "yyyy-MM-dd") private Date birthday; @DecimalMin(value = "0.1")//最小值爲0.1 @DecimalMax(value = "100")//最大值爲100 private double score; @Range(min = 1,max = 150,message = "年齡必須爲1-150之間") private int age; }
4.創建控制器
在com.example.mybatisdemo.controller包下,新建ValidateController類。代碼如下:
package com.example.mybatisdemo.controller; import com.example.mybatisdemo.entity.Student; import org.springframework.stereotype.Controller; import org.springframework.validation.Errors; import org.springframework.validation.FieldError; import org.springframework.validation.ObjectError; import org.springframework.web.bind.annotation.RequestBody; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RequestMethod; import org.springframework.web.bind.annotation.ResponseBody; import javax.validation.Valid; import java.util.HashMap; import java.util.List; import java.util.Map; @Controller public class ValidateController { //返回前端頁面 @RequestMapping(value = "/datacheck/validateview",method = RequestMethod.GET) public String getValidateView(){ return "/datacheck/validateview"; } @RequestMapping(value = "/datacheck/validatedata",method = RequestMethod.POST) @ResponseBody public Map<String,Object> validateData(@Valid @RequestBody Student stu, Errors errors){ Map<String,Object> errMap=new HashMap<>(); //獲取錯誤列表 List<ObjectError> oes=errors.getAllErrors(); for (ObjectError oe : oes) { String key=null; String message=null; if(oe instanceof FieldError){ FieldError fe=(FieldError)oe; key=fe.getField();//獲取錯誤驗證字段名 }else{ key=oe.getObjectName();//獲取驗證對象名稱 } message=oe.getDefaultMessage(); errMap.put(key,message); } return errMap; } }
注意:必須在需要驗證的參數之前加上註解"@valid",否則不會驗證。該註解表示啓動驗證機制,Spring啓用JSR-303驗證機制後,會自動將最後的驗證結果放入Errors對象中,將數據返回給前端後,前端就可以得到相關驗證的信息。
5.創建前端頁面
在resources/templates/datacheck目錄下,新建validateview.html文件,頁面內容如下:
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>數據驗證</title> </head> <body> <button id="btn">數據驗證</button> <script src="/jquery.js" type="text/javascript"></script> <script> function sendMsg(){ var param={}; param["id"]=1; param["name"]="張三丰"; param["address"]="武當山"; param["email"]="[email protected]"; param["birthday"]="1990-10-21"; param["score"]=98.5; param["age"]=30; var jsondata=JSON.stringify(param); console.log(jsondata); $.ajax({ type:'POST', url:'/datacheck/validatedata', data:jsondata, async:false, contentType:'application/json', success:function(data){ alert("成功"+data); }, error:function(data){ alert("錯誤"+data); } }) } </script> </body> </html>
如果發送錯誤的數據,例如,將score更改爲9898.9,age修改爲300,則返回的結果是:
3.4 模型綁定
模型綁定指的是通過數據模型爲視圖綁定數據。本實例採用上例數據驗證中的模型類Student。
3.4.1 創建控制器
在controller包下的DemoController控制器類中,添加如下代碼:
@RequestMapping(value = "/demo/modelbind",method = RequestMethod.GET) public String studentModel(Model model){ Student stu=new Student(); stu.setId(1); stu.setName("張三丰"); stu.setAddress("武當山"); stu.setAge(108); stu.setBirthday(new Date()); stu.setEmail("[email protected]"); stu.setScore(89.5); model.addAttribute("stu",stu); model.addAttribute("msg","Hello"); return "/demo/model1"; }
3.4.2 創建視圖頁
視圖頁採用了 前端視圖引擎。需要注意的是
<html lang="en" xmlns:th="http://www.thymeleaf.org"> <
代碼如下:
<!DOCTYPE html> <html lang="en" xmlns:th="http://www.thymeleaf.org"> <head> <meta charset="UTF-8"> <title>模型綁定1</title> </head> <body> <table> <tr> <td>編號:</td> <td th:text="${stu.id}"></td> </tr> <tr> <td>姓名:</td> <td th:text="${stu.name}"></td> </tr> <tr> <td>地址:</td> <td th:text="${stu.address}"></td> </tr> <tr> <td>年齡:</td> <td th:text="${stu.age}"></td> </tr> <tr> <td>出生日期:</td> <td th:text="${stu.birthday}"></td> </tr> <tr> <td>電子郵件:</td> <td th:text="${stu.email}"></td> </tr> <tr> <td>武術成績:</td> <td th:text="${stu.score}"></td> </tr> </table> </body> </html>
啓動程序運行結果如下: