Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/spring/12.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java Spring4和Hibernate5方法参数验证_Java_Spring_Hibernate 5.x - Fatal编程技术网

Java Spring4和Hibernate5方法参数验证

Java Spring4和Hibernate5方法参数验证,java,spring,hibernate-5.x,Java,Spring,Hibernate 5.x,如何使用Hibernate验证传入参数 在XML中 <bean id="validator" class="org.springframework.validation.beanvalidation.LocalValidatorFactoryBean"/> <bean class="org.springframework.validation.beanvalidation.MethodValidationPostProcessor"> <property n

如何使用Hibernate验证传入参数

在XML中

<bean id="validator" class="org.springframework.validation.beanvalidation.LocalValidatorFactoryBean"/>
<bean class="org.springframework.validation.beanvalidation.MethodValidationPostProcessor">
    <property name="validator" ref="validator"/>
</bean>

这种方法不起作用,我调用带有错误参数的方法,验证不起作用。

问题澄清

将Hibernate Validator(HV)4.2与Spring MVC 4一起使用时,例如使用依赖项:

dependencies {
    providedCompile 'javax.servlet:javax.servlet-api:3.0.1'
    compile 'org.springframework:spring-webmvc:4.0.3.RELEASE'
    compile 'org.hibernate:hibernate-validator:4.2.0.Final'
    runtime 'javax.servlet:jstl:1.1.2'
}
通过在配置文件中声明以下bean,可以告诉Spring自动使用HV验证带有
@Validated
(如asker的示例)注释的类的方法调用

<bean id="validator" class="org.springframework.validation.beanvalidation.LocalValidatorFactoryBean"/>
<bean class="org.springframework.validation.beanvalidation.MethodValidationPostProcessor"/>
但问题是如果您将依赖项从上面更改为

dependecies {
    providedCompile 'javax.servlet:javax.servlet-api:3.0.1'
    compile 'org.springframework:spring-webmvc:4.0.3.RELEASE'
    compile 'org.hibernate:hibernate-validator:5.1.0.Final' //**note the change here**
    runtime 'javax.servlet:jstl:1.1.2'
}
然后您将得到一个错误:

org.springframework.beans.factory.BeanCreationException: Error creating bean with name
'org.springframework.validation.beanvalidation.MethodValidationPostProcessor#0'
defined in class path resource [spring/config/web/main-config.xml]: Invocation of init
method failed; nested exception is javax.validation.ValidationException: Unable to
instantiate Configuration.
解决方案

向类路径添加2个额外的依赖项,如下所示

dependecies {
    providedCompile 'javax.servlet:javax.servlet-api:3.0.1'
    providedCompile 'javax.el:el-api:2.2'
    providedCompile 'org.glassfish.web:el-impl:2.2'
    compile 'org.springframework:spring-webmvc:4.0.3.RELEASE'
    compile 'org.hibernate:hibernate-validator:5.1.0.Final' //**note the change here**
    runtime 'javax.servlet:jstl:1.1.2'
}
而验证将重现生机。但这一次,它没有引发
MethodConstraintViolationException
,而是引发了
ConstranitViolationException
,没有任何违反的细节

我不确定Spring如何在内部管理这个异常,以及您是否可以从这个异常中展开违规细节。HV 5不再支持
MethodConstraintViolationException
及其相关功能,例如
MethodValidator
MethodConstraintViolation
。这与BV 1.0的方法级验证有所不同。我建议您自己使用aspect和
ExecutableValidator
(而不是旧的
MethodValidator
)创建验证服务,如中所述

请注意,如果您尝试像这样获取验证器

ValidatorFactory factory = Validation.buildDefaultValidatorFactory();
ExecutableValidator executableValidator = factory.getValidator().forExecutables();
您可能会得到
ValidationException:无法实例化配置。
我可以通过这样做来解决这个问题

ValidatorFactory factory = Validation.byProvider(HibernateValidator.class).configure().buildValidatorFactory();
ExecutableValidator executableValidator = factory.getValidator().forExecutables();

除了spring和maven pom文件中的其他项目依赖项之外,我还包括以下内容

<properties>
    <hibernate.version>4.3.1.Final</hibernate.version>
    <hibernate.validator.version>5.1.0.Final</hibernate.validator.version>
    <javax.el.version>3.0.0</javax.el.version>
    <asm.version>3.3.1</asm.version>
</properties>
<dependencies>
    <!-- Hibernate et al-->
    <dependency>
        <groupId>org.hibernate</groupId>
        <artifactId>hibernate-entitymanager</artifactId>
        <version>${hibernate.version}</version>
    </dependency>
    <dependency>
        <groupId>org.hibernate</groupId>
        <artifactId>hibernate-core</artifactId>
        <version>${hibernate.version}</version>
    </dependency>
    <dependency>
        <groupId>org.hibernate</groupId>
        <artifactId>hibernate-validator</artifactId>
        <version>${hibernate.validator.version}</version>
    </dependency>
    <dependency>
        <groupId>javax.el</groupId>
        <artifactId>javax.el-api</artifactId>
        <version>${javax.el.version}</version>
    </dependency>
    <dependency>
        <groupId>org.glassfish.web</groupId>
        <artifactId>javax.el</artifactId>
        <version>${javax.el.version}</version>
    </dependency>
    <!-- asm allows hibernate validator to retrieve method parameter names when reporting method validation
        without this you just get arg0 instead of argument name -->
    <dependency>
        <groupId>asm</groupId>
        <artifactId>asm</artifactId>
        <version>${asm.version}</version>
    </dependency>
</dependencies>

LocalVariableTableParameterNameDiscoveryer与ASM合作,在ConstraintViolationException中提供正确的参数名称,验证失败时将引发该异常。

显然,Spring建议不要使用ExecutableValidator,而是使用MethodValidationInterceptor,请参阅javadoc:

对于当前版本,您不必添加“asinkxcoswt”编写的所有bean

在pom.xml中添加以下内容:

<dependency>
   <groupId>org.hibernate</groupId>
   <artifactId>hibernate-validator</artifactId>
   <version>5.3.4.Final</version>
</dependency>
<dependency>
   <groupId>org.glassfish.web</groupId>
   <artifactId>javax.el</artifactId>
   <version>2.2.4</version>
</dependency>

这里没有问题。在hibernate 4.2.0中,malidate方法的packacge org.hibernate.validator.method如何使用hibernate validator 5.0.3I进行验证面临相同的问题。这不起作用,因为您初始化了spring消息源。这是因为验证是hibernate的默认属性名。您可以删除messageSource,它无论如何都会工作..糟糕,您不必使用@Validated注释。验证也可以在没有它的情况下工作。对于
@RequestParam
验证,您只需要
@Validated
。正如JavaDoc所述:“例如,可以与Spring MVC处理程序方法参数一起使用。”我无法使用Hibernate Validator和您提到的设置来验证rest调用的查询参数,验证不会被引入。
<properties>
    <hibernate.version>4.3.1.Final</hibernate.version>
    <hibernate.validator.version>5.1.0.Final</hibernate.validator.version>
    <javax.el.version>3.0.0</javax.el.version>
    <asm.version>3.3.1</asm.version>
</properties>
<dependencies>
    <!-- Hibernate et al-->
    <dependency>
        <groupId>org.hibernate</groupId>
        <artifactId>hibernate-entitymanager</artifactId>
        <version>${hibernate.version}</version>
    </dependency>
    <dependency>
        <groupId>org.hibernate</groupId>
        <artifactId>hibernate-core</artifactId>
        <version>${hibernate.version}</version>
    </dependency>
    <dependency>
        <groupId>org.hibernate</groupId>
        <artifactId>hibernate-validator</artifactId>
        <version>${hibernate.validator.version}</version>
    </dependency>
    <dependency>
        <groupId>javax.el</groupId>
        <artifactId>javax.el-api</artifactId>
        <version>${javax.el.version}</version>
    </dependency>
    <dependency>
        <groupId>org.glassfish.web</groupId>
        <artifactId>javax.el</artifactId>
        <version>${javax.el.version}</version>
    </dependency>
    <!-- asm allows hibernate validator to retrieve method parameter names when reporting method validation
        without this you just get arg0 instead of argument name -->
    <dependency>
        <groupId>asm</groupId>
        <artifactId>asm</artifactId>
        <version>${asm.version}</version>
    </dependency>
</dependencies>
@Bean
public MessageSource messageSource() {
    ReloadableResourceBundleMessageSource messageSource = new ReloadableResourceBundleMessageSource();
    messageSource.setBasename("validation");
    messageSource.setCacheSeconds(1);

    return messageSource;
}


@Bean
LocalValidatorFactoryBean getValidator() {
    LocalValidatorFactoryBean validator = new LocalValidatorFactoryBean();
    validator.setValidationMessageSource(messageSource());
    validator.setParameterNameDiscoverer(new LocalVariableTableParameterNameDiscoverer());
    return validator;

}

@Bean
@Autowired
MethodValidationPostProcessor getValidationPostProcessor(LocalValidatorFactoryBean validator) {
    MethodValidationPostProcessor processor = new MethodValidationPostProcessor();
    processor.setValidator(validator);
    return processor;
}
<dependency>
   <groupId>org.hibernate</groupId>
   <artifactId>hibernate-validator</artifactId>
   <version>5.3.4.Final</version>
</dependency>
<dependency>
   <groupId>org.glassfish.web</groupId>
   <artifactId>javax.el</artifactId>
   <version>2.2.4</version>
</dependency>
<bean id="validationFactory" class="javax.validation.Validation"  
      factory-method="buildDefaultValidatorFactory" />  
javax.validation.ConstraintViolationException: Validation failed for classes [com.example.Class] during update time for groups [javax.validation.groups.Default, ]
List of constraint violations:[
ConstraintViolationImpl{interpolatedMessage='must be greater than or equal to 0', propertyPath=amount, rootBeanClass=class com.example.Class, messageTemplate='{javax.validation.constraints.Min.message}'}
]