摘要:所以就有今天的話題利用注解對(duì)進(jìn)行校驗(yàn)。利用注解對(duì)進(jìn)行校驗(yàn),主要是利用框架,實(shí)現(xiàn)了的接口關(guān)于校驗(yàn)的接口,直接使用非常方便,省時(shí)省力。
最近寫業(yè)務(wù)代碼,因?yàn)轫撁鎻?fù)雜,導(dǎo)致對(duì)應(yīng)的Bean屬性非常多,而產(chǎn)品大佬又提出各種校驗(yàn)要求。
emmmmmm......如果寫if條件來校驗(yàn),那簡直是又臭又長。
所以就有今天的話題——利用注解對(duì)Bean進(jìn)行校驗(yàn)。
利用注解對(duì)Bean進(jìn)行校驗(yàn),主要是利用hibernate-validator框架,hibernate-validator實(shí)現(xiàn)了validation-api的接口關(guān)于Bean校驗(yàn)的接口,直接使用hibernate-validator非常方便,省時(shí)省力。
1.hibernate-validato簡介此hibernate-validator+SpringMVC可以實(shí)現(xiàn)以下功能:
注解java bean聲明校驗(yàn)規(guī)則;
添加message錯(cuò)誤信息源實(shí)現(xiàn)國際化配置;
結(jié)合spring form中的errors標(biāo)簽展現(xiàn)錯(cuò)誤信息。
優(yōu)勢:
代碼簡潔、處理校驗(yàn)可以更加優(yōu)雅。
實(shí)現(xiàn)要求:
使用hibernate validator至少要引入兩個(gè)jar包:
org.hibernate.validator hibernate-validator 6.0.1.Final org.glassfish javax.el 3.0.1-b08
java bean中使用注解添加檢驗(yàn)規(guī)則。
2.注解及用法hibernate validator使用的注解定義在hibernate-validator-6.0.1.Final.jar、validation-api-1.1.0.Final.jar兩個(gè)包中,
@AssertFalse 驗(yàn)證注解的元素值是false @AssertTrue 驗(yàn)證注解的元素值是true @DecimalMax(value=x) 驗(yàn)證注解的元素值小于等于@ DecimalMax指定的value值 @DecimalMin(value=x) 驗(yàn)證注解的元素值小于等于@ DecimalMin指定的value值 @Digits(integer=整數(shù)位數(shù), fraction=小數(shù)位數(shù)) 驗(yàn)證注解的元素值的整數(shù)位數(shù)和小數(shù)位數(shù)上限 @Future 驗(yàn)證注解的元素值(日期類型)比當(dāng)前時(shí)間晚 @Max(value=x) 驗(yàn)證注解的元素值小于等于@Max指定的value值 @Min(value=x) 驗(yàn)證注解的元素值大于等于@Min指定的value值 @NotNull 驗(yàn)證注解的元素值不是null @Null 驗(yàn)證注解的元素值是null @Past 驗(yàn)證注解的元素值(日期類型)比當(dāng)前時(shí)間早 @Pattern(regex=正則表達(dá)式, flag=) 驗(yàn)證注解的元素值與指定的正則表達(dá)式匹配 @Size(min=最小值, max=最大值) 驗(yàn)證注解的元素值的在min和max(包含)指定區(qū)間之內(nèi),如字符長度、集合大小 @Valid 驗(yàn)證關(guān)聯(lián)的對(duì)象,如賬戶對(duì)象里有一個(gè)訂單對(duì)象,指定驗(yàn)證訂單對(duì)象 @NotEmpty 驗(yàn)證注解的元素值不為null且不為空(字符串長度不為0、集合大小不為0) @Range(min=最小值, max=最大值) 驗(yàn)證注解的元素值在最小值和最大值之間 @NotBlank 驗(yàn)證注解的元素值不為空(不為null、去除首位空格后長度為0),不同于@NotEmpty,@NotBlank只應(yīng)用于字符串且在比較時(shí)會(huì)去除字符串的空格 @Length(min=下限, max=上限) 驗(yàn)證注解的元素值長度在min和max區(qū)間內(nèi) @Email 驗(yàn)證注解的元素值是Email,也可以通過正則表達(dá)式和flag指定自定義的email格式3.校驗(yàn)demo
利用hibernate validator實(shí)現(xiàn)Bean校驗(yàn),一般有兩種做法:
利用@ModelAttribute和@Valid注解;
利用validate()、validateValue()、validateProperty()等方法在需要之處直接調(diào)用。
Bean對(duì)象:
import javax.validation.constraints.Min; import javax.validation.constraints.NotNull; import javax.validation.constraints.Size; public class Car { @NotNull private String manufacturer; @NotNull @Size(min = 2, max = 14) private String licensePlate; @Min(2) private int seatCount; public Car(String manufacturer, String licencePlate, int seatCount) { this.manufacturer = manufacturer; this.licensePlate = licencePlate; this.seatCount = seatCount; } //getters and setters ... }3.1.利用Validator的validate()方法
驗(yàn)證器
import org.apache.commons.collections4.CollectionUtils; import javax.validation.ConstraintViolation; import javax.validation.Validation; import javax.validation.Validator; import java.util.Set; public class ValidateTest { /** * 驗(yàn)證器 */ private static Validator validator = Validation.buildDefaultValidatorFactory().getValidator(); public static void main(String[] args) { Car car = new Car(null, "12", 1); //執(zhí)行驗(yàn)證 Set> constraintViolations = validator.validate(car); //打印校驗(yàn)信息 if (CollectionUtils.isNotEmpty(constraintViolations)) { for (ConstraintViolation constraintViolation : constraintViolations) { System.out.println(constraintViolation.getPropertyPath().toString() + ": " + constraintViolation.getMessage()); } } } }
輸出結(jié)果:
seatCount: 最小不能小于2 manufacturer: 不能為null3.2.利用@ModelAttribute和@Valid注解和BindingResult對(duì)象
校驗(yàn)demo
import org.springframework.stereotype.Controller; import org.springframework.validation.BindingResult; import org.springframework.validation.ObjectError; import org.springframework.web.bind.annotation.ModelAttribute; import org.springframework.web.bind.annotation.RequestMapping; import javax.validation.Valid; @Controller("/Validate") public class ValidateTestController { @RequestMapping("/demo1") public void validateDemo(@Valid @ModelAttribute("car") Car car, BindingResult result) { if(result.hasErrors()){ for (ObjectError error : result.getAllErrors()) { System.out.println(error.getDefaultMessage()); } } } }
測試數(shù)據(jù):
{ "manufacturer": null, "licensePlate": "", "seatCount": 1 }
結(jié)果:
不能為null 個(gè)數(shù)必須在2和14之間 最小不能小于2
注意,需要加上@ModelAttribute注解,否則會(huì)報(bào)錯(cuò): An Error/BindingResult argument is3.3.利用@Valid注解和統(tǒng)一異常處理
expected to be declared immediately after the model attribute
校驗(yàn)demo
import org.springframework.stereotype.Controller; import org.springframework.web.bind.annotation.RequestMapping; import javax.validation.Valid; @Controller @RequestMapping("/validate") public class ValidateTestController { @RequestMapping("/demo1") public void validateDemo(@Valid Car car) { } }
測試數(shù)據(jù):
{ "manufacturer": null, "licensePlate": "", "seatCount": 1 }
統(tǒng)一異常處理類:
@Component public class ExceptionResolver implements HandlerExceptionResolver { /** * 日志 */ private static final Logger LOG = LoggerFactory.getLogger(AuditCommonExceptionResolver.class); @Override public ModelAndView resolveException(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) { if (ex instanceof BindException) { BindException exs = (BindException) ex; for (ObjectError o : exs.getAllErrors()) { System.out.println(o.getDefaultMessage()); } } else if (ex instanceof ConstraintViolationException) { ConstraintViolationException exs = (ConstraintViolationException) ex; Set> violations = exs.getConstraintViolations(); for (ConstraintViolation> item : violations) { System.out.println(item.getMessage()); } } else { LOG.error("捕獲未處理異常,異常信息:{}", ex.getMessage()); } return new ModelAndView("/sys/errorPage.jsp"); } }
結(jié)果:
不能為null 個(gè)數(shù)必須在2和14之間 最小不能小于2
注意:我自己測試的時(shí)候,捕獲的是BindException異常,但是看網(wǎng)上好多文章寫的都是捕獲ConstraintViolationException異常,
比較以上三種校驗(yàn)方式(準(zhǔn)確的說應(yīng)該是三種hibernate validator的使用方式),可以發(fā)現(xiàn)2、3大同小異,使用@Valid可以不用再自己寫校驗(yàn)的處理方法,但是方式1可以更加靈活,可以按照自己需求處理和組織校驗(yàn)的返回信息。
4.hibernate validator更詳細(xì)的使用文檔hibernate validator的更詳細(xì)的使用說明,可以參考官方文檔,以前沒關(guān)注,這次認(rèn)真的看了一下,發(fā)現(xiàn)hibernate validator的功能還是很強(qiáng)大的,最新的5.0、6.0版本只有英文文檔,4.0版本有中文文檔。地址如下:https://docs.jboss.org/hibern...
5.使用過程中遇到的問題使用方式1,在我自己電腦注解沒有添加message信息時(shí),默認(rèn)返回的是中文,如@NotNull:不能為null,@NotEmpty:不能為空等等,但是,當(dāng)部署到服務(wù)器以后,就變成英文,如@NotNull:may not be null,@NotEmpty:may not be empty等等,很是詭異。后來研讀源碼發(fā)現(xiàn),hibernate validator通過messageInterpolator字段來實(shí)現(xiàn)國際化的,messageInterpolator字段中存放著當(dāng)前操作系統(tǒng)的語言環(huán)境參數(shù),然后根據(jù)語言環(huán)境參數(shù)去對(duì)應(yīng)的配置文檔中讀取默認(rèn)提示信息,而messageInterpolator則會(huì)在項(xiàng)目啟動(dòng)時(shí)初始化,因?yàn)槲易约旱碾娔X是中文環(huán)境,而公司的系統(tǒng)環(huán)境是英文的,所以導(dǎo)致這個(gè)問題。
文章版權(quán)歸作者所有,未經(jīng)允許請(qǐng)勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。
轉(zhuǎn)載請(qǐng)注明本文地址:http://systransis.cn/yun/75290.html
摘要:如果說要使用數(shù)據(jù)校驗(yàn),我十分相信小伙伴們都能夠使用,但估計(jì)大都是有個(gè)前提的環(huán)境。具體使用可參考小家讓支持對(duì)平鋪參數(shù)執(zhí)行數(shù)據(jù)校驗(yàn)?zāi)J(rèn)使用只能對(duì)進(jìn)行校驗(yàn)級(jí)聯(lián)校驗(yàn)什么叫級(jí)聯(lián)校驗(yàn),其實(shí)就是帶校驗(yàn)的成員里存在級(jí)聯(lián)對(duì)象時(shí),也要對(duì)它完成校驗(yàn)。 每篇一句 NBA里有兩大笑話:一是科比沒天賦,二是詹姆斯沒技術(shù) 相關(guān)閱讀 【小家Java】深入了解數(shù)據(jù)校驗(yàn):Java Bean Validation 2.0(...
摘要:我們可不可以提供一個(gè)公共的入口進(jìn)行統(tǒng)一的異常處理呢當(dāng)然可以。一般我們可以在地址上帶上版本號(hào),也可以在參數(shù)上帶上版本號(hào),還可以再里帶上版本號(hào),這里我們?cè)诘刂飞蠋习姹咎?hào),大致的地址如,其中,即代表的是版本號(hào)。 上一篇帶領(lǐng)大家初步了解了如何使用 Spring Boot 搭建框架,通過 Spring Boot 和傳統(tǒng)的 SpringMVC 架構(gòu)的對(duì)比,我們清晰地發(fā)現(xiàn) Spring Boot ...
摘要:和上標(biāo)注的約束都會(huì)被執(zhí)行注意如果子類覆蓋了父類的方法,那么子類和父類的約束都會(huì)被校驗(yàn)。 每篇一句 沒有任何技術(shù)方案會(huì)是一種銀彈,任何東西都是有利弊的 相關(guān)閱讀 【小家Java】深入了解數(shù)據(jù)校驗(yàn):Java Bean Validation 2.0(JSR303、JSR349、JSR380)Hibernate-Validation 6.x使用案例【小家Spring】Spring方法級(jí)別數(shù)據(jù)校...
摘要:動(dòng)態(tài)代理的核心是接口和類。以上結(jié)果說明它生成的代理類為,說明是代理。測試前提實(shí)現(xiàn)接口測試類使用接口方式注入代理方式必須以接口方式注入測試配置為,運(yùn)行結(jié)果如下實(shí)際校驗(yàn)邏輯。。。。 本文也同步發(fā)布至簡書,地址:https://www.jianshu.com/p/f70... AOP設(shè)計(jì)模式通常運(yùn)用在日志,校驗(yàn)等業(yè)務(wù)場景,本文將簡單介紹基于Spring的AOP代理模式的運(yùn)用。 1. 代理模...
摘要:前言估計(jì)很多朋友都認(rèn)為參數(shù)校驗(yàn)是客戶端的職責(zé),不關(guān)服務(wù)端的事。輕則導(dǎo)致服務(wù)器宕機(jī),重則泄露數(shù)據(jù)。所以,這時(shí)就需要設(shè)置第二道關(guān)卡,服務(wù)端驗(yàn)證了。老項(xiàng)目的服務(wù)端校驗(yàn)不能為空不能為空看以上代碼,就一個(gè)的校驗(yàn)就如此麻煩。 前言 估計(jì)很多朋友都認(rèn)為參數(shù)校驗(yàn)是客戶端的職責(zé),不關(guān)服務(wù)端的事。其實(shí)這是錯(cuò)誤的,學(xué)過 Web 安全的都知道,客戶端的驗(yàn)證只是第一道關(guān)卡。它的參數(shù)驗(yàn)證并不是安全的,一旦被有心人...
閱讀 1802·2021-09-22 15:10
閱讀 1316·2021-09-07 09:58
閱讀 2366·2019-08-30 15:44
閱讀 1667·2019-08-26 18:29
閱讀 2072·2019-08-26 13:35
閱讀 785·2019-08-26 13:31
閱讀 745·2019-08-26 11:42
閱讀 1099·2019-08-23 18:39