简体   繁体   English

如何使用ControllerAdvice注释的类来处理不同类型的异常?

[英]How to have a class annotated by ControllerAdvice to handle different types of exceptions?

I have a class called GlobalExceptionHandler that is annotated by ControllerAdvice . 我有一个名为GlobalExceptionHandler的类,该类由ControllerAdvice注释。 It properly handle all NoHandlerFoundExceptions . 它可以正确处理所有NoHandlerFoundExceptions I added a new method to to handle InternalError exceptions but it does not handle such exceptions; 我添加了一个新方法来处理InternalError异常,但它不处理此类异常。 therefore, I am still receiving HTTP Status 500 . 因此,我仍然收到HTTP Status 500

Based on this link the exception class of 500 (Internal Server Error) is ConversionNotSupportedException . 根据此链接 ,异常类500 (Internal Server Error)ConversionNotSupportedException

I tried following codes but none of the catch Internal Server Error. 我尝试了以下代码,但没有捕获内部服务器错误。

1 1个

@ControllerAdvice
public class GlobalExceptionHandler {
    @ExceptionHandler
    @ResponseStatus(HttpStatus.NOT_FOUND)
    public String handleExceptionNotFound(NoHandlerFoundException ex) {
        System.err.println("not found");
        return "redirect:/error";
    }

    @ExceptionHandler(ConversionNotSupportedException.class)
//  @ResponseStatus(HttpStatus.INTERNAL_SERVER_ERROR)
    public String handleExceptionsInternalError(ConversionNotSupportedException ex) {
        ex.printStackTrace();
        System.err.println("internal error");
        return "redirect:/error";
    }

}

2 2

@ExceptionHandler(ConversionNotSupportedException.class)
public String handleExceptionsInternalError(HttpServletRequest req, ConversionNotSupportedException ex) {

3 3

@ExceptionHandler
@ResponseStatus(HttpStatus.INTERNAL_SERVER_ERROR)
public String handleExceptionsInternalError(ConversionNotSupportedException ex) {

Exception that I need to handle is as follows: 我需要处理的异常如下:

HTTP Status 500 - Could not resolve view with name 'user' in servlet with name 'myproject'
javax.servlet.ServletException: Could not resolve view with name 'user' in servlet with name 'myproject'
    org.springframework.web.servlet.DispatcherServlet.render(DispatcherServlet.java:1211)
    org.springframework.web.servlet.DispatcherServlet.processDispatchResult(DispatcherServlet.java:1011)
    org.springframework.web.servlet.DispatcherServlet.doDispatch(DispatcherServlet.java:955)
    org.springframework.web.servlet.DispatcherServlet.doService(DispatcherServlet.java:877)
    org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:966)
    org.springframework.web.servlet.FrameworkServlet.doGet(FrameworkServlet.java:857)
    javax.servlet.http.HttpServlet.service(HttpServlet.java:620)
    org.springframework.web.servlet.FrameworkServlet.service(FrameworkServlet.java:842)
    javax.servlet.http.HttpServlet.service(HttpServlet.java:727)
    org.apache.tomcat.websocket.server.WsFilter.doFilter(WsFilter.java:52)

It looks like your exception handler is returning an invalid view, which results in an exception in the code that calls the exception handler. 看起来您的异常处理程序正在返回一个无效的视图,这会在调用异常处理程序的代码中导致异常。 See DispatcherServlet.processDispatchResult 请参阅DispatcherServlet.processDispatchResult

In this case the exception is thrown from the DispatcherServlet itself, and the only way to handle it is through web.xml 在这种情况下,异常是从DispatcherServlet本身引发的,并且处理异常的唯一方法是通过web.xml

You need to fix your exception handler to return a valid view. 您需要修复异常处理程序才能返回有效视图。 The other answers to handle using @ExceptionHandler(Exception.class) are valid and can be used to handle exceptions thrown from your controllers. 使用@ExceptionHandler(Exception.class)处理的其他答案是有效的,可用于处理从控制器抛出的异常。

Update : Based on the @Jack's comment that the exception is caused by a controller returning a view that does not exist (and not the exception handler as I originally thought). 更新 :基于@Jack的评论,该异常是由控制器返回不存在的视图(而不是我最初认为的异常处理程序)引起的。 Once you return a view, the container calls the view resolver to render it and if that throws an exception, the exception handler will not be invoked (see this & this )- the easy solution is to handle it in web.xml. 返回视图后,容器将调用视图解析器来呈现它,如果抛出异常,则将不会调用异常处理程序(请参见thisthis ),最简单的解决方案是在web.xml中处理它。

Another option is to override the view resolver.resolveViewName, say you are using InternalResourceViewResolver which could look like this: 另一个选择是重写视图resolver.resolveViewName,比如说您正在使用InternalResourceViewResolver ,它看起来可能像这样:

public class CustomViewResolver extends InternalResourceViewResolver {
    @Override
    public View resolveViewName(String viewName,
                            Locale locale) throws Exception {
        try{
            return super.resolveViewName();
        } catch (Exception ex) {
            //log
            return new InternalResourceView("urlForErrorView");
       }
    }
}

It seems like controller advice is not able to handle such exception. 似乎控制器建议无法处理此类异常。 I added following code to my web.xml to handle this exception. 我在我的web.xml添加了以下代码来处理此异常。 If you have any better solution please let me know. 如果您有更好的解决方案,请告诉我。 Thanks. 谢谢。

<error-page>
    <error-code>500</error-code>
    <location>/errorhandler</location>
</error-page>

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM