上一篇文章我們了解了Spring Boot Web相關(guān)的知識(shí),初步了解了spring-boot-starter-web,還了解了@Contrler和@RestController的差別,如果使用@Controller注解只返回?cái)?shù)據(jù)則需要使用@ResponseBody注解。與此同時(shí)還了解了@RequestMapping注解與URL映射,URL映射可以分為URL路徑匹配、Method匹配、consumes和produces匹配、params和header匹配。這篇文章我們將會(huì)介紹數(shù)據(jù)校驗(yàn),對(duì)于任何應(yīng)用系統(tǒng)而言,任何客戶端傳入的數(shù)據(jù)都不是絕對(duì)安全有效的,這就要求我們?cè)诜?wù)端接收到數(shù)據(jù)時(shí)需要對(duì)傳入的數(shù)據(jù)的有效性進(jìn)行驗(yàn)證,以確保傳入的數(shù)據(jù)安全正確。
Hibernate Validator簡(jiǎn)介
目前數(shù)據(jù)校驗(yàn)的規(guī)范和組件有很多,Spring Boot默認(rèn)使用的數(shù)據(jù)校驗(yàn)組件是基于JSR數(shù)據(jù)校驗(yàn)規(guī)范的Hibernate Validator,其中常用的注解如下表所示
注解 | 作用目標(biāo) | 檢查規(guī)則 |
---|---|---|
@NotNull | 屬性 | 檢查值是否為空 |
@Null | 屬性 | 檢查值必須為空 |
@AsserFalse | 屬性 | 檢查演算結(jié)果是否為false |
@AssertTrue | 屬性 | 檢查演算結(jié)果是否為true |
@Max(value=) | 屬性(以numeric或string類型表示一個(gè)數(shù)字) | 檢查值是否小于或等于最大值 |
@Min(value=) | 屬性(以numeric或string類型表示一個(gè)數(shù)字) | 檢查值是否大于或等于最小值 |
@Size(min=, max=) | 屬性(array,collection,map) | 檢查元素大小是否在最大值和最小值之間(包括臨界值) |
@Digits(integer,fraction) | 屬性 | 檢查元素必須是數(shù)字且在范圍內(nèi) |
@Past | 屬性(data或calender) | 檢查日期是否是過(guò)去的日期 |
@Feature | 屬性data或calender) | 檢查日期是否是未來(lái)的日期 |
@Pattern(regex="rexgex",flag=) | 屬性 | 檢查值是否與正則表達(dá)式匹配 |
@Range(min=,max=) | 屬性(以numeric或string類型表示一個(gè)數(shù)字) | 檢查元素大小是否在最大值和最小值之間(包括臨界值) |
@Length(min=,max=) | 屬性(String) | 檢查字符串長(zhǎng)度是否符合范圍 |
屬性(String) | 檢查是否是有效的Email地址 | |
@NotEmpty | 屬性(String) | 檢查字符串不能為空 |
使用Hibernate Validator校驗(yàn)數(shù)據(jù)需要定義一個(gè)接受的數(shù)據(jù)模型,使用注解的形式描述字段的校驗(yàn)規(guī)則,下面以User對(duì)象為例說(shuō)明如何校驗(yàn)數(shù)據(jù),先加入以下依賴:
<dependency>
<groupId>org.springframework.boot<span class="hljs-name"groupId>
<artifactId>spring-boot-starter-validation<span class="hljs-name"artifactId>
<span class="hljs-name"dependency>
JavaBean參數(shù)校驗(yàn)
Post請(qǐng)求參數(shù)較多時(shí)可以在對(duì)應(yīng)的數(shù)據(jù)模型(Java Bean)中進(jìn)行校驗(yàn),通過(guò)注解來(lái)指定字段校驗(yàn)的規(guī)則。
public class User {
@NotBlank(message = "姓名不允許為空")
@Length(min = 2, max = 10, message = "姓名長(zhǎng)度錯(cuò)誤,姓名長(zhǎng)度2-10")
private String Name;
@NotNull(message = "年齡不能為空!")
@Min(18)
private int age;
@NotBlank(message = "地址不能為空!")
private String address;
@Email(message = "郵箱格式錯(cuò)誤")
private String email;
//省略get和set方法
}
上述例子中,每個(gè)message是數(shù)據(jù)校驗(yàn)不通過(guò)時(shí)要給出的提示信息。然后需要添加數(shù)據(jù)校驗(yàn)方法。
@PostMapping(path = "/check")
public String check(@RequestBody @Valid User user, BindingResult result) {
String name = user.getName();
if (result.hasErrors()) {
List
上面例子中BindingResult是驗(yàn)證不通過(guò)的結(jié)果集合,必須跟在被校驗(yàn)參數(shù)后,若被校驗(yàn)參數(shù)之后沒(méi)有BindingResult則會(huì)拋出BindException異常。
JavaBean對(duì)象的級(jí)聯(lián)校驗(yàn)
在對(duì)象的普通屬性上我們可以直接使用注解進(jìn)行數(shù)據(jù)校驗(yàn),對(duì)于關(guān)聯(lián)對(duì)象也很容易,在關(guān)聯(lián)對(duì)象上添加@Valid注解,關(guān)聯(lián)對(duì)象內(nèi)部可以正常使用數(shù)據(jù)校驗(yàn)注解。代碼如下:
public class User {
@NotBlank(message = "姓名不允許為空")
@Length(min = 2, max = 10, message = "姓名長(zhǎng)度錯(cuò)誤,姓名長(zhǎng)度2-10")
private String Name;
@NotNull(message = "年齡不能為空!")
@Min(18)
private int age;
@NotBlank(message = "地址不能為空!")
private String address;
@Email(message = "郵箱格式錯(cuò)誤")
private String email;
@NotNull(message = "detail不能為空")
@Valid
private UserDetail detail;
//省略get和set方法
}
public class UserDetail {
@NotNull(message = "id不能為空")
private String id;
public String getId() {
return id;
}
public void setId(String id) {
this.id = id;
}
}
分組校驗(yàn)
在不同的情況下,可能對(duì)相同javaBean對(duì)象的數(shù)據(jù)校驗(yàn)規(guī)則有所不同,有時(shí)需要根據(jù)狀態(tài)數(shù)據(jù)對(duì)javaBean中的某些屬性字段進(jìn)行單獨(dú)驗(yàn)證。這時(shí)候就可以使用分組校驗(yàn)功能,即根據(jù)狀態(tài)啟用一組約束,Hibernate Validator的注解提供了groups參數(shù)用于指定分組,如果沒(méi)有指定groups參數(shù),則默認(rèn)屬于javax.validation.groups.Default。接下來(lái)我們舉例來(lái)說(shuō)明這一過(guò)程。
首先創(chuàng)建分組GroupA和GroupB如下,這兩個(gè)接口作為兩個(gè)校驗(yàn)規(guī)則的分組。
public interface GroupA {
}
public interface GroupB {
}
然后創(chuàng)建實(shí)體類Person,并在相關(guān)字段定義分組校驗(yàn)規(guī)則。
public class Person {
@NotBlank(message = "userId不能為空", groups = {GroupA.class})
private String userId;
@NotBlank(message = "用戶名不能為空", groups = {GroupB.class})
private String name;
@Range(min=20, max = 30, message = "年齡必須在【20,30】", groups = {GroupA.class})
@Range(min = 30, max = 40, message = "年齡必須在【30,40】", groups = {GroupB.class})
private int age;
//省略來(lái)get方法和set方法
}
上述例子中,在age
字段使用了兩個(gè)校驗(yàn)規(guī)則,GroupA年齡要在20-30,GroupB年齡要在30-40。最后使用分組:
@RequestMapping("/save")
public String save(@RequestBody @Validated({ GroupA.class, Default.class}) Person person, BindingResult result) {
if (result.hasErrors()) {
List
其中@Validated
注解中增加了{(lán)GroupA.class, Default.class}參數(shù)表示對(duì)于定義了分組校驗(yàn)規(guī)則的字段使用GroupA規(guī)則,其他使用默認(rèn)規(guī)則。
-
Web
+關(guān)注
關(guān)注
2文章
1266瀏覽量
69551 -
URL
+關(guān)注
關(guān)注
0文章
139瀏覽量
15384 -
spring
+關(guān)注
關(guān)注
0文章
340瀏覽量
14361 -
服務(wù)端
+關(guān)注
關(guān)注
0文章
66瀏覽量
7025
發(fā)布評(píng)論請(qǐng)先 登錄
相關(guān)推薦
評(píng)論