2016-04-05 63 views
2

我正在使用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實體的實體:和映射或現場 - >錯誤

什麼是最直接的方式做到這一點? 我還無意中發現了這一點:

Detected @ExceptionHandler methods in repositoryRestExceptionHandler 

這似乎可疑有用。當我結帳時,它看起來像我需要的類肯定

回答

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驗證 - 但這不是您要求的 - 是嗎?)

  • 彈簧數據其餘驗證機構被投擲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" 
    } 
} 

定製控制器

您可以利用彈簧的數據休息使用彈簧數據休息實體生命週期application events註冊驗證。例如您可以在自定義控制器中發出BeforeSaveEvent以觸發所有事件處理程序以及spring-data-rest提供的驗證事件偵聽器。因此,您可以實現獲得相同的錯誤和錯誤表示。

+0

這看起來好像可以工作,而這正是我需要的。但是我需要攔截那些驗證失敗發生的事情。 –

+0

@ChristianBongiorno - 謝謝你的提示 - 我在帖子中增加了一些細節 - 配置完全是你需要的 - 其餘部分已經在spring-data-rest中得到了滿足 –

+0

@MathiasDpunkt很好的回答,但事實上,你會爲spring-data-rest自定義控制器實現類似的行爲嗎? – m4rtin

0

在一般情況下它將是一個痛苦的,你必須採取完全控制hibernate列表中的約束違規。 MethodValidationPostProcessor可以幫助您觸發@Validated接口/類的驗證過程。 如果您的返回對象或參數是您的複雜類,則它也必須標記爲@Valid。

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

不幸的是我還沒有發現像彈簧webmvc任何有報道在一個地方與轉換/驗證問題的錯誤(和它看起來它不能數據綁定機制以某種方式可重複使用)

+0

我會試試看,謝謝 –