2017-09-01 69 views
0

長話短說:我正在創建應該是100%REST的API。 我試圖改寫下列情況下默認響應: 我有我的@RestController的方法有@RequestBody作爲一個屬性Java/Spring>當請求中沒有主體時,處理帶有@RequestBody的控制器方法的錯誤請求響應

@RequestMapping(value = {"register"}, method = RequestMethod.POST, produces = "application/hal+json") 
public Resource<User> registerClient(@RequestBody User user, HttpServletRequest request) 

,如果我發送的方法工作得很好適當的要求。但是當我不這樣做的時候有一個問題。當請求有空的時候,我得到一個狀態爲400的通用Tomcat錯誤頁面,我需要它只發送一個字符串或一個JSON對象。

到目前爲止,我嘗試在我的RestControllerAdvice中爲包org.springframework.web.binding中的所有Spring異常添加異常處理程序,但它也不起作用。

我已經意識到,對於一些與安全相關的錯誤,必須在配置中創建處理程序,但我不知道是否屬於這種情況。

有沒有人遇到過類似的問題?有什麼我失蹤?

+0

「但是當我不這樣做的時候有一個問題。」 在哪些情況下你不會返回用戶資源? – ruslanys

+0

@ruslanys我的意思是,當我發送POST請求沒有身體或空身體,每當我發佈身體至少** {} **它的處理如設計 –

+0

@ruslanys不幸的是,它並沒有幫助,內容類型標題在那裏,但仍然 - 請求中沒有正文帶來提及的問題 –

回答

2

解決方案是簡單地把required = false in RequestBody註釋。之後,我可以輕鬆添加一些邏輯來引發自定義異常,並在ControllerAdvice中處理它。

@RequestMapping(value = {"register"}, method = RequestMethod.POST, produces = "application/hal+json") 
public Resource<User> registerClient(@RequestBody(required = false) User user, HttpServletRequest request){ 
    logger.debug("addClient() requested from {}; registration of user ({})", getClientIp(request), user); 
    if(user == null){ 
     throw new BadRequestException() 
       .setErrorCode(ErrorCode.USER_IS_NULL.toString()) 
       .setErrorMessage("Wrong body or no body in reqest"); 
    } (...) 
0

在正常情況下,您的控件永遠無法達到您的請求方法。 如果你想要一個看起來不錯的頁面,你可以使用web.xml並配置它來產生你的答案。

<error-page> 
    <error-code>404</error-code> 
    <location>/pages/resource-not-found.html</location> 
</error-page> 

一般來說,如果你想要去的過去,這400問題,你將有幾個annotiations添加到您的User.java以避免同時反序列任何未知領域。

1

首先,我建議你使用BindingResult作爲POST調用的參數並檢查它是否會返回一個錯誤或沒有。

@RequestMapping(value = {"register"}, method = RequestMethod.POST, produces = "application/hal+json") 
public ResponseEntity<?> registerClient(@RequestBody User user, HttpServletRequest request, BindingResult brs) 
    if (!brs.hasErrors()) { 
     // add the new one 
     return new ResponseEntity<User>(user, HttpStatus.CREATED); 
    } 
    return new ResponseEntity<String>(brs.toString(), HttpStatus.BAD_REQUEST); 
} 

其次,呼叫可以拋出一些錯誤的,一個好的做法是carch他們並返回他們自己或他們轉化爲自己的異常對象。它的優點是保證了所有更新/修改方法的調用(POST,PUT,PATCH)

@ExceptionHandler(MethodArgumentNotValidException.class) 
@ResponseBody 
public ResponseEntity<?> handleMethodArgumentNotValidException(MethodArgumentNotValidException e) { 
    return new ResponseEntity<List<MethodArgumentNotValidException>>(e, HttpStatus.BAD_REQUEST); 
} 

@ExceptionHandler({HttpMessageNotReadableException.class}) 
@ResponseBody 
public ResponseEntity<?> handleHttpMessageNotReadableException(HttpMessageNotReadableException e) { 
    return new ResponseEntity<List<HttpMessageNotReadableException>>(e, HttpStatus.BAD_REQUEST); 
} 
+0

不知道!看起來非常有用,謝謝! –

+0

歡迎:)有很多方法來處理異常。我選擇了這個,因爲使用Spring AOP很容易記錄。 –