Spring数据restvalidation+exception映射器:令人困惑

我正在使用Spring Data Rest,一切顺利。

我想在我的实体上应用validation(JSR 303)。

春季文档说我可以通过几种方式拦截应用程序事件(我无法开始工作,而现在spring.io似乎已经失效)。

但是,我确实通过推杆让它发挥作用

@Validated

在我的存储库:

@Validated @RepositoryRestResource(collectionResourceRel = "workers", path = "workers") public interface WorkerRepository extends PagingAndSortingRepository { } 

它会引发exception。 问题是它是一个弹簧exception而不是根目录,我需要基本上进行validation并将它们转换为自定义实体有效负载:

 { "foo": "must be of length 10", "baz": "Must match pattern '[AZ]+'" } 

所以,简而言之,我想

  • 使用JSR 303validation实体
  • 生成具有400的HTTP实体:以及映射或字段 – >错误

最简单的方法是什么? 我也偶然发现了这个:

 Detected @ExceptionHandler methods in repositoryRestExceptionHandler 

这看起来很可疑。 当我结账时,它看起来像我需要的肯定

Spring数据rest不会自动应用beanvalidation。 如果您想要beanvalidation,则需要在spring数据rest中注册相应的validation器。

以下配置对我有用:

 @Configuration public class MyValidationConfiguration extends RepositoryRestConfigurerAdapter { @Bean @Primary /** * Create a validator to use in bean validation - primary to be able to autowire without qualifier */ Validator validator() { return new LocalValidatorFactoryBean(); } @Override public void configureValidatingRepositoryEventListener(ValidatingRepositoryEventListener validatingListener) { Validator validator = validator(); //bean validation always before save and create validatingListener.addValidator("beforeCreate", validator); validatingListener.addValidator("beforeSave", validator); } } 

使用此配置,每个具有beanvalidation约束的实体都会在更新和创建之前进行validation。

(这不是在spring-data-rest项目中为自定义控制器启用beanvalidation – 但这不是你要求的 – 是吗?)

  • spring数据restvalidation机制正在抛出RepositoryConstraintViolationException
  • 它由RepositoryRestExceptionHandler处理
  • 这导致错误被序列化为RepositoryConstraintViolationExceptionMessage

所以validation错误响应会导致400 Bad Request与这样的正文:

 { "errors" : [ { "entity" : "MyEntity", "message" : "may not be null", "invalidValue" : "null", "property" : "price" }, { "entity" : "MyEntity", "message" : "may not be empty", "invalidValue" : "", "property" : "name" } } 

自定义控制器

您可以使用spring-data-rest实体生命周期应用程序事件来利用spring-data-rest注册的validation程序 。 例如,您可以在自定义控制器中发出BeforeSaveEvent以触​​发所有事件处理程序以及spring-data-rest提供的validation事件侦听器。 因此,您可以实现获得相同的错误和错误表示。

一般来说这将是一个痛苦的,你必须在hibernate条件下限制违规行为。 MethodValidationPostProcessor可以帮助您触发@Validated接口/类的validation过程。 如果您的返回对象或参数是您的复杂类,则它也必须标记为@Valid。

下一篇文章可以帮助您: https : //dzone.com/articles/method-validation-spring-31

不幸的是我没有发现像spring-webmvc这样的DataBinding机制,它在一个地方报告带有转换/validation问题的错误(它看起来不能以某种方式重复使用)