美文网首页
SpringBoot中使用Hibernate Validator

SpringBoot中使用Hibernate Validator

作者: 木木与呆呆 | 来源:发表于2022-03-30 11:30 被阅读0次

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)

相关文章

网友评论

      本文标题:SpringBoot中使用Hibernate Validator

      本文链接:https://www.haomeiwen.com/subject/xciijrtx.html