SpringMVC处理rest控制器中的错误



我正在使用SpringMVC,我想处理rest控制器上的异常。我的控制器通常在响应输出中写入json,但是当异常发生时,我无法捕获它并且返回tomcat html页面。

如何捕获全局异常并根据请求中的"接受"参数返回适当的响应?

@ControllerAdvice注释是Spring 3.2版本中添加的新注释。参考文档:

带@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(这是你的自定义错误类,Spring将根据Accept头序列化到响应体),并在这个例子中设置响应状态为400 - Bad Request。注意,最后一个示例返回一个ResponseEntity(并且是而不是用@ResponseBody注释的),它允许您以编程方式指定响应状态和其他响应头。关于@ExceptionHandler的更多信息可以在参考文档中找到,或者在我之前写的一篇博客文章中找到。

更新:根据注释增加了更多的例子

另一种方法(我正在使用的)是创建一个全局异常处理程序,并告诉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,在那里您可以查看请求并确定应该如何回复用户。在我的例子中,我使用的是Jackson

ExceptionHandler注释正在执行您想要的操作。

最新更新