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

时间:2014-01-06 07:05:47

标签: java json spring jsp spring-mvc

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

然而,似乎我无法定义两个处理Exception.class的全局异常处理程序(带有ControllerAdvice),但是一个返回一个ModelAndView,另一个用@ResponseBody注释。我得到一个例外,提到它过于暧昧。

org.springframework.beans.factory.BeanCreationException:创建名为'org.springframework.web.servlet.mvc.method.annotation.ExceptionHandlerExceptionResolver#0'的bean时出错:init方法的调用失败;嵌套异常是java.lang.IllegalStateException:为[类java.lang.Exception]映射的不明确的@ExceptionHandler方法

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

方法

@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处理

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

1 个答案:

答案 0 :(得分:2)

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

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

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

祝你好运:)。