首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >Spring MVC,将@ExceptionHandler迁移到RESTful服务的HandlerExceptionResolver

Spring MVC,将@ExceptionHandler迁移到RESTful服务的HandlerExceptionResolver
EN

Stack Overflow用户
提问于 2012-06-05 01:53:32
回答 2查看 9K关注 0票数 9

背景

我有一个错误消息类:

代码语言:javascript
复制
@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:

代码语言:javascript
复制
@ExceptionHandler
@ResponseStatus(HttpStatus.NOT_FOUND)
@ResponseBody
ErrorMessage handleException(RuntimeException e) {
    return new ErrorMessage("something went wrong");
}

每当客户端在发出以application/json作为Accept头部的请求后触发RuntimeException时,它都会收到正确的状态码和匹配的JSON主体的响应:

代码语言:javascript
复制
{"error":"something went wrong"}

或者,如果Accept标头为application/xml,则接收XML体

代码语言:javascript
复制
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<errorMessage><error>something went wrong</error></errorMessage>

问题

现在,我想通过实现一个HandlerExceptionResolver来推广这个解决方案,这样我就不必将@ExceptionHandler复制/粘贴到每个控制器(或者创建一个其他控制器可以扩展的通用“父控制器”)。

但是,AbstractHandlerExceptionResolver.doResolveException()方法返回的是ModelAndView,而不是我指定的ErrorMessage,所以我尝试了以下方法:

代码语言:javascript
复制
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()方法。客户端的响应具有预期的状态代码,但内容类型是主体中包含html的text/html,而不是原始请求中的Accept头部指定的JSON或XLM内容。

(附注,上面示例中的实际异常、响应代码和文本消息并不重要,它们只是一个简单的示例。)

Spring版本: 3.1.1.RELEASE

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2012-09-24 05:07:58

我花了一些时间调查这个问题,我写了一个blog post,在其中我提出了一个问题的解决方案。

更新:如果你使用的是Spring3.2,你可以利用@ControllerAdvice注解。更多详细信息可以在我的second blog post中找到。

票数 4
EN

Stack Overflow用户

发布于 2012-06-05 04:14:05

为了让@ExceptionHandler使用内容协商,AnnotationMethodHandlerExceptionResolver有一个setMessageConverters()方法,该方法必须与消息转换器一起提供,例如:

代码语言:javascript
复制
<bean class="org.springframework.web.servlet.mvc.annotation.AnnotationMethodHandlerExceptionResolver">
    <property name="messageConverters">
        <list>
            <ref bean="xmlConverter"/>
            <ref bean="jsonConverter"/>
        </list>
    </property>
</bean>

但是,由于您使用的是自定义方法,因此您可能必须自己实现此功能。最简单的方法可能是从AnnotationMethodHandlerExceptionResolver source执行Ctrl-C Ctrl-V,特别是handleResponseBody()方法。

票数 4
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/10885795

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档