Spring Boot JSR-303/349配置
在我的Spring Boot 1.5.1
应用程序中,我正在尝试配置对JSR-303 / JSR-349validation的支持。
我在我的方法中添加了以下注释@NotNull @Size(min = 1)
:
@Service @Transactional public class DecisionDaoImpl extends BaseDao implements DecisionDao { @Override public Decision create(@NotNull @Size(min = 1) String name, String description, String url, String imageUrl, Decision parentDecision, Tenant tenant, User user) { ... } }
我试图从我的测试中调用此方法,但它不会在validation约束上失败。
这是我的测试和配置:
@SpringBootTest(classes = { TestConfig.class, Neo4jTestConfig.class }) @RunWith(SpringRunner.class) @Transactional public class TenantTest { @Test public void testCreateDecision() { User user1 = userService.createUser("test1", "test1", "test1@test.com", null, null); Tenant tenant1 = tenantDao.create("Tenant 1", "Tenant 1 description", false, user1); // the following line should fail on the validation constraint because name parameter is null but it doesn't final Decision rootDecision = decisionDao.create(null, "Root decision 1 description", null, tenant1, user1); ... @Configuration @ComponentScan("com.example") @SpringBootApplication(exclude={Neo4jDataAutoConfiguration.class}) public class TestConfig { }
我做错了什么以及如何在那里配置JSR-303?
更新
我已经添加了
public Decision create(@Valid @NotNull @Size(min = 1) String name, String description, Decision parentDecision, Tenant tenant, User author) {
但它仍然无效
我已将@Validated
添加到我的DecisionDaoImpl
但它现在失败并出现以下exception:
Caused by: org.springframework.beans.factory.BeanCurrentlyInCreationException: Error creating bean with name 'decisionDaoImpl': Bean with name 'decisionDaoImpl' has been injected into other beans [criterionGroupDaoImpl,characteristicGroupDaoImpl,tenantDaoImpl] in its raw version as part of a circular reference, but has eventually been wrapped. This means that said other beans do not use the final version of the bean. This is often the result of over-eager type matching - consider using 'getBeanNamesOfType' with the 'allowEagerInit' flag turned off, for example. at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:585) at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:483) at org.springframework.beans.factory.support.AbstractBeanFactory$1.getObject(AbstractBeanFactory.java:306) at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:230) at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:302) at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:202) at org.springframework.beans.factory.config.DependencyDescriptor.resolveCandidate(DependencyDescriptor.java:208) at org.springframework.beans.factory.support.DefaultListableBeanFactory.doResolveDependency(DefaultListableBeanFactory.java:1138) at org.springframework.beans.factory.support.DefaultListableBeanFactory.resolveDependency(DefaultListableBeanFactory.java:1066) at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor$AutowiredFieldElement.inject(AutowiredAnnotationBeanPostProcessor.java:585) ... 43 common frames omitted
我还在我自动assemblyDecisionDao
的地方添加了@Lazy
注释,但是现在我的测试失败并出现以下exception:
javax.validation.ConstraintDeclarationException: HV000151: A method overriding another method must not alter the parameter constraint configuration, but method public com.example.domain.model.entity.decision.Decision com.example.domain.dao.decision.DecisionDaoImpl.create(java.lang.String,java.lang.String,java.lang.String,java.lang.String,java.lang.Long,java.lang.Long,com.example.domain.model.entity.user.User) changes the configuration of public abstract com.example.domain.model.entity.decision.Decision com.example.domain.dao.decision.DecisionDao.create(java.lang.String,java.lang.String,java.lang.String,java.lang.String,java.lang.Long,java.lang.Long,com.example.domain.model.entity.user.User). at org.hibernate.validator.internal.metadata.aggregated.rule.OverridingMethodMustNotAlterParameterConstraints.apply(OverridingMethodMustNotAlterParameterConstraints.java:24) at org.hibernate.validator.internal.metadata.aggregated.ExecutableMetaData$Builder.assertCorrectnessOfConfiguration(ExecutableMetaData.java:456)
将validation移至界面,如下所示:
import javax.validation.Valid; import javax.validation.constraints.NotNull; import javax.validation.constraints.Size; public interface DecisionDao { Decision create(@Valid @NotNull @Size(min = 1) String name, String description, String url, String imageUrl); }
使用@Validated
注释DecisionDaoImpl
,如下所示:
import org.springframework.stereotype.Service; import org.springframework.validation.annotation.Validated; @Service @Validated public class DecisionDaoImpl extends BaseDao implements DecisionDao { @Override public Decision create(String name, String description, String url, String imageUrl) { System.out.println(name); return new Decision(); } }
使用assertj或ExpectedException修改测试用例以validationjavax.validation.ConstraintViolationException
,如下所示:
import static org.assertj.core.api.Assertions.assertThatExceptionOfType; import javax.validation.ConstraintViolationException; import org.junit.Test; import org.junit.runner.RunWith; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.test.context.ContextConfiguration; import org.springframework.test.context.junit4.SpringRunner; import org.springframework.validation.beanvalidation.MethodValidationPostProcessor; @ContextConfiguration(classes = { TenantTest.Config.class }) @RunWith(SpringRunner.class) public class TenantTest { @Autowired private DecisionDao decisionDao; @Rule public ExpectedException expectedException = ExpectedException.none(); @Test public void testCreateDecisionUsingAssertj() { assertThatExceptionOfType(ConstraintViolationException.class) .isThrownBy( () -> decisionDao.create(null, "Root decision 1 description", null, null)); } @Test public void testCreateDecision() { expectedException.expect(ConstraintViolationException.class); decisionDao.create(null, "Root decision 1 description", null, null); } @Configuration public static class Config { @Bean public MethodValidationPostProcessor methodValidationPostProcessor() { return new MethodValidationPostProcessor(); } @Bean public DecisionDao decisionDao() { return new DecisionDaoImpl(); } } }
确保你的类路径中有hibernate-validator和@StanislavL答案:
org.hibernate hibernate-validator
以及org.assertj.core.api.Assertions.assertThatExceptionOfType
的可选依赖org.assertj.core.api.Assertions.assertThatExceptionOfType
,如:
org.assertj assertj-core 3.3.0 test
例如,您可以参考arpitaggarwal / jsr-303
你需要@Valid
注释
标记用于validation级联的属性,方法参数或方法返回类型。 在validation属性,方法参数或方法返回类型时,将validation在对象及其属性上定义的约束。
约束注释旨在应用于JavaBeans。 请参阅http://beanvalidation.org/1.0/spec/#constraintsdefinitionimplementation-constraintdefinition
您在DAO中应用了约束注释@Size
, @Size
等。 您必须创建一个Java Bean,例如“Person”,它包装这些属性(名称,描述等),然后将“Person”作为参数传递给Controller方法。 如果您需要使用DAO而不是控制器,则需要对其进行检测以执行validation。 关于AOP等,你可能在这方面独立,除非这篇文章发生了一些变化: http : //forum.spring.io/forum/spring-projects/container/82643-annotation-driven-jsr -303validation-ON-服务和DAO层
更新 :好了,现在支持它(方法级validationJSR-349)现在请参阅http://blog.codeleak.pl/2012/03/how-to-method-level-validation-in.html作为示例,类似于Arpit的回答。 更新了问题标题以反映最新的JSR。
- 是否有使用带注释的方法参数启用JSR 303 Bean Validation的标准方法
- 可参数化的JSR-303validation值
- Beanvalidation引发ConstraintViolationException时自定义JAX-RS响应
- Hibernate – 激活Bean Validation集成时出错
- javax.validation.ValidationException:无法找到默认提供程序
- 从jsr-303自定义validation器访问数据库
- 交叉字段validation(JSR 303)问题
- Spring MVC和JSR-303 hibernate条件validation
- 如何手动触发弹簧validation?