2012-02-18 70 views
6

我在我的控制器之一這樣定義的操作方法:如何從這個Spring MVC控制器返回錯誤狀態和驗證錯誤?

@RequestMapping(method = RequestMethod.POST) 
public @ResponseBody Post create(@Valid Post post, BindingResult bindingResult) { 
    if (bindingResult.hasErrors()) { 
     // how to return an error status + error messages from here? 
    } else { 
     postRepository.persist(post); 
     return post; 
    } 
} 

當後成功地堅持着,我回來後返回給客戶端。但是當它有驗證錯誤時,我想返回錯誤狀態代碼以及所有驗證錯誤消息返回給客戶端。

這樣做的最好方法是什麼?

+0

您是在設計API還是處理表單? – 2012-02-18 08:30:48

+0

我正在設計一個REST API。 – 2012-02-18 08:47:11

回答

7

正弦,你需要創建自己的POJO的(亦稱資源),這將代表古怪的行爲或驗證錯誤,如horaceman說。我會告訴你我們如何在我們的應用程序中做到這一點。

由於我們使用JSON作爲數據表示,如果發生意外異常,我們希望接收以下信息。

{ "status" : "EXCEPTION", "exceptionName" : "MyCustomException", "exceptionMsg" : "ex.unsupportedOperation" } 

這是一個當然的例子。很好的解決方案是,我們可以將exceptionMsg作爲我們前端的一個關鍵字,以便顯示正確的i18n消息或按照原樣顯示給用戶(在這種情況下,我們使用更多描述性消息)。

現在,當一切都OK了,我們做這樣的事情:

{ "status" : "OK", "data" : {(...)} } 

Data元素是可選的。我們可以發送任何我們需要通知前端,或​​完全跳過它。

最後一種情況是你的 - 驗證錯誤。在這種情況下,我們通常發送以下內容:

{ "status" : "VALIDATION_FAILED", "errors" : [ "fieldName" : "username", "errorCode" : "validation.requiredField", "errorMsg" : "Username is required."] } 

所以很明顯API客戶端將收到的信息驗證失敗,並在適當的領域 - 關於什麼地方出了錯具體細節。當然errors是一個數組(或List),所以我們總是提供儘可能多的細節。

我該怎麼做? 簡單而言,這些對象是簡單的POJOS,使用Jackson將其轉換爲JSON。這給了我JSON表示的無限可能性。我所做的是,我準備代表驗證錯誤的POJO(例如),並將其作爲Model添加到我的ModelAndView實例中。然後我只依靠Spring來做適當的JSON封送。

在你的情況下,你有@ResponseBody註釋與你的Post實例,所以據我所知,你將無法做到這一點。你的設置說「好的,不管發生了什麼 - 總是返回一個Post的實例」。你應該做的,是用簡單的ModelAndView替換它,根據驗證提供合適的Model,並將其返回給客戶端API。

+0

謝謝!已到達1k:D – 2012-02-19 09:05:20

3

我想你想在你的控制器中做一個ajax調用。你在方法中返回一個post對象,所以不可能返回另一個對象(比如帶有代碼的錯誤消息)。如何返回一個ExecutionResult呢?你是一個desigining REST API

ExecutionResult{ 
private int statusCode; 
private String message; 
private Object yourPost; 
//get and set methods here... 
} 
3

對於@ResponseBody我會從方法簽名中刪除BindigResult,並拋出BindException。然後,我會使用@ExceptionHandler方法返回一個包含Likacz描述的錯誤的對象。

@RequestMapping(method = RequestMethod.POST) 
public @ResponseBody Post create(@Valid Post post) { 
    postRepository.persist(post); 
    return post; 
} 

@ExceptionHandler 
public ValidationErrors handleException(BindException ex) { 
    // ... 
} 
+0

請注意,如果您想在響應正文中返回'ValidationErrors','handleException'方法將需要'@ ResponseBody'。 – CorayThan 2013-05-06 23:56:50