本篇概述
在正常的項目開發中,我們常常需要對程序的參數進行校驗來保證程序的安全性。參數校驗非常簡單,說白了就是對參數進行正確性驗證,例如非空驗證、范圍驗證、類型驗證等等。校驗的方式也有很多種。如果架構設計的比較好的話,可能我們都不需要做任何驗證,或者寫比較少的代碼就可以滿足驗證的需求。如果架構設計的有缺陷,或者說壓根就沒有架構的話,那么我們對參數進行驗證時,就需要我們寫大量相對重復的代碼進行驗證了。
手動參數校驗
下面我們還是以上一篇的內容為例,我們首先手動對參數進行校驗。下面為Controller源碼:
package com.jilinwula.springboot.helloworld.controller; import com.jilinwula.springboot.helloworld.Repository.UserInfoRepository;
import com.jilinwula.springboot.helloworld.entity.UserInfoEntity;
import com.jilinwula.springboot.helloworld.query.UserInfoQuery;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.util.StringUtils;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
@RestController
@RequestMapping("/userinfo")
public class UserInfoController {
<span class="hljs-meta">@Autowired</span>
<span class="hljs-keyword">private</span> UserInfoRepository userInfoRepository;
<span class="hljs-meta">@GetMapping(<span class="hljs-meta-string">"/query"</span>)</span>
<span class="hljs-keyword">public</span> Object list(UserInfoQuery userInfo) {
<span class="hljs-keyword">if</span> (StringUtils.isEmpty(userInfo.getUsername())) {
<span class="hljs-keyword">return</span> <span class="hljs-string">"賬號不能為空"</span>;
}
<span class="hljs-keyword">if</span> (StringUtils.isEmpty(userInfo.getRoleId()) || userInfo.getRoleId() > <span class="hljs-number">100</span> || userInfo.getRoleId() < <span class="hljs-number">1</span>) {
<span class="hljs-keyword">return</span> <span class="hljs-string">"權限不能為空,並且范圍為[1-99]"</span>;
}
UserInfoEntity userInfoEntity = userInfoRepository.findByUsernameAndRoleId(userInfo.getUsername(), userInfo.getRoleId());
<span class="hljs-keyword">return</span> userInfoEntity;
}
}
我們只驗證了username和roleId參數,分別驗證為空驗證及范圍驗證。下面我們測試一下。啟動項目后,訪問以下地址:
http://127.0.0.1:8080/springb...
我們看一下程序的運行結果。
因為我們沒有寫任何參數,所以參數驗證一定是不能通過的。所以就返回的上圖中的提示信息。下面我們看一下數據庫中的數據,然后訪問一下正確的地址,看看能不能成功的返回數據庫中的數據。下圖為數據庫中的數據:
下面我們訪問一下正確的參數,然后看一下返回的結果。訪問地址:
http://127.0.0.1:8080/springb...
訪問結果:
我們看上圖已經成功的返回數據庫中的數據了,這就是簡單的參數校驗,正是因為簡單,所以我們就不做過多的介紹了。下面我們簡單分析一下,這樣做參數驗證好不好。如果我們的項目比較簡單,那答案一定是肯定的,因為站在軟件設計角度考慮,沒必要為了一個簡單的功能而設計一個復雜的架構。因為越是復雜的功能,出問題的可能性就越大,程序就越不穩定。但如果站在程序開發角度,那上面的代碼一定是有問題的,因為上面的代碼根本沒辦法復用,如果要開發很多這樣的項目,要進行參數驗證時,那結果一定是代碼中有很多相類似的代碼,這顯然是不合理的。那怎么辦呢?那答案就是本篇中的重點內容,也就是SpringBoot對參數的驗證,實際上本篇的內容主要是和Spring內容相關和SpringBoot的關系不大。但SpringBoot中基本包括了所有Spring的內容,所以我們還是以SpringBoot項目為例。下面我們看一下,怎么在SpringBoot中的對參數進行校驗。
ObjectError參數校驗
我們首先看一下代碼,然后在詳細介紹代碼中的新知識。下面為接受的參數類的源碼。
修改前:
package com.jilinwula.springboot.helloworld.query; import lombok.Data;
import org.springframework.stereotype.Component;
@Component
@Data
public class UserInfoQuery{
<span class="hljs-keyword">private</span> String username;
<span class="hljs-keyword">private</span> <span class="hljs-built_in">Long</span> roleId;
}
修改后:
package com.jilinwula.springboot.helloworld.query; import lombok.Data;
import org.springframework.stereotype.Component;
import javax.validation.constraints.Max;
import javax.validation.constraints.Min;
import javax.validation.constraints.NotNull;
@Component
@Data
public class UserInfoQuery{
@<span class="hljs-keyword">NotNull</span>(<span class="hljs-keyword">message</span> = <span class="hljs-string">"賬號不能為空"</span>)
private String username;
@<span class="hljs-keyword">NotNull</span>(<span class="hljs-keyword">message</span> = <span class="hljs-string">"權限不能為空"</span>)
@Min(value = <span class="hljs-number">1</span>, message = <span class="hljs-string">"權限范圍為[1-99]"</span>)
@Max(value = <span class="hljs-number">99</span>, message = <span class="hljs-string">"權限范圍為[1-99]"</span>)
private Long roleId;
}
我們看代碼中唯一的區別就是添加了很多的注解。沒錯,在SpringBoot項目中進行參數校驗時,就是使用這些注解來完成的。並且注解的命名很直觀,基本上通過名字就可以知道什么含義。唯一需要注意的就是這些注解的包是javax中的,而不是其它第三方引入的包。這一點要特別注意,因為很多第三方的包,也包含這些同名的注解。下面我們繼續看Controller中的改動(備注:有關javax中的校驗注解相關的使用說明,我們后續在做介紹)。Controller源碼:
改動前:
package com.jilinwula.springboot.helloworld.controller; import com.jilinwula.springboot.helloworld.Repository.UserInfoRepository;
import com.jilinwula.springboot.helloworld.entity.UserInfoEntity;
import com.jilinwula.springboot.helloworld.query.UserInfoQuery;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.util.StringUtils;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
@RestController
@RequestMapping("/userinfo")
public class UserInfoController {
<span class="hljs-meta">@Autowired</span>
<span class="hljs-keyword">private</span> UserInfoRepository userInfoRepository;
<span class="hljs-meta">@GetMapping(<span class="hljs-meta-string">"/query"</span>)</span>
<span class="hljs-keyword">public</span> Object list(UserInfoQuery userInfo) {
<span class="hljs-keyword">if</span> (StringUtils.isEmpty(userInfo.getUsername())) {
<span class="hljs-keyword">return</span> <span class="hljs-string">"賬號不能為空"</span>;
}
<span class="hljs-keyword">if</span> (StringUtils.isEmpty(userInfo.getRoleId()) || userInfo.getRoleId() > <span class="hljs-number">100</span> || userInfo.getRoleId() < <span class="hljs-number">1</span>) {
<span class="hljs-keyword">return</span> <span class="hljs-string">"權限不能為空,並且范圍為[1-99]"</span>;
}
UserInfoEntity userInfoEntity = userInfoRepository.findByUsernameAndRoleId(userInfo.getUsername(), userInfo.getRoleId());
<span class="hljs-keyword">return</span> userInfoEntity;
}
}
改動后:
package com.jilinwula.springboot.helloworld.controller; import com.jilinwula.springboot.helloworld.Repository.UserInfoRepository;
import com.jilinwula.springboot.helloworld.entity.UserInfoEntity;
import com.jilinwula.springboot.helloworld.query.UserInfoQuery;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.validation.BindingResult;
import org.springframework.validation.ObjectError;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import javax.validation.Valid;
@RestController
@RequestMapping("/userinfo")
public class UserInfoController {
<span class="hljs-meta">@Autowired</span>
<span class="hljs-keyword">private</span> UserInfoRepository userInfoRepository;
<span class="hljs-meta">@GetMapping(<span class="hljs-meta-string">"/query"</span>)</span>
<span class="hljs-keyword">public</span> Object list(<span class="hljs-meta">@Valid</span> UserInfoQuery userInfo, BindingResult result) {
<span class="hljs-keyword">if</span> (result.hasErrors()) {
<span class="hljs-keyword">for</span> (ObjectError error : result.getAllErrors()) {
<span class="hljs-keyword">return</span> error.getDefaultMessage();
}
}
UserInfoEntity userInfoEntity = userInfoRepository.findByUsernameAndRoleId(userInfo.getUsername(), userInfo.getRoleId());
<span class="hljs-keyword">return</span> userInfoEntity;
}
}
我們看代碼改動的還是比較大的首先在入參中添加了@Valid注解。該注解就是標識讓SpringBoot對請求參數進行驗證。也就是和參數類里的注解是對應的。其次我們修改了直接在Controller中進行參數判斷的邏輯,將以前的代碼修改成了SpringBoot中指定的校驗方式。下面我們啟動項目,來驗證一下上述代碼是否能成功的驗證參數的正確性。我們訪問下面請求地址:
http://127.0.0.1:8080/springb...
返回結果:
我們看上圖成功的驗證了為空的校驗,下面我們試一下范圍的驗證。我們訪問下面的請求地址:
http://127.0.0.1:8080/springb...
看一下返回結果:
我們看成功的檢測到了參數范圍不正確。這就是SpringBoot中的參數驗證功能。但上面的代碼一個問題,就是只是會返回錯誤的提示信息,而沒有提示,是哪個參數不正確。下面我們修改一下代碼,來看一下怎么返回是哪個參數不正確。
FieldError參數校驗
package com.jilinwula.springboot.helloworld.controller; import com.jilinwula.springboot.helloworld.Repository.UserInfoRepository;
import com.jilinwula.springboot.helloworld.entity.UserInfoEntity;
import com.jilinwula.springboot.helloworld.query.UserInfoQuery;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.validation.BindingResult;
import org.springframework.validation.FieldError;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import javax.validation.Valid;
@RestController
@RequestMapping("/userinfo")
public class UserInfoController {
<span class="hljs-meta">@Autowired</span>
<span class="hljs-keyword">private</span> UserInfoRepository userInfoRepository;
<span class="hljs-meta">@GetMapping(<span class="hljs-meta-string">"/query"</span>)</span>
<span class="hljs-keyword">public</span> Object list(<span class="hljs-meta">@Valid</span> UserInfoQuery userInfo, BindingResult result) {
<span class="hljs-keyword">if</span> (result.hasErrors()) {
FieldError error = result.getFieldError();
<span class="hljs-keyword">return</span> error.getField() + <span class="hljs-string">"+"</span> + error.getDefaultMessage();
}
UserInfoEntity userInfoEntity = userInfoRepository.findByUsernameAndRoleId(userInfo.getUsername(), userInfo.getRoleId());
<span class="hljs-keyword">return</span> userInfoEntity;
}
}
我們將獲取ObjectError的類型修改成了FieldError。因為FieldError類型可以獲取到驗證錯誤的字段名字,所以我們將ObjectError修改為FieldError。下面我們看一下請求返回的結果。
我們看這回我們就獲取到了驗證錯誤的字段名子了。在實際的項目開發中,我們在返回接口數據時,大部分都會采用json格式的方式返回,下面我們簡單封裝一個返回的類,使上面的驗證返回json格式。下面為封裝的返回類的源碼:
package com.jilinwula.springboot.helloworld.utils; import lombok.Data;
@Data
public class Return {
private int code;
private Object data;
private String msg;
<span class="hljs-keyword">public</span> static <span class="hljs-keyword">Return</span> error(Object <span class="hljs-keyword">data</span>, String msg) {
<span class="hljs-keyword">Return</span> r = new <span class="hljs-keyword">Return</span>();
r.setCode(-<span class="hljs-number">1</span>);
r.setData(<span class="hljs-keyword">data</span>);
r.setMsg(msg);
<span class="hljs-keyword">return</span> r;
}
}
Controller修改:
package com.jilinwula.springboot.helloworld.controller; import com.jilinwula.springboot.helloworld.Repository.UserInfoRepository;
import com.jilinwula.springboot.helloworld.entity.UserInfoEntity;
import com.jilinwula.springboot.helloworld.query.UserInfoQuery;
import com.jilinwula.springboot.helloworld.utils.Return;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.validation.BindingResult;
import org.springframework.validation.FieldError;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import javax.validation.Valid;
@RestController
@RequestMapping("/userinfo")
public class UserInfoController {
<span class="hljs-meta">@Autowired</span>
<span class="hljs-keyword">private</span> UserInfoRepository userInfoRepository;
<span class="hljs-meta">@GetMapping(<span class="hljs-meta-string">"/query"</span>)</span>
<span class="hljs-keyword">public</span> Object list(<span class="hljs-meta">@Valid</span> UserInfoQuery userInfo, BindingResult result) {
<span class="hljs-keyword">if</span> (result.hasErrors()) {
FieldError error = result.getFieldError();
<span class="hljs-keyword">return</span> Return.error(error.getField(), error.getDefaultMessage());
}
UserInfoEntity userInfoEntity = userInfoRepository.findByUsernameAndRoleId(userInfo.getUsername(), userInfo.getRoleId());
<span class="hljs-keyword">return</span> userInfoEntity;
}
}
我們還是啟動項目,並訪問下面地址看看返回的結果:
http://127.0.0.1:8080/springb...
返回結果:
創建切面
這樣我們就返回一個簡單的json類型的數據了。雖然我們的校驗參數的邏輯沒有在Controller里面寫,但我們還是在Controller里面寫了很多和業務無關的代碼,並且這些代碼還是重復的,這顯然是不合理的。我們可以將上述相同的代碼的封裝起來,然后統一的處理。這樣就避免了有很多重復的代碼了。那這代碼封裝到哪里呢?我們可以使用Spring中的切面功能。因為SpringBoot中基本包括了所有Spring中的技術,所以,我們可以放心大膽的在SpringBoot項目中使用Spring中的技術。我們知道在使用切面技術時,我們可以對方法進行前置增強、后置增強、環繞增強等。這樣我們就可以利用切面的技術,在方法之前,也就是請求Controller之前,做參數的校驗工作,這樣就不會對我們的業務代碼產生侵入了。下面我們看一下切面的源碼然后在做詳細說明:
package com.jilinwula.springboot.helloworld.aspect; import com.jilinwula.springboot.helloworld.utils.Return;
import lombok.extern.slf4j.Slf4j;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
import org.springframework.stereotype.Component;
import org.springframework.validation.BindingResult;
import org.springframework.validation.FieldError;
@Slf4j
@Aspect
@Component
public class UserAspect {
<span class="hljs-meta">@Before</span>(<span class="hljs-string">"execution(public * com.jilinwula.springboot.helloworld.controller..*(..))"</span>)
<span class="hljs-keyword">public</span> <span class="hljs-keyword">void</span> doBefore(JoinPoint joinPoint) {
<span class="hljs-keyword">for</span> (Object <span class="hljs-string">arg :</span> joinPoint.getArgs()) {
<span class="hljs-keyword">if</span> (arg <span class="hljs-keyword">instanceof</span> BindingResult) {
BindingResult result = (BindingResult) arg;
<span class="hljs-keyword">if</span> (result.hasErrors()) {
FieldError error = result.getFieldError();
Return.error(error.getField(), error.getDefaultMessage());
}
}
}
}
}
我們看上述的代碼中我們添加了一個@Aspect注解,這個就是切面的注解,然后我們在方法中又添加了@Before注解,也就是對目標方法進行前置增強,Spring在請求Controller之前會先請求此方法。所以我們可以將校驗參數的代碼邏輯寫在這個方法中。execution參數為切點函數,也就是目標方法的切入點。切點函數包含一些通配符的語法,下面我們簡單介紹一下:
-
- 匹配任意字符,但它可能匹配上下文中的一個元素
- .. 匹配任意字符,可以匹配上下文中的多個元素
-
- 表示按類型匹配指定類的所有類,必須跟在類名后面,也就是會匹配繼承或者擴展指定類的所有類,包括指定類.
創建異常類
我們通過上述代碼知道,Spring中的切面功能是沒有返回值的。所以我們在使用切面功能時,是沒有辦法在切面里面做參數返回的。那我們應該怎么辦呢?這時異常就派上用場了。我們知道當程序拋出異常時,如果當前方法沒有做try catch處理,那么異常就會一直向上拋出,如果程序也一直沒有做處理,那么當前異常就會一直拋出,直到被Java虛擬機捕獲。但Java虛擬機也不會對異常進行處理,而是直接拋出異常。這也就是程序不做任何處理拋出異常的根本原因。我們正好可以利用異常的這種特性,返回參數驗證的結果。因為在Spring中為我們提供了統一捕獲異常的方法,我們可以在這個方法中,將我們的異常信息封裝成json格式,這樣我們就可以返回統一的jons格式了。所以在上述的切面中我們手動了拋出了一個異常。該異常因為我們沒有用任何處理,所以上述異常會被SpringBoot中的統一異常攔截處理。這樣當SpringBoot檢測到參數不正確時,就會拋出一個異常,然后SpringBoot就會檢測到程序拋出的異常,然后返回異常中的信息。下面我們看一下異常類的源碼:
異常類:
package com.jilinwula.springboot.helloworld.exception; import com.jilinwula.springboot.helloworld.utils.Return;
import lombok.Data;
@Data
public class UserInfoException extends RuntimeException {
private Return r;
public <span class="hljs-type">UserInfoException</span>(<span class="hljs-type">Return</span> r) {
<span class="hljs-keyword">this</span>.r = r;
}
}
Return源碼:
package com.jilinwula.springboot.helloworld.utils; import com.jilinwula.springboot.helloworld.exception.UserInfoException;
import lombok.Data;
@Data
public class Return {
private int code;
private Object data;
private String msg;
<span class="hljs-function"><span class="hljs-keyword">public</span> <span class="hljs-keyword">static</span> <span class="hljs-keyword">void</span> <span class="hljs-title">error</span><span class="hljs-params">(Object data, String msg)</span> </span>{
Return r = <span class="hljs-keyword">new</span> Return();
r.setCode(-<span class="hljs-number">1</span>);
r.setData(data);
r.setMsg(msg);
<span class="hljs-keyword">throw</span> <span class="hljs-keyword">new</span> UserInfoException(r);
}
<span class="hljs-function"><span class="hljs-keyword">public</span> <span class="hljs-keyword">static</span> Return <span class="hljs-title">success</span><span class="hljs-params">()</span> </span>{
Return r = <span class="hljs-keyword">new</span> Return();
r.setCode(<span class="hljs-number">0</span>);
<span class="hljs-keyword">return</span> r;
}
}
SpringBoot統一異常攔截
因為該異常類比較簡單,我們就不會過多的介紹了,唯一有一點需要注意的是該異常類繼承的是RuntimeException異常類,而不是Exception異常類,原因我們已經在上一篇中介紹了,Spring只會回滾RuntimeException異常類及其子類,而不會回滾Exception異常類的。下面我們看一下Spring中統一攔截異常處理,下面為該類的源碼:
package com.jilinwula.springboot.helloworld.handler; import com.jilinwula.springboot.helloworld.exception.UserInfoException;
import lombok.extern.slf4j.Slf4j;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.RestControllerAdvice;
@Slf4j
@RestControllerAdvice
public class UserInfoHandler {
<span class="hljs-comment">/**
* 校驗錯誤攔截處理
*
* @param e 錯誤信息集合
* @return 錯誤信息
*/</span>
@ExceptionHandler(UserInfoException.class)
public <span class="hljs-built_in">Object</span> handle(UserInfoException e) {
<span class="hljs-keyword">return</span> e.getR();
}
}
我們在該類添加了@RestControllerAdvice注解。該注解就是為了定義我們統一獲取異常攔截的。然后我們又添加了@ExceptionHandler注解,該注解就是用來攔截異常類的注解,並且可以在當前方法中,直接獲取到該異常類的對象信息。這樣我們直接返回這個異常類的信息就可以了。因為我們在這個自定義異常類中添加了Return參數,所以,我們只要反悔Return對象的信息即可,而不用返回整個異常的信息。下面我們訪問一下下面的請求,看看上述代碼是否能檢測到參數不正確。請求地址:
http://127.0.0.1:8080/springb...
返回結果:
這樣我們完成了參數校驗的功能了,並且這種方式有很大的復用性,即使我們在寫新的Controller,也不需要手動的校驗參數了,只要我們的請求參數是UserInfoQuery類就可以了。還有一點要注意,所以我們不用手動驗證參數了,但我們的請求參數中還是要寫BindingResult參數,這一點要特別注意。
正則表達式校驗注解
下面我們更詳細的介紹一下參數驗證的注解,我們首先看一下正則校驗,我們在實體類中添加一個新屬性,然后用正則的的方式,驗證該參數的正確性。下面為實體類源碼:
package com.jilinwula.springboot.helloworld.query; import lombok.Data;
import org.springframework.stereotype.Component;
import javax.validation.constraints.Max;
import javax.validation.constraints.Min;
import javax.validation.constraints.NotNull;
import javax.validation.constraints.Pattern;
@Component
@Data
public class UserInfoQuery{
@<span class="hljs-keyword">NotNull</span>(<span class="hljs-keyword">message</span> = <span class="hljs-string">"用戶編號不能為空"</span>)
@Pattern(regexp = <span class="hljs-string">"^[1-10]$"</span>,message = <span class="hljs-string">"用戶編號范圍不正確"</span>)
private String id;
@<span class="hljs-keyword">NotNull</span>(<span class="hljs-keyword">message</span> = <span class="hljs-string">"賬號不能為空"</span>)
private String username;
@<span class="hljs-keyword">NotNull</span>(<span class="hljs-keyword">message</span> = <span class="hljs-string">"權限不能為空"</span>)
@Min(value = <span class="hljs-number">1</span>, message = <span class="hljs-string">"權限范圍為[1-99]"</span>)
@Max(value = <span class="hljs-number">99</span>, message = <span class="hljs-string">"權限范圍為[1-99]"</span>)
private Long roleId;
}
下面我們訪問以下地址:
http://127.0.0.1:8080/springb...
http文件請求接口
但這回我們不在瀏覽器里請求,因為瀏覽器請求不太方便,並且返回的json格式也沒有格式化不方便瀏覽,除非要裝一些瀏覽器插件才可以。實際上在IDEA中我們可以很方便的請求一下接口地址,並且返回的json內容是自動格式化的。下面我們來看一下怎么在IDEA中發起接口請求。在IDEA中請求一個接口很簡單,我們只要創建一個.http類型的文件名字就可以。然后我們可以在該文件中,指定我們接口的請求類型,例如GET或者POST。當我們在文件的開口寫GET或者POST時,IDEA會自動有相應的提示。下面我們看一下http文件中的內容。
http.http:
GET http://127.0.0.1:8080/springboot/userinfo/query?roleId=3&username=阿里巴巴&id=-1
這時標識GET參數的地方,就會出現綠色剪頭,但我們點擊這個綠色箭頭,IDEA就會就會啟動請求GET參數后面的接口。下面我們看一下上述的返回結果。
GET http://127.0.0.1:8080/springboot/userinfo/query?roleId=3&username=%E9%98%BF%E9%87%8C%E5%B7%B4%E5%B7%B4&id=-1 HTTP/1.1 200
Content-Type: application/json;charset=UTF-8
Transfer-Encoding: chunked
Date: Mon, 18 Feb 2019 03:57:29 GMT
{
"code": -1,
"data": "id",
"msg": "用戶編號范圍不正確"
}
Response code: 200; Time: 24ms; Content length: 41 bytes
這就是.http文件類型的返回結果,用該文件請求接口,相比用瀏覽器來說,要方便的多。因為我們在實體類中使用正則指定參數范圍為1-10,所以請求接口時反悔了id參數有錯誤。下面我們輸入一個正確的值在看一下返回結果。
http.http:
GET http://127.0.0.1:8080/springboot/userinfo/query?roleId=3&username=阿里巴巴&id=1
返回結果:
GET <http://127.0.0.1:8080/springboot/userinfo/query?roleId=3&username=%E9%98%BF%E9%87%8C%E5%B7%B4%E5%B7%B4&id=1> HTTP/1.1 200
Content-Type: application/json;charset=UTF-8
Transfer-Encoding: chunked
Date: Mon, 18 Feb 2019 05:46:49 GMT
{
"id": 61,
"username": "阿里巴巴",
"password": "alibaba",
"nickname": "阿里巴巴",
"roleId": 3
}
Response code: 200; Time: 25ms; Content length: 77 bytes
常見校驗注解
我們看已經正確的返回數據庫中的數據了。在Spring中,提供了很多種注解來方便我們進行參數校驗,下面是比較常見的注解:
注解 | 作用 | |
---|---|---|
@Null | 參數必須為null | |
@NotNull | 參數必須不為null | |
@NotBlank | 參數必須不為null,並且長度必須大於0 | |
@NotEmpty | 參數必須不為空 | |
@Min | 參數必須大於等於該值 | |
@Max | 參數必須小於等於該值 | |
@Size | 參數必須在指定的范圍內 | |
@Past | 參數必須是一個過期的時間 | |
@Future | 參數必須是一個未來的時間 | |
@Pattern | 參數必須滿足正則表達式 | |
參數必須為電子郵箱 |
上述內容就是SpringBoot中的參數校驗全部內容,如有不正確的歡迎留言,謝謝。
源碼地址
https://github.com/jilinwula/...
原文地址
http://jilinwula.com/article/...原文地址:https://segmentfault.com/a/1190000018190090
Powered by .NET Core on Kubernetes