2013-12-20 56 views
3

我還是一般的Spring新手,我正在嘗試使用Spring引導。我有一個(希望)快速的問題。我正在嘗試構建一個將返回JSON的ReSTful服務。我遵循Building a RESTful Web Service Guide並可以成功返回JSON。我已將JPA集成到我的Web服務中,以便我的數據由數據庫支持。Spring Boot Validation回覆JSON

現在,我需要創建一個路徑,用戶可以在其中創建一個對象,並且我希望對象進行驗證。我遵循Validation Form Input Guide,但我並沒有真的嘗試創建提供Web內容的服務。我想要的是,每當發生驗證錯誤時,返回我自己的自定義JSON。到目前爲止,儘管我已經嘗試了Petri's Sweet Rest API Guide,但我發現它並沒有找到任何資源來實現此目的,但我發現它在多種情況下都很有幫助,但在這種情況下似乎並不奏效。我正在使用hibernate-validator:5.0.1.Final和休眠以下。

@Entity 
@Table(name = "PEOPLE") 
public class Person{ 

    @Id 
    @Column(unique = true) 
    @GeneratedValue(strategy = GenerationType.AUTO) 
    private long id; 

    @Min(18) 
    private long age; 
    private String name; 

    //Necessary for JPA 
    protected Person() {} 

    public Person(long age, String name) { 
     this.age = age; 
     this.name = name; 
    } 

    // Getters Omitted 
} 

然後我PersonController:

@Controller 
public class PersonController { 

    @RequestMapping(value="person/", method=RequestMethod.POST) 
    @ResponseBody 
    public ResponseEntity<Person> create(@Valid @RequestBody Person person) { 
     // Create in DB and return 
    } 
} 

這工作在最嚴格的方式,在這,如果你發送垃圾JSON到這條路線,它會返回一個400,這是相當不錯的。但是響應的主體是一個HTML頁面,它不太好。所以,我的問題是,是否有某種方法來捕獲驗證錯誤?我試着加入以下到我的控制器,但沒有成功:

@ExceptionHandler(MethodArgumentNotValidException.class) 
public ResponseEntity handleError(MethodArgumentNotValidException ex) { 
    //generate my own error message 
    return new ResponseEntity(customErrorClass, HttpStatus.BAD_GATEWAY); 
} 

我知道錯誤的網關是不是一個有效的返回代碼,但我用它只是爲了證明異常處理程序不會被調用。當我POST到我的休息服務,我仍然看到400錯誤的請求+ HTML。我會假設有一些合理的默認值,我可以覆蓋,但我似乎無法弄清楚它在哪裏。我試過Google搜索和搜索stackoverflow沒有運氣。

在此先感謝。

UPDATE

如果我修改控制器以包括方法簽名BindingResult

@Controller 
public class PersonController { 

    @RequestMapping(value="person/", method=RequestMethod.POST) 
    @ResponseBody 
    public ResponseEntity<Person> create(@Valid @RequestBody Person person, BindingResult bindingResult) { 
     if(bindingResult.hasErrors()){ 
      //handle errors and return 
     } else { 
     // Create in DB and return 
     } 
    } 
} 

我能得到它的工作。 (注意我還必須將jasper-el jar添加到我的依賴項)之前我曾嘗試過這種方法,但沒有得到它的效果,但原因並不直觀。我發佈了以下JSON:{ "id" : "foo", "age": 22, "name" : "James Bond" }根據JSON Spec,這是有效的JSON。顯然,我的人物模型不能將字符串「foo」投射到很長時間。我不會考慮錯誤是否應該是400,我的新問題是:我怎樣才能抓住這400?

+0

驗證不會導致400錯誤格式的JSON將導致400 –

+0

有趣,所以你是正確的400沒有被驗證造成的,我得到一個現在驗證實際發生時出現新錯誤。奇怪的是,以下是不是格式不正確的JSON:'{「id」:「foo」,「age」:20,「name」:「James Bond」}'但是,錯誤仍然是400.這是我正在使用的示例,但現在,如果根據我的驗證將其更改爲「無效」記錄,則會得到一個500,這看起來像我沒有包含庫。我現在正在研究它。 – loganasherjones

+1

對於驗證錯誤,請在'@ Valid'註釋參數旁邊使用'BindingResult'參數。 –

回答

2

要處理格式不正確或不可兌換的JSON,你可以趕上HttpMessageNotReadableException

@ExceptionHandler(HttpMessageNotReadableException.class) 
public ResponseEntity handleBadInput(HttpMessageNotReadableException ex) { 
    Throwable cause = ex.getCause(); 
1

的你的問題是,你設置字段的ID在你的模型是一個長期的,用字符串FOO。這是400 http錯誤的原因。假設這種異常通過http狀態的表達能力正確管理。關鍵的一點是,你能想到管理400錯誤和zeroflagL的解決方案工作正常,但它是一個很好的解決方案,如果您使用@ExceptionHandler象下面這樣:

@ExceptionHandler(HttpMessageNotReadableException.class) 
public ResponseEntity handleBadInput(HttpMessageNotReadableException ex) { 
    // manage the exceptio for instance log it 
    ..... 

    retunr ResponseEntity.badRequest().body(/** body may be optional if you want send a description of the error*/); 
} 

這是非常重要的是,你的異常處理程序管理異常的意義在於將日誌記錄爲分析錯誤,但是您應該返回具有400 http狀態的http響應。

這很重要,因爲http respon是正確的,你發佈了一個json,對於你的服務沒有意義,保存這些信息可能對你的客戶端應用程序中的發現問題至關重要,例如關鍵點聽到這個http satatus說你的實體對你的端點沒有意義。

我一跳,它可以幫助你