Spring数据休息验证+异常映射器:令人困惑的

时间:2016-04-05 21:59:23

标签: java spring spring-data-rest

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

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

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

然而,我确实通过推出

来实现它

@Validated

在我的存储库中:

@Validated
@RepositoryRestResource(collectionResourceRel = "workers", path = "workers")
public interface WorkerRepository extends PagingAndSortingRepository<Worker, Long> {

}

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

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

因此,简而言之,我想

  • 使用JSR 303验证实体
  • 使用400:和映射或字段生成HTTP实体 - &gt;错误

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

Detected @ExceptionHandler methods in repositoryRestExceptionHandler

这看起来很有用。当我查看该课程时,它看起来就像我需要的那样

2 个答案:

答案 0 :(得分:3)

Spring数据休息不会自动应用bean验证。如果您想要bean验证,则需要在spring data rest中注册相应的验证器。

以下配置对我有用:

@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);
    }
} 

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

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

  • spring数据休息验证机制正在抛出RepositoryConstraintViolationException
  • RepositoryRestExceptionHandler
  • 处理
  • 导致错误被序列化为RepositoryConstraintViolationExceptionMessage

因此,验证错误响应会导致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实体生命周期application events来利用spring-data-rest注册的验证程序。例如您可以在自定义控制器中发出BeforeSaveEvent以触发所有事件处理程序以及spring-data-rest提供的验证事件侦听器。因此,您可以实现获得相同的错误和错误表示。

答案 1 :(得分:0)

一般来说这将是一件痛苦的事情,你必须在hibernate的约束违规列表下完全控制。 MethodValidationPostProcessor可以帮助您触发@Validated接口/类的验证过程。 如果您的返回对象或参数是您的复杂类,则它也必须标记为@Valid。

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

不幸的是我没有找到像spring-webmvc那样的数据绑定机制,它在一个地方报告带有转换/验证问题的错误(它看起来不能以某种方式重复使用)