版權(quán)說明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請進(jìn)行舉報或認(rèn)領(lǐng)
文檔簡介
第springboot整合JSR303參數(shù)校驗與全局異常處理的方法目錄一、前言二、JSR303簡介三、導(dǎo)入依賴四、常用注解五、@Validated、@Valid區(qū)別六、常用使用測試1.實體類添加校驗2.統(tǒng)一返回類型3.測試類4.普通測試結(jié)果5.我們把異常返回給頁面6.異常處理結(jié)果七、抽離全局異常處理1.心得體會2.書寫ExceptionControllerAdvice3.測試結(jié)果八、分組校驗1.需求2.創(chuàng)建分組接口(不需寫任何內(nèi)容)3.在需要二義性的字段上添加分組4.不同Controller添加校驗規(guī)則5.測試九、自定義校驗1.定義自定義校驗器2.定義一個注解配合校驗器使用3.實體類添加一個新的校驗屬性4.測試十、總結(jié)
一、前言
我們在日常開發(fā)中,避不開的就是參數(shù)校驗,有人說前端不是會在表單中進(jìn)行校驗的嗎?在后端中,我們可以直接不管前端怎么樣判斷過濾,我們后端都需要進(jìn)行再次判斷,為了安全。因為前端很容易拜托,當(dāng)測試使用PostMan來測試,如果后端沒有校驗,不就亂了嗎?肯定會有很多異常的。今天小編和大家一起學(xué)習(xí)一下JSR303專門用于參數(shù)校驗的,算是一個工具吧!
二、JSR303簡介
JSR-303是JAVAEE6中的一項子規(guī)范,叫做BeanValidation,官方參考實現(xiàn)是HibernateValidator。
HibernateValidator提供了JSR303規(guī)范中所有內(nèi)置constraint的實現(xiàn),除此之外還有一些附加的constraint。
Hibernate官網(wǎng)
官網(wǎng)介紹:
驗證數(shù)據(jù)是一項常見任務(wù),它發(fā)生在從表示層到持久層的所有應(yīng)用程序?qū)又小MǔT诿恳粚佣紝崿F(xiàn)相同的驗證邏輯,這既耗時又容易出錯。為了避免重復(fù)這些驗證,開發(fā)人員經(jīng)常將驗證邏輯直接捆綁到域模型中,將域類與驗證代碼混在一起,而驗證代碼實際上是關(guān)于類本身的元數(shù)據(jù)。
JakartaBeanValidation2.0-為實體和方法驗證定義了元數(shù)據(jù)模型和API。默認(rèn)元數(shù)據(jù)源是注釋,能夠通過使用XML覆蓋和擴(kuò)展元數(shù)據(jù)。API不依賴于特定的應(yīng)用程序?qū)踊蚓幊棠P汀K貏e不依賴于Web或持久層,并且可用于服務(wù)器端應(yīng)用程序編程以及富客戶端Swing應(yīng)用程序開發(fā)人員。
三、導(dǎo)入依賴
dependency
groupIdorg.springframework.boot/groupId
artifactIdspring-boot-starter-validation/artifactId
/dependency
四、常用注解
約束注解名稱約束注解說明@Null用于驗證對象為null@NotNull用于對象不能為null,無法查檢長度為0的字符串@NotBlank只用于String類型上,不能為null且trim()之后的size0@NotEmpty用于集合類、String類不能為null,且size0。但是帶有空格的字符串校驗不出來@Size用于對象(Array,Collection,Map,String)長度是否在給定的范圍之內(nèi)@Length用于String對象的大小必須在指定的范圍內(nèi)@Pattern用于String對象是否符合正則表達(dá)式的規(guī)則@Email用于String對象是否符合郵箱格式@Min用于Number和String對象是否大等于指定的值@Max用于Number和String對象是否小等于指定的值@AssertTrue用于Boolean對象是否為true@AssertFalse用于Boolean對象是否為false
所有的大家參考jar包
五、@Validated、@Valid區(qū)別
@Validated:
Spring提供的支持分組校驗可以用在類型、方法和方法參數(shù)上。但是不能用在成員屬性(字段)上由于無法加在成員屬性(字段)上,所以無法單獨完成級聯(lián)校驗,需要配合@Valid
@Valid:
JDK提供的(標(biāo)準(zhǔn)JSR-303規(guī)范)不支持分組校驗可以用在方法、構(gòu)造函數(shù)、方法參數(shù)和成員屬性(字段)上可以加在成員屬性(字段)上,能夠獨自完成級聯(lián)校驗
總結(jié):@Validated用到分組時使用,一個學(xué)校對象里還有很多個學(xué)生對象需要使用@Validated在Controller方法參數(shù)前加上,@Valid加在學(xué)校中的學(xué)生屬性上,不加則無法對學(xué)生對象里的屬性進(jìn)行校驗!
區(qū)別參考博客地址
例子:
@Data
publicclassSchool{
@NotBlank
privateStringid;
privateStringname;
@Valid//需要加上,否則不會驗證student類中的校驗注解
@NotNull//且需要觸發(fā)該字段的驗證才會進(jìn)行嵌套驗證。
privateListStudentlist;
@Data
publicclassStudent{
@NotBlank
privateStringid;
privateStringname;
privateintage;
@PostMapping("/test")
publicResulttest(@Validated@RequestBodySchoolschool){
}
六、常用使用測試
1.實體類添加校驗
importlombok.Data;
importjavax.validation.constraints.Min;
importjavax.validation.constraints.NotBlank;
importjavax.validation.constraints.NotNull;
importjavax.validation.constraints.Pattern;
importjava.io.Serializable;
@Data
publicclassBrandEntityimplementsSerializable{
privatestaticfinallongserialVersionUID=1L;
*品牌id
@NotNull(message="修改必須有品牌id")
privateLongbrandId;
*品牌名F
@NotBlank(message="品牌名必須提交")
privateStringname;
*品牌logo地址
@NotBlank(message="地址必須不為空")
privateStringlogo;
*介紹
privateStringdescript;
*檢索首字母
//正則表達(dá)式
@Pattern(regexp="^[a-zA-Z]$",message="檢索的首字母必須是字母")
privateStringfirstLetter;
*排序
@Min(value=0,message="排序必須大于等于0")
privateIntegersort;
}
2.統(tǒng)一返回類型
importcom.alibaba.druid.util.StringUtils;
importio.swagger.annotations.ApiModel;
importio.swagger.annotations.ApiModelProperty;
importlombok.AllArgsConstructor;
importlombok.Data;
importlombok.NoArgsConstructor;
//統(tǒng)一返回結(jié)果
@Data
@NoArgsConstructor
@AllArgsConstructor
@ApiModel
publicclassResultT{
@ApiModelProperty("響應(yīng)碼")
privateIntegercode;
@ApiModelProperty("相應(yīng)信息")
privateStringmsg;
@ApiModelProperty("返回對象或者集合")
privateTdata;
//成功碼
publicstaticfinalIntegerSUCCESS_CODE=200;
//成功消息
publicstaticfinalStringSUCCESS_MSG="SUCCESS";
//失敗
publicstaticfinalIntegerERROR_CODE=201;
publicstaticfinalStringERROR_MSG="系統(tǒng)異常,請聯(lián)系管理員";
//沒有權(quán)限的響應(yīng)碼
publicstaticfinalIntegerNO_AUTH_COOD=999;
//執(zhí)行成功
publicstaticTResultTsuccess(Tdata){
returnnewResult(SUCCESS_CODE,SUCCESS_MSG,data);
//執(zhí)行失敗
publicstaticTResultfailed(Stringmsg){
msg=StringUtils.isEmpty(msg)ERROR_MSG:msg;
returnnewResult(ERROR_CODE,msg,"");
//傳入錯誤碼的方法
publicstaticTResultfailed(intcode,Stringmsg){
msg=StringUtils.isEmpty(msg)ERROR_MSG:msg;
returnnewResult(code,msg,"");
//傳入錯誤碼的數(shù)據(jù)
publicstaticTResultfailed(intcode,Stringmsg,Tdata){
msg=StringUtils.isEmpty(msg)ERROR_MSG:msg;
returnnewResult(code,msg,data);
}
3.測試類
@PostMapping("/add")
publicResultadd(@Valid@RequestBodyBrandEntitybrandEntity){
returnResult.success("成功");
}
遇到的坑:小編在公司的項目中添加沒什么問題,但是就是無法觸發(fā)校驗,看到的是Springboot版本太高了,所有要添加下面的依賴才觸發(fā)。
dependency
groupIdorg.hibernate.validator/groupId
artifactIdhibernate-validator/artifactId
version6.0.18.Final/version
/dependency
4.普通測試結(jié)果
5.我們把異常返回給頁面
@PostMapping("/add")
publicResultadd(@Valid@RequestBodyBrandEntitybrandEntity,BindingResultbindingResult){
if(bindingResult.hasErrors()){
MapString,Stringmap=newHashMap();
bindingResult.getFieldErrors().forEach(item-{
map.put(item.getField(),item.getDefaultMessage());
returnResult.failed(400,"提交的數(shù)據(jù)不合規(guī)范",map);
returnResult.success("成功");
}
6.異常處理結(jié)果
{
"code":400,
"data":{
"name":"品牌名必須提交",
"logo":"地址必須不為空"
"msg":"提交的數(shù)據(jù)不合規(guī)范"
}
七、抽離全局異常處理
1.心得體會
上面我們要在每個校驗的接口上面寫,所以我們要抽離出來做個全局異常。并且要改進(jìn)一下,原來的是把錯誤信息放到data里,但是正常情況下的data是返回給前端的數(shù)據(jù)。我們這樣把異常數(shù)據(jù)放進(jìn)去,會使data的數(shù)據(jù)有二義性。這樣對于前端就不知道里面是數(shù)據(jù)還是報錯信息了哈,這樣就可以直接前端展示msg里面的提示即可!
2.書寫ExceptionControllerAdvice
importcom.wang.test.demo.response.Result;
importlombok.extern.slf4j.Slf4j;
importorg.springframework.validation.BindingResult;
importorg.springframework.web.bind.MethodArgumentNotValidException;
importorg.springframework.web.bind.annotation.ExceptionHandler;
importorg.springframework.web.bind.annotation.RestControllerAdvice;
@Slf4j
@RestControllerAdvice(basePackages="com.wang.test.demo.controller")
publicclassExceptionControllerAdvice{
@ExceptionHandler(value=MethodArgumentNotValidException.class)
publicResulthandleVaildException(MethodArgumentNotValidExceptione){
log.error("數(shù)據(jù)校驗出現(xiàn)問題:{},異常類型:{}",e.getMessage(),e.getClass());
BindingResultbindingResult=e.getBindingResult();
StringBufferstringBuffer=newStringBuffer();
bindingResult.getFieldErrors().forEach(item-{
//獲取錯誤信息
Stringmessage=item.getDefaultMessage();
//獲取錯誤的屬性名字
Stringfield=item.getField();
stringBuffer.append(field+":"+message+"");
returnResult.failed(400,stringBuffer+"");
@ExceptionHandler(value=Throwable.class)
publicResulthandleException(Throwablethrowable){
log.error("錯誤",throwable);
returnResult.failed(400,"系統(tǒng)異常");
3.測試結(jié)果
{
code:400,
data:,
msg:logo:地址必須不為空name:品牌名必須提交
}
八、分組校驗
1.需求
我們在做校驗的時候,通常會遇到一個實體類的添加和修改,他們的校驗規(guī)則是不同的,所以分組顯得尤為重要。他可以幫助我們少建一個冗余的實體類,所以我們必須要會的。
2.創(chuàng)建分組接口(不需寫任何內(nèi)容)
publicinterfaceEditGroup{
publicinterfaceAddGroup{
}
3.在需要二義性的字段上添加分組
/**
*品牌id
@NotNull(message="修改必須有品牌id",groups={EditGroup.class})
@Null(message="新增不能指定id",groups={AddGroup.class})
privateLongbrandId;
//其余屬性我們不變
4.不同Controller添加校驗規(guī)則
注意:我們要進(jìn)行分組,所以@Valid不能使用了,要使用@Validated。相信大家已經(jīng)看到上面的他倆區(qū)別了哈!
@PostMapping("/add")
publicResultadd(@Validated({AddGroup.class})@RequestBodyBrandEntitybrandEntity){
returnResult.success("成功");
@PostMapping("/edit")
publicResultedit(@Validated({EditGroup.class})@RequestBodyBrandEntitybrandEntity){
returnResult.success("成功");
}
5.測試
九、自定義校驗
1.定義自定義校驗器
importjavax.validation.ConstraintValidator;
importjavax.validation.ConstraintValidatorContext;
importjava.util.HashSet;
importjava.util.Set;
//編寫自定義的校驗器
publicclassListValueConstraintValidatorimplementsConstraintValidatorListValue,Integer{
privateSetIntegerset=newHashSetInteger
//初始化方法
@Override
publicvoidinitialize(ListValueconstraintAnnotation){
int[]value=constraintAnnotation.vals();
for(inti:value){
set.add(i);
*判斷是否校驗成功
*@paramvalue需要校驗的值
*@paramcontext
*@return
@Override
publicboole
溫馨提示
- 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請下載最新的WinRAR軟件解壓。
- 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶所有。
- 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁內(nèi)容里面會有圖紙預(yù)覽,若沒有圖紙預(yù)覽就沒有圖紙。
- 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
- 5. 人人文庫網(wǎng)僅提供信息存儲空間,僅對用戶上傳內(nèi)容的表現(xiàn)方式做保護(hù)處理,對用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對任何下載內(nèi)容負(fù)責(zé)。
- 6. 下載文件中如有侵權(quán)或不適當(dāng)內(nèi)容,請與我們聯(lián)系,我們立即糾正。
- 7. 本站不保證下載資源的準(zhǔn)確性、安全性和完整性, 同時也不承擔(dān)用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。
最新文檔
- 2025年中職第二學(xué)年(護(hù)理)老年照護(hù)專項試題及答案
- 2025年大學(xué)本科(食品質(zhì)量與安全)食品分析試題及答案
- 2025年大學(xué)食品科學(xué)與工程(食品工程)試題及答案
- 2025年中職焊接技術(shù)與自動化(手工焊接)試題及答案
- 養(yǎng)老院老人心理咨詢師培訓(xùn)制度
- 養(yǎng)老院心理慰藉制度
- 公共交通從業(yè)人員培訓(xùn)考核制度
- 2026年人工智能計算機(jī)視覺基礎(chǔ)知識題庫含答案
- 2026年刮痧師中醫(yī)理論考核試題含答案
- 2026年中級公共文化服務(wù)面試題及答案
- 土壤微生物群落結(jié)構(gòu)優(yōu)化研究
- 2024外研版四年級英語上冊Unit 4知識清單
- 四川省南充市2024-2025學(xué)年部編版七年級上學(xué)期期末歷史試題
- 國有企業(yè)三位一體推進(jìn)內(nèi)控風(fēng)控合規(guī)建設(shè)的問題和分析
- 急診預(yù)檢分診課件教學(xué)
- 2025年高二數(shù)學(xué)建模試題及答案
- 儲能集裝箱知識培訓(xùn)總結(jié)課件
- 幼兒園中班語言《雪房子》課件
- 房地產(chǎn)項目開發(fā)管理方案
- 堆垛車安全培訓(xùn)課件
- 貝林妥單抗護(hù)理要點
評論
0/150
提交評論