Spring?Boot項目傳參校驗的最佳實踐指南
場景還原
簡單業(yè)務(wù)場景模擬:
假如你現(xiàn)在在做一個成績錄入系統(tǒng),你愉快地用Spring Boot框架寫了一個后臺接口,用于接收前臺瀏覽器傳過來的 Student對象,并插入后臺數(shù)據(jù)庫。
我們將傳入的 Student對象定義為:
public class Student { private String name; // 姓名 private Integer score; // 考試分?jǐn)?shù)(滿分100分) private String mobile; // 電話號碼(11位) }
然后寫一個Post請求的后臺接口,來接收網(wǎng)頁端傳過來的 Student對象:
@RestController public class TestController { @Autowired private StudentService studentService; @PostMapping("/add") public String addStudent( @RequestBody Student student ) { studentService.addStudent( student ); // 將student對象存入數(shù)據(jù)庫 return "SUCCESS"; } }
此時我想你一定看出來了上面這段代碼的漏洞,因為我們并沒有對傳入的 Student對象做任何數(shù)據(jù)校驗,比如:
Student對象里三個字段的某一個忘傳了,為 null怎么辦?Student的 score分?jǐn)?shù),假如寫錯了,寫成 101分怎么辦?Student的 mobile11位手機號碼,假如填錯了,多寫了一位怎么辦?...等等
這些數(shù)據(jù)雖然在前端頁面一般會做校驗,但我們作為一個嚴(yán)謹(jǐn)且良心的后端開發(fā)工程師,我們肯定要對傳入的每一項數(shù)據(jù)做嚴(yán)格的校驗,所以我們應(yīng)該怎么寫?
@PostMapping("/add") public String addStudent( @RequestBody Student student ) { if( student == null ) return "傳入的Student對象為null,請傳值"; if( student.getName()==null || "".equals(student.getName()) ) return "傳入的學(xué)生姓名為空,請傳值"; if( student.getScore()==null ) return "傳入的學(xué)生成績?yōu)閚ull,請傳值"; if( (student.getScore()<0) || (student.getScore()>100) ) return "傳入的學(xué)生成績有誤,分?jǐn)?shù)應(yīng)該在0~100之間"; if( student.getMobile()==null || "".equals(student.getMobile()) ) return "傳入的學(xué)生電話號碼為空,請傳值"; if( student.getMobile().length()!=11 ) return "傳入的學(xué)生電話號碼長度有誤,應(yīng)為11位"; studentService.addStudent( student ); // 將student對象存入MySQL數(shù)據(jù)庫 return "SUCCESS"; }
寫是寫完了,就是感覺手有點酸,并且心有點累,這個 Student對象倒還好,畢竟內(nèi)部僅3個字段,假如一個復(fù)雜的對象有30個字段怎么辦?簡直不敢想象!
神注解加持
其實Spring框架很早版本開始,就通過注解的方式,來方便地為我們提供了各項交互數(shù)據(jù)的校驗工作,比如上面的例子,我們只需要在傳入的 Student實體類的字段中加入對應(yīng)注解即可方便的解決問題:
public class Student { @NotNull(message = "傳入的姓名為null,請傳值") @NotEmpty(message = "傳入的姓名為空字符串,請傳值") private String name; // 姓名 @NotNull(message = "傳入的分?jǐn)?shù)為null,請傳值") @Min(value = 0,message = "傳入的學(xué)生成績有誤,分?jǐn)?shù)應(yīng)該在0~100之間") @Max(value = 100,message = "傳入的學(xué)生成績有誤,分?jǐn)?shù)應(yīng)該在0~100之間") private Integer score; // 分?jǐn)?shù) @NotNull(message = "傳入的電話為null,請傳值") @NotEmpty(message = "傳入的電話為空字符串,請傳值") @Length(min = 11, max = 11, message = "傳入的電話號碼長度有誤,必須為11位") private String mobile; // 電話號碼 }
當(dāng)然,于此同時,我們還需要在對象入口處,加上注解 @Valid來開啟對傳入 Student對象的驗證工作:
@PostMapping("/add") public String addStudent( @RequestBody @Valid Student student ) { // 棒棒噠!原先各種繁雜的參數(shù)校驗工作統(tǒng)統(tǒng)都省了!一行代碼不用寫 studentService.addStudent( student ); // 將student對象存入MySQL數(shù)據(jù)庫 return "SUCCESS"; }
這時候,如果某個字段傳入錯誤,比如我傳數(shù)據(jù)的時候,將學(xué)生的成績誤傳為 101分,則接口返回結(jié)果便會提示出錯誤詳情:
當(dāng)然,關(guān)于這個事情的原理,既然用到了注解,無非用的也就是Java里的各種反射等知識來實現(xiàn)的,感興趣的小伙伴可以借此機會研究一下!
數(shù)據(jù)異常統(tǒng)一攔截
上面利用注解的方式做統(tǒng)一數(shù)據(jù)校驗感覺十分美好,但唯一美中不足的就是返回的結(jié)果太過繁雜,不一定使我們需要的格式,我們需要做統(tǒng)一處理,比如:我只想將具體參數(shù)校驗的錯誤提示信息給摳出來返回給前端即可。
為此,我們?yōu)轫椖颗渲?strong>全局統(tǒng)一異常攔截器來格式化所有數(shù)據(jù)校驗的返回結(jié)果。
@ControllerAdvice @ResponseBody public class GlobalExceptionInterceptor { @ExceptionHandler(value = Exception.class) public String exceptionHandler(HttpServletRequest request, Exception e) { String failMsg = null; if (e instanceof MethodArgumentNotValidException) { // 拿到參數(shù)校驗具體異常信息提示 failMsg = ((MethodArgumentNotValidException) e).getBindingResult().getFieldError().getDefaultMessage(); } return failMsg; // 直接吐回給前端 } }
如上面代碼所示,我們全局統(tǒng)一攔截了參數(shù)校驗異常 MethodArgumentNotValidException,并僅僅只拿到對應(yīng)異常的詳細(xì) Message信息吐給前端,此時返回給前端的數(shù)據(jù)就清楚得多:
可以的,非常優(yōu)雅!
總結(jié)
到此這篇關(guān)于Spring Boot項目傳參校驗的文章就介紹到這了,更多相關(guān)SpringBoot項目傳參校驗內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
java 數(shù)據(jù)結(jié)構(gòu)與算法 (快速排序法)
這篇文章主要介紹了java 數(shù)據(jù)結(jié)構(gòu)與算法(快速排序法),,快速排序法是實踐中的一種快速的排序算法,在c++或?qū)ava基本類型的排序中特別有用,下面我們一起進入文章學(xué)習(xí)更詳細(xì)的內(nèi)容吧,需要的朋友可以參考下2022-02-02idea企業(yè)開發(fā)之新建各類型項目的詳細(xì)教程
這篇文章主要介紹了idea企業(yè)開發(fā)之新建各類型項目的詳細(xì)教程,本文通過圖文并茂的形式給大家介紹的非常詳細(xì),對大家的學(xué)習(xí)或工作具有一定的參考借鑒價值,需要的朋友可以參考下2020-12-12JAVA技術(shù)實現(xiàn)上傳下載文件到FTP服務(wù)器(完整)
這篇文章主要介紹了JAVA技術(shù)實現(xiàn)上傳下載文件到FTP服務(wù)器(完整),本文使用 Apache Jakarta Commons Net(commons-net-3.3.jar) 基于FileZilla Server服務(wù)器實現(xiàn)FTP服務(wù)器上文件的上傳/下載/刪除等操作,需要的朋友可以參考下2015-07-07SpringCloud客戶端報錯:- was unable to send&nb
這篇文章主要介紹了SpringCloud客戶端報錯:- was unable to send heartbeat!的問題及解決方案,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教2022-05-05【Redis緩存機制】詳解Java連接Redis_Jedis_事務(wù)
這篇文章主要介紹了【Redis緩存機制】詳解Java連接Redis_Jedis_事務(wù),詳細(xì)的介紹了Jedis事務(wù)和實例,有興趣的可以了解一下。2016-12-12詳解java8在Collection中新增加的方法removeIf
這篇文章主要介紹了詳解java8在Collection中新增加的方法removeIf的相關(guān)資料,需要的朋友可以參考下2018-01-01