您的位置:首页 > 其它

Hibernate Validator参数校验

2017-07-29 19:37 676 查看
日常开发中经常会遇到需要参数校验的情况,比如某个字段不能为空、长度不能超过5等都属于参数校验的范围。对于简单的参数校验通过写几个if-else判断语句就搞定,但是对于复杂的多个参数校验的情况,就不是那么简单了,通常是各种循环嵌套+一堆if-else语句。一个字,丑!

所以,这就需要引进本文的主人公——Hibernate Validator(下文简称hb)。顾名思义,这是出自ORM框架Hibernate之手,那么,这个玩意可以帮助我们什么呢?

Express validation rules in a standardized way using annotation-based constraints and benefit from transparent integration with a wide variety of frameworks.

使用基于注解的约束,以标准化的方式表达验证规则,并可以与大多数框架无缝集成。

既然是基于注解进行阐述校验,那么有哪些注解呢?

参数注解

hv的参数校验有多个级别:

bean

method

bean也就是JavaBean(一个标准的)校验又有三种:

field constraints(字段)

property constraints(属性)

class constraints(类)

参数注解可以附加到字段、getter方法,类或者接口上面。对于一些特定的需求,用户可以很容易的开发定制化的约束。

hv提供了JSR规范中所有内置constraint的实现,除此之外还有一些附加的constraint。





快速入门

引入pom依赖:

<dependency>
<groupId>javax.validation</groupId>
<artifactId>validation-api</artifactId>
</dependency>

<dependency>
<groupId>org.glassfish</groupId>
<artifactId>javax.el</artifactId>
<version>3.0.1-b08</version>
</dependency>

<dependency>
<groupId>org.hibernate</groupId>
<artifactId>hibernate-validator</artifactId>
<version>5.3.4.Final</version>
</dependency>


JavaBean:

public class CarBO {

@NotNull
private String manufacturer;

@NotNull
@Size(min = 2, max = 5)
private String licensePlate;

@Min(5)
private int seatCount;

public CarBO(String manufacturer, String licencePlate, int seatCount) {
this.manufacturer = manufacturer;
this.licensePlate = licencePlate;
this.seatCount = seatCount;
}

//setter、getter
}


编写测试类:

public class CarTest {
private static Validator validator;

@BeforeClass
public static void setUp() {
ValidatorFactory factory = Validation.buildDefaultValidatorFactory();
validator = factory.getValidator();
}

@Test
public void manufacturerIsNull() {
CarBO car = new CarBO( null, "DD-AB-123", 4 );

Set<ConstraintViolation<CarBO>> constraintViolations =
validator.validate( car );

assertEquals( 1, constraintViolations.size() );
assertEquals(
"may not be null",
constraintViolations.iterator().next().getMessage()
);
}

@Test
public void licensePlateTooShort() {
CarBO car = new CarBO( "Morris", "D", 4 );

Set<ConstraintViolation<CarBO>> constraintViolations =
validator.validate( car );

assertEquals( 1, constraintViolations.size() );
assertEquals(
"size must be between 2 and 14",
constraintViolations.iterator().next().getMessage()
);
}

@Test
public void seatCountTooLow() {
CarBO car = new CarBO( "Morris", "DD-AB-123", 1 );

Set<ConstraintViolation<CarBO>> constraintViolations =
validator.validate( car );

assertEquals( 1, constraintViolations.size() );
assertEquals(
"must be greater than or equal to 2",
constraintViolations.iterator().next().getMessage()
);
}

@Test
public void carIsValid() {
CarBO car = new CarBO( "Morris", "DD-AB-123", 2 );

Set<ConstraintViolation<CarBO>> constraintViolations =
validator.validate( car );

assertEquals( 0, constraintViolations.size() );
}

}


在实际场景中,对于非法的参数需要抛出异常,比如哪个参数因为什么校验不通过。具体哪个字段可以通过ConstraintViolation的getPropertyPath方法获取,校验的提示信息可以通过ConstraintViolation的getMessage方法获取。

实例如下:

private void validate(CarBO car) {
Set<ConstraintViolation<CarBO>> constraintViolations = validator.validate( car );
if (!constraintViolations.isEmpty()) {
throw new RuntimeException("参数非法!!" + getValidateMsg(constraintViolations));
}
}

private String getValidateMsg(Set<ConstraintViolation<CarBO>> constraintViolations) {
StringBuilder msg = new StringBuilder();
for (ConstraintViolation<CarBO> violation : constraintViolations) {
msg.append(violation.getPropertyPath())
.append(violation.getMessage())
.append(",");
}
return msg.substring(0, msg.lastIndexOf(","));
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: