ResponseBody 方法和普通方法的多个异常处理程序

Posted

技术标签:

【中文标题】ResponseBody 方法和普通方法的多个异常处理程序【英文标题】:Multiple exception handlers for ResponseBody methods and normal methods 【发布时间】:2014-01-23 13:12:15 【问题描述】:

我有一个要求,我想处理如何返回异常。如果使用 @ResponseBody 注释控制器方法的类型,则应返回 json 字符串。另外如果是String返回方法,应该返回jsp错误页面。

但是,我似乎无法定义两个全局异常处理程序(带有 ControllerAdvice),它们都处理 Exception.class,但一个返回 ModelAndView,另一个使用 @ResponseBody 进行注释。我收到一个例外,说它太模棱两可了。

org.springframework.beans.factory.BeanCreationException:创建名为“org.springframework.web.servlet.mvc.method.annotation.ExceptionHandlerExceptionResolver#0”的bean时出错:调用init方法失败;嵌套异常是 java.lang.IllegalStateException: Ambiguous @ExceptionHandler method mapped for [class java.lang.Exception]

以下代码是处理这两种情况的理想情况的示例

方法

@RequestMapping(value = "/pathValue/page", method = RequestMethod.GET)
public String getPage(@PathVariable(value="pathValue") String pathValue, ModelMap model) throws Exception 

@RequestMapping(value = "pathValue/jsonData", method = RequestMethod.GET, produces = MediaType.APPLICATION_JSON_VALUE)
public @ResponseBody ModelMap getJson(@PathVariable(value="pathValue") String pathValue) throws Exception  

异常处理程序

@ExceptionHandler(Exception.class)
@ResponseBody ErrorInfo handleBadRequest(HttpServletRequest req, Exception ex) 

@ExceptionHandler(value = Exception.class)
public ModelAndView defaultErrorHandler(HttpServletRequest req, Exception e) throws Exception  

在上面的例子中,getPage方法应该由handleBadRequest处理,getJson应该由defaultErrorHandler处理

有没有办法配置两个全局异常处理程序,它们都处理相同的异常类并根据控制器方法类型返回页面或json。

【问题讨论】:

【参考方案1】:

我想不是开箱即用的,因为 AbstractHandlerMethodExceptionResolver 不能做你想做的事。如果我没记错的话,接口没有参数可以指示抛出特定异常实例的方法。

我记得过去创建可配置为特定异常类型的包装实现(例如方面)对我有帮助。这样的实现将包装每个控制器的方法调用并捕获所有异常,只是为了将其包装为可配置的异常类型并重新抛出。在您的情况下,它将类似于 JsonSomethingException 和 ResourceSomethingException。

另一种选择可能是相反的(更底层的)方法。请注意,在异常处理方法中,您会收到 HttpServletRequest 实例,因此可以浏览有关请求的一些数据。在您的情况下,@RequestMapping 基于此数据来确定应该调用哪个方法 - 您可以在异常处理程序中执行相同的操作!最好的(恕我直言)方法是通过 HTTP 协议的 Content-Type 标头来区分 json 和 html 。在这种情况下,编写单个全局错误处理程序,根据 Content-Type 返回适当的 ResponseEntity 将非常容易。尤其是添加了一些 json 解析器(例如 Jackson)。

祝你好运:)。

【讨论】:

以上是关于ResponseBody 方法和普通方法的多个异常处理程序的主要内容,如果未能解决你的问题,请参考以下文章

SpringBoot全局异常

@ResponseBody 和 @RequestBody 注解的区别

ajax 请求后台数据返回异常 及 提示404方法名不存在

Restful接口调用统一异常处理

如何在 Spring Boot @ResponseBody 中返回 404 响应状态 - 方法返回类型是响应?

关于@ResponseBody的使用