簡體   English   中英

ExceptionHandler不適用於Throwable

[英]ExceptionHandler doesn't work with Throwable

我們的是基於Spring MVC的REST應用程序。 我正在嘗試使用ExceptionHandler批注來處理所有錯誤和異常。

我有

    @ExceptionHandler(Throwable.class)
    public @ResponseBody String handleErrors() {
        return "error";
    }

只要拋出異常,它就不會對任何錯誤起作用。

我正在使用Spring 4.0。 有什么解決方法嗎?

ExceptionHandler#value()屬性所指示的相反

Class<? extends Throwable>[] value() default {};

@ExceptionHandler僅用於處理Exception及其子類型。

Spring使用ExceptionHandlerExceptionResolver通過以下方法解析帶注釋的處理程序

doResolveHandlerMethodException(HttpServletRequest request,
        HttpServletResponse response, HandlerMethod handlerMethod, Exception exception) 

如您所見,它僅接受Exception

使用這種配置,您無法使用@ExceptionHandler處理ThrowableError類型。

我會告訴您提供自己的HandlerExceptionResolver實現,該實現可以處理Throwable實例,但是您需要自己提供自己的DispatcherServlet (以及大多數MVC堆棧),因為DispatcherServlet不會在任何可以放置Throwable實例的地方catch顯着差異。


更新:

從4.3開始,Spring MVC將拋出的Throwable值包裝在NestedServletException實例中,並將其公開給ExceptionHandlerExceptionResolver

您可以執行一種Hacking來捕獲Spring MVC中的Error。 首先,定義一個攔截器,如下所示:

public class ErrorHandlingInterceptor extends HandlerInterceptorAdapter {
    public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception
{
    super.afterCompletion(request, response, handler, ex);

    controller.handleError(ex.getCause(), request, response);
} }

其次,在控制器中定義一個方法,例如“ handleError”方法:

    ErrorResponse errorResponse = new ErrorResponse();
    errorResponse.setExceptionId(exceptionId);
    errorResponse.setErrorMsg(ex.toString());
    errorResponse.setServerStackTrace(serverStackTrace(ex));

    response.setStatus(responseCode);
    response.setContentType("application/json");

    ObjectWriter writer = mapper.writer().withDefaultPrettyPrinter();
    writer.writeValue(response.getOutputStream(), errorResponse);

最后,在Spring配置中配置攔截器。

<mvc:interceptors>
    <bean class="ErrorHandlingInterceptor" />
</mvc:interceptors>

DispatchServlet中的代碼:

            catch (Exception ex) {
            Object handler = (mappedHandler != null ? mappedHandler.getHandler() : null);
// This is where to handle Exception by Spring.
// If Error happens, it will go to catch Error statement 
// which will call afterCompletion method
            mv = processHandlerException(processedRequest, response, handler, ex);
            errorView = (mv != null);
        }

        // Did the handler return a view to render?
        if (mv != null && !mv.wasCleared()) {
            render(mv, processedRequest, response);
            if (errorView) {
                WebUtils.clearErrorRequestAttributes(request);
            }
        }
        else {
            if (logger.isDebugEnabled()) {
                logger.debug("Null ModelAndView returned to DispatcherServlet with name '" + getServletName() +
                        "': assuming HandlerAdapter completed request handling");
            }
        }

        // Trigger after-completion for successful outcome.
        triggerAfterCompletion(mappedHandler, interceptorIndex, processedRequest, response, null);
    }

    catch (Exception ex) {
        // Trigger after-completion for thrown exception.
        triggerAfterCompletion(mappedHandler, interceptorIndex, processedRequest, response, ex);
        throw ex;
    }
    catch (Error err) {
        ServletException ex = new NestedServletException("Handler processing failed", err);
        // Trigger after-completion for thrown exception.
        triggerAfterCompletion(mappedHandler, interceptorIndex, processedRequest, response, ex);
        throw ex;
    }

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM