java hibernate 校验_Hibernate Validator校验

1. 参数校验

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

2. hibernate validator校验demo

1. 导入包

import org.hibernate.validator.constraints.NotBlank;

import javax.validation.constraints.AssertFalse;

import javax.validation.constraints.Pattern;

2. demo

@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;

/**

* 如果是空,则不校验,如果不为空,则校验

*/

@Pattern(regexp="^[0-9]{4}-[0-9]{2}-[0-9]{2}$",message="出生日期格式不正确")

private String birthday;

}

3. 结果返回

@RequestMapping("/demo2")

public void demo2(@RequestBody @Valid DemoModel demo, BindingResult result){

if(result.hasErrors()){

for (ObjectError error : result.getAllErrors()) {

System.out.println(error.getDefaultMessage());

}

}

}

4. 传入参数

{"userName":"dd","age":120,"isFalse":true,"birthday":"21010-21-12"}

5. 输出结果

出生日期格式不正确

必须为false

年龄不正确

3. hibernate的校验模式

1. 普通模式(默认为该模式)

会校验所有属性,然后返回所有的验证失败信息。

2. 快速失败返回模式

只要有一个校验失败则返回。

3. 设置方式

// failFast: true 快速失败返回模式,false 普通模式

ValidatorFactory validatorFactory = Validation.byProvider( HibernateValidator.class )

.configure()

.failFast( true )

.buildValidatorFactory();

Validator validator = validatorFactory.getValidator();

// hibernate.validator.fail_fast: true 快速失败返回模式,false 普通模式

ValidatorFactory validatorFactory = Validation.byProvider( HibernateValidator.class )

.configure()

.addProperty( "hibernate.validator.fail_fast", "true" )

.buildValidatorFactory();

Validator validator = validatorFactory.getValidator();

4. hibernate的校验

配置hibernate Validator为快速返回模式: @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. 请求参数校验

验证请求参数时,在 @RequestBody DemoModel demo 之间加注解 @Valid,然后在后面加 BindindResult 即可;多个参数,可以添加多个 @Valid 和 BindindResult。

public void test()(@RequestBody @Valid DemoModel demo, BindingResult result)

public void test()(@RequestBody @Valid DemoModel demo, BindingResult result,@RequestBody @Valid DemoModel demo2, BindingResult result2)

@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参数校验(@RequestParam参数校验)

controller @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 注解对 RequestParam 对应的参数时无效的,需要使用 @Validated 注解来使验证生效。

MethodValidationPostProcessor 的 Bean @Bean

public MethodValidationPostProcessor methodValidationPostProcessor() {

/**默认是普通模式,会返回所有的验证不通过信息集合*/

return new MethodValidationPostProcessor();

}

或者可对 MethodValidationPostProcessor 进行设置 Validator

此时不是使用 Validator 进行验证,Validator 的配置不起作用 @Bean

public MethodValidationPostProcessor methodValidationPostProcessor() {

MethodValidationPostProcessor postProcessor = new MethodValidationPostProcessor();

/**设置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;

}

方法所在的Controller上加注解 @Validated @RequestMapping("/validation")

@RestController

@Validated

public class ValidationController {

/**如果只有少数对象,直接把参数写到Controller层,然后在Controller层进行验证就可以了。*/

@RequestMapping(value = "/demo3", method = RequestMethod.GET)

public void demo3(@Range(min = 1, max = 9, message = "年级只能从1-9")

@RequestParam(name = "grade", required = true)

int grade,

@Min(value = 1, message = "班级最小只能1")

@Max(value = 99, message = "班级最大只能99")

@RequestParam(name = "classroom", required = true)

int classroom) {

System.out.println(grade + "," + classroom);

}

}

返回验证信息提示

验证不通过,抛出来 ConstraintViolationException 异常,使用统一捕获异常处理 @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> violations = exs.getConstraintViolations();

for (ConstraintViolation> item : violations) {

/**打印验证不通过的信息*/

System.out.println(item.getMessage());

}

}

return "bad request, " ;

}

}

验证 http://localhost:8080/validation/demo3?grade=18&classroom=888

3. model校验

model @Data

public class Demo2 {

@Length(min = 5, max = 17, message = "length长度在[5,17]之间")

private String length;

/**@Size不能验证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 list;

}

校验 @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(){{add("111");add("222");add("333");}});

Set> violationSet = validator.validate(demo2);

for (ConstraintViolation model : violationSet) {

System.out.println(model.getMessage());

}

}

4. 对象级联校验

对象内部包含另一个对象作为属性,属性上加 @Valid,可以验证作为属性的对象内部的验证

demo @Data

public class Demo2 {

@Size(min = 3,max = 5,message = "list的Size在[3,5]")

private List list;

@NotNull

@Valid

private Demo3 demo3;

}

@Data

public class Demo3 {

@Length(min = 5, max = 17, message = "length长度在[5,17]之间")

private String extField;

}

校验 /**前面配置了快速失败返回的Bean*/

@Autowired

private Validator validator;

@RequestMapping("/demo3")

public void demo3(){

Demo2 demo2 = new Demo2();

demo2.setList(new ArrayList(){{add("111");add("222");add("333");}});

Demo3 demo3 = new Demo3();

demo3.setExtField("22");

demo2.setDemo3(demo3);

Set> violationSet = validator.validate(demo2);

for (ConstraintViolation model : violationSet) {

System.out.println(model.getMessage());

}

}

5. 分组校验

校验接口 public interface GroupA {

}

public interface GroupB {

}

demo @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;

}

GroupA校验字段userId

GroupB校验字段userName、sex

Default校验字段age(Default使Validator自带的默认分组)

验证

只验证GroupA和GroupB的分组,以下示例代码 @RequestMapping("/demo5")

public void demo5(){

Person p = new Person();

/**GroupA验证不通过*/

p.setUserId(-12);

/**GroupA验证通过*/

//p.setUserId(12);

p.setUserName("a");

p.setAge(110);

p.setSex(5);

Set> validate = validator.validate(p, GroupA.class, GroupB.class);

for (ConstraintViolation item : validate) {

System.out.println(item);

}

} @RequestMapping("/demo6")

public void demo6(@Validated({GroupA.class, GroupB.class}) Person p, BindingResult result){

if(result.hasErrors()){

List allErrors = result.getAllErrors();

for (ObjectError error : allErrors) {

System.out.println(error);

}

}

}

组序列

指定组的验证顺序,前面组验证不通过,后面组不验证 // GroupA > GroupB > Default

@GroupSequence({GroupA.class, GroupB.class, Default.class})

public interface GroupOrder {

}

5. 自定义校验器

1. 大小写校验器

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 {

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());

}

}

}

2. Demo

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;

}

}

3. Validator配置

@Bean

public Validator validator(){

ValidatorFactory validatorFactory = Validation.byProvider( HibernateValidator.class )

.configure()

.addProperty( "hibernate.validator.fail_fast", "true" )

.buildValidatorFactory();

Validator validator = validatorFactory.getValidator();

return validator;

}

4. 校验测试

@RequestMapping("/demo4")

public void demo4(){

Demo demo = new Demo();

demo.setUserName("userName");

Set> validate = validator.validate(demo);

for (ConstraintViolation dem : validate) {

System.out.println(dem.getMessage());

}

}

6. 常见的注解

No.

注解

解释

01

@Null

检查该字段为空

02

@NotNull

不能为 null

03

@NotBlank

不能为空,检查时会将空格忽略

04

@NotEmpty

不能为空,这里的空是指空字符串

05

@AssertTrue

用于boolwan字段,只能为true

06

@AssertFalse

用于boolwan字段,只能为false

07

@CreditCardNumber

对信用卡进行一个大致的校验

08

@DecimalMin(value)

数值类型,只能小于或等于value

09

@DecimalMax(value)

数值类型,只能大于或等于value

10

@Digits(integer=2,fraction=20)

限制必须为一个小数,整数部分位数不能超过integer,小数部分位数不能超过fraction

11

@Email

检查是否是一个有效的email地址

12

@Past

检查该字段的日期是否属于过去的日期

13

@Future

检查该字段的日期是否属于将来的日期

14

@Length(min=,max=)

检查该字段的长度是否在min和max之间,只能用于字符串

15

@Size(min=,max=)

检查该字段的size是否在min和max之间,可以是字符串、数组、集合、map等

16

@Min(value)

小于等于value

17

@Max(value)

大于等于value

18

@URL(protocol=,host,port) 检查是否是一个有效的URL,如果提供来protocol,host等,则该url还需满足提供的条件

19

@Valid

该注解只要用于字段为一个包含其他对象的集合或map或数组的字段,或该字段直接为一个其他对象的引用(这样在检查当前对象的同时也会检查该字段所引用的对象)

7. 参考文档

转载至链接:https://my.oschina.net/shadowolf/blog/1934934

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值