我正在使用SpringMVC,並且我想處理其他控制器上的異常。 我的控制器通常在響應輸出中寫入一個json,但是當發生異常時,我無法捕獲它並返回tomcat html頁面。SpringMVC處理其他控制器中的錯誤
如何根據請求中的「accept」參數捕獲全局異常並返回適當的響應?
我正在使用SpringMVC,並且我想處理其他控制器上的異常。 我的控制器通常在響應輸出中寫入一個json,但是當發生異常時,我無法捕獲它並返回tomcat html頁面。SpringMVC處理其他控制器中的錯誤
如何根據請求中的「accept」參數捕獲全局異常並返回適當的響應?
ExceptionHandler annotation正在做你想要的hwat。
@ControllerAdvice註解是在Spring 3.2發行版中添加的新註釋。從reference docs:
中的類@ControllerAdvice註釋可以包含@ExceptionHandler,@InitBinder和@ModelAttribute方法和那些將適用於整個@RequestMapping控制器層次的方法,而不是內聲明它們控制器層次。 @ControllerAdvice是一個組件註釋,允許通過類路徑掃描來自動檢測實現類。
例子:
@ControllerAdvice
class GlobalControllerExceptionHandler {
// Basic example
@ExceptionHandler
@ResponseStatus(HttpStatus.BAD_REQUEST)
@ResponseBody
ErrorMessage handleException(FirstException ex) {
ErrorMessage errorMessage = createErrorMessage(ex);
return errorMessage;
}
// Multiple exceptions can be handled
@ExceptionHandler({SecondException.class, ThirdException.class})
@ResponseStatus(HttpStatus.BAD_REQUEST)
@ResponseBody
ErrorMessage handleException() {
ErrorMessage errorMessage = createErrorMessage(...);
return errorMessage;
}
// Returning a custom response entity
@ExceptionHandler
ResponseEntity<ErrorMessage> handleException(OtherException ex) {
ErrorMessage errorMessage = createErrorMessage(...);
ResponseEntity<ErrorMessage> responseEntity = new ResponseEntity<ErrorMessage>(errorMessage, HttpStatus.BAD_REQUEST);
return responseEntity;
}
}
基本上,它可以讓你捕捉指定的異常,創建一個自定義的ErrorMessage
(這是根據Accept
頭自定義錯誤類,Spring將序列化到響應正文),在本例中將響應狀態設置爲400 - Bad Request
。請注意,最後一個示例返回ResponseEntity(並且不是註釋@ResponseBody
),它允許您以編程方式指定響應狀態和其他響應標頭。有關@ExceptionHandler
的更多信息可以在reference docs或我之前寫的blog post中找到。
更新:根據評論添加更多示例。
很好的答案! @ControllerAdvice是Spring 3.2中最好的事情之一!你也可以把多個映射放到'@ExceptionHandler({Exception1.class,Exception2.class})'。更新帖子信息可能很有趣,當然我認爲。 – 2013-04-30 17:14:08
用這個解決方案可以以編程方式設置響應狀態嗎?我需要這些用於我的用例,並且可以在我的解決方案中看到它可能在那裏。但是,感謝分享這種新方法,將派上用場。 – Matsemann 2013-04-30 17:22:15
@DeividiCavarzan完成! – matsev 2013-05-01 08:47:26
另一種方法(我使用的是)創建一個全局異常處理程序,並告訴Spring它應該被使用。那麼當用@ExceptionHandler
註釋控制器方法時,您不必重複邏輯或擴展相同的基礎控制器。這是一個簡單的例子。
public class ExceptionHandler implements HandlerExceptionResolver {
@Override
public ModelAndView resolveException(HttpServletRequest httpServletRequest, HttpServletResponse response, Object o, Exception e) {
response.setStatus(HttpServletResponse.SC_INTERNAL_SERVER_ERROR); // Or some other error code
ModelAndView mav = new ModelAndView(new MappingJackson2JsonView());
mav.addObject("error", "Something went wrong: \"" + e.getMessage() + "\"");
return mav;
}
}
而在<something>-servlet.xml
你將它設爲您想要的exceptionResolver:
<!-- Define our exceptionHandler as the resolver for our program -->
<bean id="exceptionResolver" class="tld.something.ExceptionHandler" />
然後所有的異常將被髮送到您的ExceptionHandler,在那裏你可以看看的請求,並決定如何應該回復給用戶。在我的情況下,我正在使用傑克遜。
查看['@ ExceptionHandler'](http://static.springsource.org/spring/docs/3.1.x/javadoc-api/org/springframework/web/bind/annotation/ExceptionHandler.html)註釋。 – 2013-04-30 15:15:01