一区二区三区在线-一区二区三区亚洲视频-一区二区三区亚洲-一区二区三区午夜-一区二区三区四区在线视频-一区二区三区四区在线免费观看

服務(wù)器之家:專注于服務(wù)器技術(shù)及軟件下載分享
分類導(dǎo)航

PHP教程|ASP.NET教程|JAVA教程|ASP教程|編程技術(shù)|正則表達(dá)式|C/C++|IOS|C#|Swift|Android|JavaScript|易語(yǔ)言|

服務(wù)器之家 - 編程語(yǔ)言 - JAVA教程 - springboot使用hibernate validator校驗(yàn)方式

springboot使用hibernate validator校驗(yàn)方式

2021-03-23 14:23Mr.yang.localhost JAVA教程

hibernate validator提供了一套比較完善、便捷的驗(yàn)證實(shí)現(xiàn)方式。下面小編給大家介紹下springboot使用hibernate validator校驗(yàn)方式,感興趣的朋友一起看看吧

一、參數(shù)校驗(yàn)

 在開發(fā)中經(jīng)常需要寫一些字段校驗(yàn)的代碼,比如字段非空,字段長(zhǎng)度限制,郵箱格式驗(yàn)證等等,寫這些與業(yè)務(wù)邏輯關(guān)系不大的代碼個(gè)人感覺有兩個(gè)麻煩:

  • 驗(yàn)證代碼繁瑣,重復(fù)勞動(dòng)
  • 方法內(nèi)代碼顯得冗長(zhǎng)
  • 每次要看哪些參數(shù)驗(yàn)證是否完整,需要去翻閱驗(yàn)證邏輯代碼

hibernate validator官方文檔)提供了一套比較完善、便捷的驗(yàn)證實(shí)現(xiàn)方式。

spring-boot-starter-web包里面有hibernate-validator包,不需要引用hibernate validator依賴。

二、hibernate validator校驗(yàn)demo

 先來看一個(gè)簡(jiǎn)單的demo,添加了Validator的注解:

?
1
2
3
import org.hibernate.validator.constraints.NotBlank;
import javax.validation.constraints.AssertFalse;
import javax.validation.constraints.Pattern;
?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
@Getter
@Setter
@NoArgsConstructor
public class DemoModel {
 @NotBlank(message="用戶名不能為空")
 private String userName;
 @NotBlank(message="年齡不能為空")
 @Pattern(regexp="^[0-9]{1,2}$",message="年齡不正確")
 private String age;
 @AssertFalse(message = "必須為false")
 private Boolean isFalse;
 /**
 * 如果是空,則不校驗(yàn),如果不為空,則校驗(yàn)
 */
 @Pattern(regexp="^[0-9]{4}-[0-9]{2}-[0-9]{2}$",message="出生日期格式不正確")
 private String birthday;
}

POST接口驗(yàn)證,BindingResult是驗(yàn)證不通過的結(jié)果集合:

?
1
2
3
4
5
6
7
8
@RequestMapping("/demo2")
public void demo2(@RequestBody @Valid DemoModel demo, BindingResult result){
if(result.hasErrors()){
 for (ObjectError error : result.getAllErrors()) {
 System.out.println(error.getDefaultMessage());
 }
}
}

POST請(qǐng)求傳入的參數(shù):{"userName":"dd","age":120,"isFalse":true,"birthday":"21010-21-12"}

輸出結(jié)果:

出生日期格式不正確
必須為false
年齡不正確

 參數(shù)驗(yàn)證非常方便,字段上注解+驗(yàn)證不通過提示信息即可代替手寫一大堆的非空和字段限制驗(yàn)證代碼。下面深入了解下參數(shù)校驗(yàn)的玩法。

三、hibernate的校驗(yàn)?zāi)J?/strong>

細(xì)心的讀者肯定發(fā)現(xiàn)了:上面例子中一次性返回了所有驗(yàn)證不通過的集合,通常按順序驗(yàn)證到第一個(gè)字段不符合驗(yàn)證要求時(shí),就可以直接拒絕請(qǐng)求了。Hibernate Validator有以下兩種驗(yàn)證模式:

1、普通模式(默認(rèn)是這個(gè)模式)

  普通模式(會(huì)校驗(yàn)完所有的屬性,然后返回所有的驗(yàn)證失敗信息)

2、快速失敗返回模式

  快速失敗返回模式(只要有一個(gè)驗(yàn)證失敗,則返回)

兩種驗(yàn)證模式配置方式:(參考官方文檔

failFast:true  快速失敗返回模式    false 普通模式

?
1
2
3
4
5
ValidatorFactory validatorFactory = Validation.byProvider( HibernateValidator.class )
 .configure()
 .failFast( true )
 .buildValidatorFactory();
Validator validator = validatorFactory.getValidator();

和 (hibernate.validator.fail_fast:true  快速失敗返回模式    false 普通模式)

?
1
2
3
4
5
ValidatorFactory validatorFactory = Validation.byProvider( HibernateValidator.class )
 .configure()
 .addProperty( "hibernate.validator.fail_fast", "true" )
 .buildValidatorFactory();
Validator validator = validatorFactory.getValidator();

四、hibernate的兩種校驗(yàn)

配置hibernate Validator為快速失敗返回模式:

?
1
2
3
4
5
6
7
8
9
10
11
12
@Configuration
public class ValidatorConfiguration {
 @Bean
 public Validator validator(){
 ValidatorFactory validatorFactory = Validation.byProvider( HibernateValidator.class )
  .configure()
  .addProperty( "hibernate.validator.fail_fast", "true" )
  .buildValidatorFactory();
 Validator validator = validatorFactory.getValidator();
 return validator;
 }
}

1、請(qǐng)求參數(shù)校驗(yàn)

如demo里示例的,驗(yàn)證請(qǐng)求參數(shù)時(shí),在@RequestBody DemoModel demo之間加注解 @Valid,然后后面加BindindResult即可;多個(gè)參數(shù)的,可以加多個(gè)@Valid和BindingResult,如:

?
1
2
public void test()(@RequestBody @Valid DemoModel demo, BindingResult result)
public void test()(@RequestBody @Valid DemoModel demo, BindingResult result,@RequestBody @Valid DemoModel demo2, BindingResult result2)
?
1
2
3
4
5
6
7
8
@RequestMapping("/demo2")
public void demo2(@RequestBody @Valid DemoModel demo, BindingResult result){
if(result.hasErrors()){
 for (ObjectError error : result.getAllErrors()) {
 System.out.println(error.getDefaultMessage());
 }
}
}

2、GET參數(shù)校驗(yàn)(@RequestParam參數(shù)校驗(yàn))

使用校驗(yàn)bean的方式,沒有辦法校驗(yàn)RequestParam的內(nèi)容,一般在處理Get請(qǐng)求(或參數(shù)比較少)的時(shí)候,會(huì)使用下面這樣的代碼:

?
1
2
3
4
@RequestMapping(value = "/demo3", method = RequestMethod.GET)
public void demo3(@RequestParam(name = "grade", required = true) int grade,@RequestParam(name = "classroom", required = true) int classroom) {
System.out.println(grade + "," + classroom);
}

使用@Valid注解,對(duì)RequestParam對(duì)應(yīng)的參數(shù)進(jìn)行注解,是無效的,需要使用@Validated注解來使得驗(yàn)證生效。如下所示:

a.此時(shí)需要使用MethodValidationPostProcessor 的Bean:

?
1
2
3
4
5
@Bean
public MethodValidationPostProcessor methodValidationPostProcessor() {
    /**默認(rèn)是普通模式,會(huì)返回所有的驗(yàn)證不通過信息集合*/
return new MethodValidationPostProcessor();
}

或 可對(duì)MethodValidationPostProcessor 進(jìn)行設(shè)置Validator(因?yàn)榇藭r(shí)不是用的Validator進(jìn)行驗(yàn)證,Validator的配置不起作用)

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
@Bean
 public MethodValidationPostProcessor methodValidationPostProcessor() {
 MethodValidationPostProcessor postProcessor = new MethodValidationPostProcessor();
     /**設(shè)置validator模式為快速失敗返回*/
 postProcessor.setValidator(validator());
 return postProcessor;
 }
 @Bean
 public Validator validator(){
 ValidatorFactory validatorFactory = Validation.byProvider( HibernateValidator.class )
  .configure()
  .addProperty( "hibernate.validator.fail_fast", "true" )
  .buildValidatorFactory();
 Validator validator = validatorFactory.getValidator();
 return validator;
 }

b.方法所在的Controller上加注解@Validated

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
@RequestMapping("/validation")
@RestController
@Validated
public class ValidationController {
 /**如果只有少數(shù)對(duì)象,直接把參數(shù)寫到Controller層,然后在Controller層進(jìn)行驗(yàn)證就可以了。*/
 @RequestMapping(value = "/demo3", method = RequestMethod.GET)
 public void demo3(@Range(min = 1, max = 9, message = "年級(jí)只能從1-9")
   @RequestParam(name = "grade", required = true)
   int grade,
   @Min(value = 1, message = "班級(jí)最小只能1")
   @Max(value = 99, message = "班級(jí)最大只能99")
   @RequestParam(name = "classroom", required = true)
   int classroom) {
 System.out.println(grade + "," + classroom);
 }
}

c.返回驗(yàn)證信息提示

可以看到:驗(yàn)證不通過時(shí),拋出了ConstraintViolationException異常,使用同一捕獲異常處理:

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
@ControllerAdvice
@Component
public class GlobalExceptionHandler {
 @ExceptionHandler
 @ResponseBody
 @ResponseStatus(HttpStatus.BAD_REQUEST)
 public String handle(ValidationException exception) {
 if(exception instanceof ConstraintViolationException){
  ConstraintViolationException exs = (ConstraintViolationException) exception;
  Set<ConstraintViolation<?>> violations = exs.getConstraintViolations();
  for (ConstraintViolation<?> item : violations) {
          /**打印驗(yàn)證不通過的信息*/
  System.out.println(item.getMessage());
  }
 }
 return "bad request, " ;
 }
}

d.驗(yàn)證

瀏覽器服務(wù)請(qǐng)求地址:http://localhost:8080/validation/demo3?grade=18&classroom=888

沒有配置快速失敗返回的MethodValidationPostProcessor 時(shí)輸出信息如下:

年級(jí)只能從1-9
班級(jí)最大只能99

配置了快速失敗返回的MethodValidationPostProcessor 時(shí)輸出信息如下:

年級(jí)只能從1-9

瀏覽器服務(wù)請(qǐng)求地址:http://localhost:8080/validation/demo3?grade=0&classroom=0

沒有配置快速失敗返回的MethodValidationPostProcessor 時(shí)輸出信息如下:

年級(jí)只能從1-9
班級(jí)最小只能1

配置了快速失敗返回的MethodValidationPostProcessor 時(shí)輸出信息如下:

年級(jí)只能從1-9

3、model校驗(yàn)

待校驗(yàn)的model:

?
1
2
3
4
5
6
7
8
9
10
11
12
@Data
public class Demo2 {
 @Length(min = 5, max = 17, message = "length長(zhǎng)度在[5,17]之間")
 private String length;
 /**@Size不能驗(yàn)證Integer,適用于String, Collection, Map and arrays*/
 @Size(min = 1, max = 3, message = "size在[1,3]之間")
 private String age;
 @Range(min = 150, max = 250, message = "range在[150,250]之間")
 private int high;
 @Size(min = 3,max = 5,message = "list的Size在[3,5]")
 private List<String> list;
}

驗(yàn)證model,以下全部驗(yàn)證通過:

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
@Autowired
private Validator validator;
@RequestMapping("/demo3")
public void demo3(){
Demo2 demo2 = new Demo2();
demo2.setAge("111");
demo2.setHigh(150);
demo2.setLength("ABCDE");
demo2.setList(new ArrayList<String>(){{add("111");add("222");add("333");}});
Set<ConstraintViolation<Demo2>> violationSet = validator.validate(demo2);
for (ConstraintViolation<Demo2> model : violationSet) {
 System.out.println(model.getMessage());
}
}

4、對(duì)象級(jí)聯(lián)校驗(yàn)

對(duì)象內(nèi)部包含另一個(gè)對(duì)象作為屬性,屬性上加@Valid,可以驗(yàn)證作為屬性的對(duì)象內(nèi)部的驗(yàn)證:(驗(yàn)證Demo2示例時(shí),可以驗(yàn)證Demo2的字段)

?
1
2
3
4
5
6
7
8
9
10
11
12
13
@Data
public class Demo2 {
 @Size(min = 3,max = 5,message = "list的Size在[3,5]")
 private List<String> list;
 @NotNull
 @Valid
 private Demo3 demo3;
}
@Data
public class Demo3 {
 @Length(min = 5, max = 17, message = "length長(zhǎng)度在[5,17]之間")
 private String extField;
}

級(jí)聯(lián)校驗(yàn):

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
/**前面配置了快速失敗返回的Bean*/
@Autowired
private Validator validator;
@RequestMapping("/demo3")
public void demo3(){
Demo2 demo2 = new Demo2();
demo2.setList(new ArrayList<String>(){{add("111");add("222");add("333");}});
Demo3 demo3 = new Demo3();
demo3.setExtField("22");
demo2.setDemo3(demo3);
Set<ConstraintViolation<Demo2>> violationSet = validator.validate(demo2);
for (ConstraintViolation<Demo2> model : violationSet) {
 System.out.println(model.getMessage());
}
}

可以校驗(yàn)Demo3的extField字段。

5、分組校驗(yàn)

結(jié)論:分組順序校驗(yàn)時(shí),按指定的分組先后順序進(jìn)行驗(yàn)證,前面的驗(yàn)證不通過,后面的分組就不行驗(yàn)證。

有這樣一種場(chǎng)景,新增用戶信息的時(shí)候,不需要驗(yàn)證userId(因?yàn)橄到y(tǒng)生成);修改的時(shí)候需要驗(yàn)證userId,這時(shí)候可用用戶到validator的分組驗(yàn)證功能。

設(shè)置validator為普通驗(yàn)證模式("hibernate.validator.fail_fast", "false"),用到的驗(yàn)證GroupA、GroupB和model:

?
1
2
3
4
5
GroupA、GroupB:
public interface GroupA {
}
public interface GroupB {
}

驗(yàn)證model:Person

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
@Data
public class Person {
 @NotBlank
 @Range(min = 1,max = Integer.MAX_VALUE,message = "必須大于0",groups = {GroupA.class})
 /**用戶id*/
 private Integer userId;
 @NotBlank
 @Length(min = 4,max = 20,message = "必須在[4,20]",groups = {GroupB.class})
 /**用戶名*/
 private String userName;
 @NotBlank
 @Range(min = 0,max = 100,message = "年齡必須在[0,100]",groups={Default.class})
 /**年齡*/
 private Integer age;
 @Range(min = 0,max = 2,message = "性別必須在[0,2]",groups = {GroupB.class})
 /**性別 0:未知;1:男;2:女*/
 private Integer sex;
}

如上Person所示,3個(gè)分組分別驗(yàn)證字段如下:

  • GroupA驗(yàn)證字段userId;
  • GroupB驗(yàn)證字段userName、sex;
  • Default驗(yàn)證字段age(Default是Validator自帶的默認(rèn)分組)
  •  

a、分組

只驗(yàn)證GroupA、GroupB標(biāo)記的分組:

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
@RequestMapping("/demo5")
public void demo5(){
 Person p = new Person();
 /**GroupA驗(yàn)證不通過*/
 p.setUserId(-12);
 /**GroupA驗(yàn)證通過*/
 //p.setUserId(12);
 p.setUserName("a");
 p.setAge(110);
 p.setSex(5);
 Set<ConstraintViolation<Person>> validate = validator.validate(p, GroupA.class, GroupB.class);
 for (ConstraintViolation<Person> item : validate) {
 System.out.println(item);
 }
}

?
1
2
3
4
5
6
7
8
9
@RequestMapping("/demo6")
public void demo6(@Validated({GroupA.class, GroupB.class}) Person p, BindingResult result){
if(result.hasErrors()){
 List<ObjectError> allErrors = result.getAllErrors();
 for (ObjectError error : allErrors) {
 System.out.println(error);
 }
}
}

GroupA、GroupB、Default都驗(yàn)證不通過的情況:

驗(yàn)證信息如下所示:

?
1
2
3
ConstraintViolationImpl{interpolatedMessage='必須在[4,20]', propertyPath=userName, rootBeanClass=class validator.demo.project.model.Person, messageTemplate='必須在[4,20]'}
ConstraintViolationImpl{interpolatedMessage='必須大于0', propertyPath=userId, rootBeanClass=class validator.demo.project.model.Person, messageTemplate='必須大于0'}
ConstraintViolationImpl{interpolatedMessage='性別必須在[0,2]', propertyPath=sex, rootBeanClass=class validator.demo.project.model.Person, messageTemplate='性別必須在[0,2]'}

GroupA驗(yàn)證通過、GroupB、Default驗(yàn)證不通過的情況:

驗(yàn)證信息如下所示:

?
1
2
ConstraintViolationImpl{interpolatedMessage='必須在[4,20]', propertyPath=userName, rootBeanClass=class validator.demo.project.model.Person, messageTemplate='必須在[4,20]'}
ConstraintViolationImpl{interpolatedMessage='性別必須在[0,2]', propertyPath=sex, rootBeanClass=class validator.demo.project.model.Person, messageTemplate='性別必須在[0,2]'}

b、組序列

除了按組指定是否驗(yàn)證之外,還可以指定組的驗(yàn)證順序,前面組驗(yàn)證不通過的,后面組不進(jìn)行驗(yàn)證:

指定組的序列(GroupA》GroupB》Default):

?
1
2
3
@GroupSequence({GroupA.class, GroupB.class, Default.class})
public interface GroupOrder {
}

測(cè)試demo:

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
@RequestMapping("/demo7")
public void demo7(){
Person p = new Person();
/**GroupA驗(yàn)證不通過*/
//p.setUserId(-12);
/**GroupA驗(yàn)證通過*/
p.setUserId(12);
p.setUserName("a");
p.setAge(110);
p.setSex(5);
Set<ConstraintViolation<Person>> validate = validator.validate(p, GroupOrder.class);
for (ConstraintViolation<Person> item : validate) {
 System.out.println(item);
}
}

?
1
2
3
4
5
6
7
8
9
@RequestMapping("/demo8")
public void demo8(@Validated({GroupOrder.class}) Person p, BindingResult result){
if(result.hasErrors()){
 List<ObjectError> allErrors = result.getAllErrors();
 for (ObjectError error : allErrors) {
 System.out.println(error);
 }
}
}

GroupA、GroupB、Default都驗(yàn)證不通過的情況:

驗(yàn)證信息如下所示:

?
1
ConstraintViolationImpl{interpolatedMessage='必須大于0', propertyPath=userId, rootBeanClass=class validator.demo.project.model.Person, messageTemplate='必須大于0'}

GroupA驗(yàn)證通過、GroupB、Default驗(yàn)證不通過的情況:

驗(yàn)證信息如下所示:

?
1
2
ConstraintViolationImpl{interpolatedMessage='必須在[4,20]', propertyPath=userName, rootBeanClass=class validator.demo.project.model.Person, messageTemplate='必須在[4,20]'}
ConstraintViolationImpl{interpolatedMessage='性別必須在[0,2]', propertyPath=sex, rootBeanClass=class validator.demo.project.model.Person, messageTemplate='性別必須在[0,2]'}

結(jié)論:分組順序校驗(yàn)時(shí),按指定的分組先后順序進(jìn)行驗(yàn)證,前面的驗(yàn)證不通過,后面的分組就不行驗(yàn)證。

五、自定義驗(yàn)證器

一般情況,自定義驗(yàn)證可以解決很多問題。但也有無法滿足情況的時(shí)候,此時(shí),我們可以實(shí)現(xiàn)validator的接口,自定義自己需要的驗(yàn)證器。

如下所示,實(shí)現(xiàn)了一個(gè)自定義的大小寫驗(yàn)證器:

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
public enum CaseMode {
 UPPER,
 LOWER;
}
@Target( { ElementType.METHOD, ElementType.FIELD, ElementType.ANNOTATION_TYPE })
@Retention(RetentionPolicy.RUNTIME)
@Constraint(validatedBy = CheckCaseValidator.class)
@Documented
public @interface CheckCase {
 String message() default "";
 Class<?>[] groups() default {};
 Class<? extends Payload>[] payload() default {};
 CaseMode value();
}
public class CheckCaseValidator implements ConstraintValidator<CheckCase, String> {
 private CaseMode caseMode;
 public void initialize(CheckCase checkCase) {
 this.caseMode = checkCase.value();
 }
 public boolean isValid(String s, ConstraintValidatorContext constraintValidatorContext) {
 if (s == null) {
  return true;
 }
 if (caseMode == CaseMode.UPPER) {
  return s.equals(s.toUpperCase());
 } else {
  return s.equals(s.toLowerCase());
 }
 }
}

要驗(yàn)證的Model:

?
1
2
3
4
5
6
7
8
9
10
public class Demo{
@CheckCase(value = CaseMode.LOWER,message = "userName必須是小寫")
private String userName;
public String getUserName() {
 return userName;
}
public void setUserName(String userName) {
 this.userName = userName;
}
}

validator配置:

?
1
2
3
4
5
6
7
8
9
@Bean
 public Validator validator(){
 ValidatorFactory validatorFactory = Validation.byProvider( HibernateValidator.class )
  .configure()
  .addProperty( "hibernate.validator.fail_fast", "true" )
  .buildValidatorFactory();
 Validator validator = validatorFactory.getValidator();
 return validator;
 }

驗(yàn)證測(cè)試:

?
1
2
3
4
5
6
7
8
9
@RequestMapping("/demo4")
public void demo4(){
Demo demo = new Demo();
demo.setUserName("userName");
Set<ConstraintViolation<Demo>> validate = validator.validate(demo);
for (ConstraintViolation<Demo> dem : validate) {
 System.out.println(dem.getMessage());
}
}

輸出結(jié)果:

userName必須是小寫

六、常見的注解

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
Bean Validation 中內(nèi)置的 constraint
@Null 被注釋的元素必須為 null
@NotNull 被注釋的元素必須不為 null
@AssertTrue 被注釋的元素必須為 true
@AssertFalse 被注釋的元素必須為 false
@Min(value) 被注釋的元素必須是一個(gè)數(shù)字,其值必須大于等于指定的最小值
@Max(value) 被注釋的元素必須是一個(gè)數(shù)字,其值必須小于等于指定的最大值
@DecimalMin(value) 被注釋的元素必須是一個(gè)數(shù)字,其值必須大于等于指定的最小值
@DecimalMax(value) 被注釋的元素必須是一個(gè)數(shù)字,其值必須小于等于指定的最大值
@Size(max=, min=) 被注釋的元素的大小必須在指定的范圍內(nèi)
@Digits (integer, fraction) 被注釋的元素必須是一個(gè)數(shù)字,其值必須在可接受的范圍內(nèi)
@Past 被注釋的元素必須是一個(gè)過去的日期
@Future 被注釋的元素必須是一個(gè)將來的日期
@Pattern(regex=,flag=) 被注釋的元素必須符合指定的正則表達(dá)式
Hibernate Validator 附加的 constraint
@NotBlank(message =) 驗(yàn)證字符串非null,且長(zhǎng)度必須大于0
@Email 被注釋的元素必須是電子郵箱地址
@Length(min=,max=) 被注釋的字符串的大小必須在指定的范圍內(nèi)
@NotEmpty 被注釋的字符串的必須非空
@Range(min=,max=,message=) 被注釋的元素必須在合適的范圍內(nèi)
//大于0.01,不包含0.01
@NotNull
@DecimalMin(value = "0.01", inclusive = false)
private Integer greaterThan;
//大于等于0.01
@NotNull
@DecimalMin(value = "0.01", inclusive = true)
private BigDecimal greatOrEqualThan;
@Length(min = 1, max = 20, message = "message不能為空")
//不能將Length錯(cuò)用成Range
//@Range(min = 1, max = 20, message = "message不能為空")
private String message;

七、參考資料

參考資料:

http://docs.jboss.org/hibernate/validator/4.2/reference/zh-CN/html_single/#validator-gettingstarted

原文鏈接:https://www.cnblogs.com/mr-yang-localhost/p/7812038.html

延伸 · 閱讀

精彩推薦
  • JAVA教程SpringBoot四大神器之Actuator的使用小結(jié)

    SpringBoot四大神器之Actuator的使用小結(jié)

    這篇文章主要介紹了SpringBoot四大神器之Actuator的使用小結(jié),詳細(xì)的介紹了Actuator的使用和端點(diǎn)的使用,有興趣的可以了解一下...

    xixicat7022021-02-06
  • JAVA教程如何完成spring的最小化XML配置

    如何完成spring的最小化XML配置

    這篇文章主要介紹了如何完成spring的最小化XML配置,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,,需要的朋友可以...

    fleyX3182019-06-27
  • JAVA教程Java中使用開源庫(kù)JSoup解析HTML文件實(shí)例

    Java中使用開源庫(kù)JSoup解析HTML文件實(shí)例

    這篇文章主要介紹了Java中使用開源庫(kù)JSoup解析HTML文件實(shí)例,Jsoup是一個(gè)開源的Java庫(kù),它可以用于處理實(shí)際應(yīng)用中的HTML,比如常見的HTML格式化就可以用它來實(shí)...

    junjie3332019-11-29
  • JAVA教程java在文件尾部追加內(nèi)容的簡(jiǎn)單實(shí)例

    java在文件尾部追加內(nèi)容的簡(jiǎn)單實(shí)例

    下面小編就為大家?guī)硪黄猨ava在文件尾部追加內(nèi)容的簡(jiǎn)單實(shí)例。小編覺得挺不錯(cuò)的,現(xiàn)在就分享給大家,也給大家做個(gè)參考。一起跟隨小編過來看看吧 ...

    java教程網(wǎng)2652020-07-11
  • JAVA教程JAVA 內(nèi)部類詳解及實(shí)例

    JAVA 內(nèi)部類詳解及實(shí)例

    這篇文章主要介紹了JAVA 內(nèi)部類詳解及實(shí)例的相關(guān)資料,需要的朋友可以參考下 ...

    java教程網(wǎng)2722020-07-06
  • JAVA教程java中hibernate二級(jí)緩存詳解

    java中hibernate二級(jí)緩存詳解

    本篇文章中主要介紹了java中hibernate二級(jí)緩存詳解,小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過來看看吧...

    SIHAIloveYAN3352020-09-25
  • JAVA教程JavaMe開發(fā)自適應(yīng)滾動(dòng)顯示

    JavaMe開發(fā)自適應(yīng)滾動(dòng)顯示

    我們常看到一些滾動(dòng)顯示的實(shí)例,比如UC瀏覽器中,顯示網(wǎng)頁(yè)的內(nèi)容。當(dāng)內(nèi)容比較多時(shí),采用滾動(dòng)分頁(yè)顯示是合理的。在Canvas中繪圖中,多余的內(nèi)容被截?cái)?..

    lijiao1912020-01-06
  • JAVA教程基于jdk1.8的Java源碼詳解 Integer

    基于jdk1.8的Java源碼詳解 Integer

    這篇文章主要介紹了基于jdk1.8的Java源碼詳解 Integer,Integer是int的Warpper類,是面向?qū)ο蟮募碠OP的對(duì)象類型,,需要的朋友可以參考下...

    rainple4832019-07-07
主站蜘蛛池模板: 亚洲欧美日韩精品久久亚洲区 | 超强台风免费观看完整版视频 | 午夜a一级毛片 | 欧美日韩高清完整版在线观看免费 | 国产里番 | 国产精品怡红院永久免费 | 日本xxxx18vr69| 亚洲va久久久久 | 好大用力深一点视频 | 毛片一级毛片 | 欧美性f | 5555kkkk香蕉在线观看 | 日本暖暖视频在线观看 | 精新精新国产自在现 | 99这里精品| 美女一线天| 性xxx欧美 | 久久午夜夜伦痒痒想咳嗽P 久久无码AV亚洲精品色午夜麻豆 | 国产精品第2页 | 俄罗斯妈妈k8影院在线观看 | 亚洲男人天 | mm131亚洲精品久久 | 青草视频网站在线观看 | 国产精品亚洲综合久久 | 亚洲六月丁香六月婷婷色伊人 | 91精品国产免费久久 | 韩国美女豪爽一级毛片 | 香蕉视频久久 | 四虎精品永久在线网址 | 日本在线观看免费观看完整版 | 波多野结衣两女调教 | 国产一区二区三区丶四区 | 免费网址视频在线看 | 欧洲女同同性videos0 | 欧美精品国产第一区二区 | 91最新高端约会系列178 | 四虎影视库永久在线地址 | 桃乃木香奈ipx在线播放 | 日本破处 | 无限好资源第一片免费韩国 | 精新精新国产自在现拍 |