[英]Spring MVC, Migrate @ExceptionHandler to HandlerExceptionResolver for a RESTful service
我有一個錯誤消息類:
@XmlRootElement
public class ErrorMessage {
private String message;
public ErrorMessage() {
}
public ErrorMessage(String message) {
this.message = message;
}
public String getError() {
return message;
}
public void setError(String message) {
this.message = message;
}
}
此類已被指定為Spring MVC REST控制器中@ExceptionHandler的返回值:
@ExceptionHandler
@ResponseStatus(HttpStatus.NOT_FOUND)
@ResponseBody
ErrorMessage handleException(RuntimeException e) {
return new ErrorMessage("something went wrong");
}
每當客戶端在使用application/json
作為Accept
標application/json
出請求后觸發RuntimeException
,它就會收到一個響應,其中包含正確的狀態代碼和匹配的JSON正文:
{"error":"something went wrong"}
或者,如果Accept
標頭是application/xml
則接收XML主體:
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<errorMessage><error>something went wrong</error></errorMessage>
現在,我想通過實現一個HandlerExceptionResolver來使這個解決方案變成一般,所以我不必將@ExceptionHandler
復制/粘貼到每個控制器(或者創建一個其他控制器可以擴展的公共“父控制器”)。
但是, AbstractHandlerExceptionResolver.doResolveException()方法返回ModelAndView
而不是我的專有ErrorMessage
,所以我嘗試了以下內容:
public class RuntimeExceptionHandlerExceptionResolver extends AbstractHandlerExceptionResolver {
@Override
protected ModelAndView doResolveException(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) {
if (ex instanceof RuntimeException) {
response.setStatus(HttpServletResponse.SC_NOT_FOUND);
ModelAndView mav = new ModelAndView();
mav.addObject("error", "something went wrong");
return mav;
}
return null;
}
}
調試時,我可以看到調用了mav.addObject()
方法。 客戶端的響應具有預期的狀態代碼,但內容類型是text/html
帶有html的text/html
,而不是原始請求中的Accept
標頭指定的JSON或XLM內容。
(旁注,上面示例中的實際異常,響應代碼和文本消息並不重要,它們只是用作簡單示例。)
Spring版本:3.1.1.RELEASE
要使@ExceptionHandler
使用內容協商, AnnotationMethodHandlerExceptionResolver
有一個setMessageConverters()
方法,必須與消息轉換器一起提供,例如:
<bean class="org.springframework.web.servlet.mvc.annotation.AnnotationMethodHandlerExceptionResolver">
<property name="messageConverters">
<list>
<ref bean="xmlConverter"/>
<ref bean="jsonConverter"/>
</list>
</property>
</bean>
但由於您使用的是自定義方法,因此您可能必須自己實現此功能。 最簡單的方法可能是來自AnnotationMethodHandlerExceptionResolver
源的 Ctrl-C Ctrl-V
,特別是handleResponseBody()
方法。
我花了一些時間調查此事,我寫了一篇博文 ,其中我提出了解決問題的方法。
更新:如果您使用的是Spring 3.2,則可以利用@ControllerAdvice批注。 更多細節可以在我的第二篇博文中找到。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.