1.说明
在Spring Boot已经集成Hibernate Validator校验器的情况下,
对于配置了校验注解的请求参数,
框架会自动校验其参数,
但是如果想手动校验一个加了注解的普通对象,
比如从文件中解析出来的对象,
或者自己新建的对象,
可以使用如下工具类对其进行校验。
2.工具类
通过Spring上下文获取容器中的Validator,
然后注入到本地静态变量中,
用于后续的对象校验,
ValidatorUtil.java源码:
package com.ai.ipc.resource.util;
import java.util.Set;
import javax.validation.ConstraintViolation;
import javax.validation.ValidationException;
import javax.validation.Validator;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware;
import org.springframework.stereotype.Component;
import org.springframework.validation.beanvalidation.LocalValidatorFactoryBean;
import org.springframework.validation.beanvalidation.SpringValidatorAdapter;
/**
* Hibernate Validator校验工具类
*/
@Component
public class ValidatorUtil implements ApplicationContextAware {
// 通过Spring获得校验器
private static Validator validator;
@Override
public void setApplicationContext(ApplicationContext applicationContext) {
Validator validatorBean = applicationContext.getBean(Validator.class);
setValidator(validatorBean);
}
public static void setValidator(Validator validatorBean) {
// Unwrap to the native Validator with forExecutables support
if (validatorBean instanceof LocalValidatorFactoryBean) {
validator = ((LocalValidatorFactoryBean) validatorBean).getValidator();
} else if (validatorBean instanceof SpringValidatorAdapter) {
validator = validatorBean.unwrap(Validator.class);
} else {
validator = validatorBean;
}
}
/**
* 对配置了注解的对象进行校验
*/
public static <T> void validate(T object) {
Set<ConstraintViolation<T>> violationSet = validator.validate(object);
for (ConstraintViolation<T> violation : violationSet) {
// 快速返回第一个校验失败的数据
throw new ValidationException(violation.getMessage());
}
}
}
3.使用方式
在如下Junit测试用例中,
新建了Device对象的实例,
然后用ValidatorUtil对其进行校验,
如果参数不满足校验注解,
会抛出对应的校验异常:
package com.ai.ipc.util;
import javax.validation.constraints.NotEmpty;
import javax.validation.constraints.NotNull;
import javax.validation.constraints.Size;
import org.junit.jupiter.api.Test;
import org.springframework.boot.test.context.SpringBootTest;
import com.ai.ipc.resource.ResourceApplication;
import com.ai.ipc.resource.util.ValidatorUtil;
@SpringBootTest(classes = ResourceApplication.class)
public class ValidatorUtilTest {
@Test
public void testValidateBean() {
Device device = new Device();
device.deviceId = "d001";
device.ip = "1.1.1.1";
device.name = "12345";
ValidatorUtil.validate(device);
}
public class Device {
/**
* 设备ID
*/
@NotNull(message = "deviceId不能为Null")
private String deviceId;
/**
* 设备IP,业务主键,建立唯一索引约束,不支持修改
*/
@NotEmpty(message = "IP不能为空")
private String ip;
/**
* 设备名称
*/
@Size(min = 1, max = 3, message = "name的长度size在[1,3]之间")
private String name;
}
}
4.异常日志
上面测试代码填写的name长度为5,
发生异常时的日志如下:
javax.validation.ValidationException: name的长度size在[1,3]之间
at com.ai.ipc.resource.util.ValidatorUtil.validate(ValidatorUtil.java:51)
at com.ai.ipc.util.ValidatorUtilTest.testValidateBean(ValidatorUtilTest.java:26)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:498)
at org.junit.platform.commons.util.ReflectionUtils.invokeMethod(ReflectionUtils.java:686)
at org.junit.jupiter.engine.execution.MethodInvocation.proceed(MethodInvocation.java:60)
网友评论