簡體   English   中英

ControllerAdvice不處理異常

[英]ControllerAdvice not handling exception

我有一個Spring Boot 1.3.3應用程序。 我有一個rest控制器,在某些情況下會引發異常。 將引發異常並打印消息,但不會觸發ControllerAdvice類。 這是我的相關文件:TestController.java

@Controller
public class TestController {
    // RESTful method
    @RequestMapping(
            value = "/test",
            method = RequestMethod.POST,
            consumes = "application/json",
            produces = "application/json")
    @ResponseBody
    public JsonNode fooRestTest(@RequestHeader HttpHeaders header,
            @RequestBody String payload) {
        ControllerUtil.validateHeaders(header);
        return null;
    }
}

ControllerUtil.java

public class ControllerUtil {
    public static void validateHeaders(HttpHeaders headers) {
        if(headers.get("test-field") == null) {
            throw new InvalidHeaderException("Invalid test-field in header");
        }
    }
}

InvalidHeaderException.java

public class InvalidHeaderException extends RuntimeException {


    public InvalidHeaderException(String message) {
        super(message);
    }

    public InvalidHeaderException(String message, Throwable cause) {
        super(message, cause);
    }
}

AppErrorController.java

@ControllerAdvice
@EnableWebMvc
public class AppErrorController {

    @ExceptionHandler(InvalidHeaderException.class)
    public ModelAndView handleHeaderError(HttpServletRequest req, Exception ex) {
        ModelAndView mav = new ModelAndView();
        mav.addObject("exception", ex);
        mav.addObject("url", req.getRequestURL());
        mav.addObject("timestamp", LocalDateTime.now());
        mav.addObject("status", 400);
        return mav;
    }
}

web.xml

<web-app id="RBGApp" version="3.0"
    xmlns="http://java.sun.com/xml/ns/javaee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd">

    <display-name>FooTester</display-name>

    <servlet>
        <servlet-name>Foo_Test</servlet-name>
        <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
        <load-on-startup>1</load-on-startup>
    </servlet>

    <!-- Mappings -->
    <servlet-mapping>
        <servlet-name>Foo_Test</servlet-name>
        <url-pattern>/</url-pattern>
    </servlet-mapping>

</web-app>

MvcConfiguration.java

@Configuration
@EnableWebMvc
public class MvcConfiguration extends WebMvcConfigurerAdapter {
    @Autowired
    ServletContext servletContext;

    @Override
    public void configureDefaultServletHandling(
            DefaultServletHandlerConfigurer configurer) {
        configurer.enable();
    }

    @Bean
    public ViewResolver getJspViewResolver() {
        InternalResourceViewResolver resolver = new InternalResourceViewResolver();
        resolver.setPrefix("WEB-INF/jsp/views/");
        resolver.setSuffix(".jsp");
        resolver.setOrder(1);
        return resolver;
    }
}

我用郵遞員的請求對此進行了測試,它引發異常並打印出以下行:

Invalid test-field in header

但是代碼根本不會進入AppErrorController中。 因此,不會填充其他任何值(例如timestamp 任何想法我在這里做錯了嗎?

編輯1:這是郵遞員吐出來的內容:

<html>
    <head>
        <title>Apache Tomcat/7.0.62 - Error report</title>
        <style>
            <!--H1 {font-family:Tahoma,Arial,sans-serif;color:white;background-color:#525D76;font-size:22px;} H2 {font-family:Tahoma,Arial,sans-serif;color:white;background-color:#525D76;font-size:16px;} H3 {font-family:Tahoma,Arial,sans-serif;color:white;background-color:#525D76;font-size:14px;} BODY {font-family:Tahoma,Arial,sans-serif;color:black;background-color:white;} B {font-family:Tahoma,Arial,sans-serif;color:white;background-color:#525D76;} P {font-family:Tahoma,Arial,sans-serif;background:white;color:black;font-size:12px;}A {color : black;}A.name {color : black;}HR {color : #525D76;}-->
        </style> 
    </head>
    <body>
        <h1>HTTP Status 500 - Invalid test-field in header</h1>
        <HR size="1" noshade="noshade">
        <p>
            <b>type</b> Exception report
        </p>
        <p>
            <b>message</b>
            <u>Invalid test-field in header</u>
        </p>
        <p>
            <b>description</b>
            <u>The server encountered an internal error that prevented it from fulfilling this request.</u>
        </p>
        <p>
            <b>exception</b>
            <pre>controllers.exceptions.InvalidHeaderException: Invalid test-field in header
    controllers.util.ControllerUtil.validateHeaders(ControllerUtil.java:12)
    controllers.TestController.fooRestTest(TestController.java:77)
    sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
    sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    java.lang.reflect.Method.invoke(Method.java:497)
    org.springframework.web.method.support.InvocableHandlerMethod.doInvoke(InvocableHandlerMethod.java:221)
    org.springframework.web.method.support.InvocableHandlerMethod.invokeForRequest(InvocableHandlerMethod.java:136)
    org.springframework.web.servlet.mvc.method.annotation.ServletInvocableHandlerMethod.invokeAndHandle(ServletInvocableHandlerMethod.java:110)
    org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.invokeHandlerMethod(RequestMappingHandlerAdapter.java:814)
    org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.handleInternal(RequestMappingHandlerAdapter.java:737)
    org.springframework.web.servlet.mvc.method.AbstractHandlerMethodAdapter.handle(AbstractHandlerMethodAdapter.java:85)
    org.springframework.web.servlet.DispatcherServlet.doDispatch(DispatcherServlet.java:959)
    org.springframework.web.servlet.DispatcherServlet.doService(DispatcherServlet.java:893)
    org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:969)
    org.springframework.web.servlet.FrameworkServlet.doPost(FrameworkServlet.java:871)
    javax.servlet.http.HttpServlet.service(HttpServlet.java:650)
    org.springframework.web.servlet.FrameworkServlet.service(FrameworkServlet.java:845)
    javax.servlet.http.HttpServlet.service(HttpServlet.java:731)
    org.apache.tomcat.websocket.server.WsFilter.doFilter(WsFilter.java:52)
    org.springframework.boot.context.web.ErrorPageFilter.doFilter(ErrorPageFilter.java:120)
    org.springframework.boot.context.web.ErrorPageFilter.access$000(ErrorPageFilter.java:61)
    org.springframework.boot.context.web.ErrorPageFilter$1.doFilterInternal(ErrorPageFilter.java:95)
    org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107)
    org.springframework.boot.context.web.ErrorPageFilter.doFilter(ErrorPageFilter.java:113)
</pre>
        </p>
        <p>
            <b>note</b>
            <u>The full stack trace of the root cause is available in the Apache Tomcat/7.0.62 logs.</u>
        </p>
        <HR size="1" noshade="noshade">
        <h3>Apache Tomcat/7.0.62</h3>
    </body>
</html>

編輯2:發出郵遞員請求時的控制台輸出

09:08:14.373 [http-bio-8080-exec-1] DEBUG org.springframework.web.servlet.DispatcherServlet - DispatcherServlet with name 'Foo_Test' processing POST request for [/TEST]
09:08:14.381 [http-bio-8080-exec-1] DEBUG org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerMapping - Looking up handler method for path /test
09:08:14.390 [http-bio-8080-exec-1] DEBUG org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerMapping - Returning handler method [public com.fasterxml.jackson.databind.JsonNode controllers.AlertController.getAlertsForRest(org.springframework.http.HttpHeaders,java.lang.String)]
09:08:14.390 [http-bio-8080-exec-1] DEBUG org.springframework.beans.factory.support.DefaultListableBeanFactory - Returning cached instance of singleton bean 'alertController'
09:08:14.426 [http-bio-8080-exec-1] DEBUG org.springframework.web.servlet.mvc.method.annotation.RequestResponseBodyMethodProcessor - Read [class java.lang.String] as "application/json" with [org.springframework.http.converter.StringHttpMessageConverter@4732b26d]
09:08:14.436 [http-bio-8080-exec-1] DEBUG org.springframework.web.servlet.mvc.method.annotation.ExceptionHandlerExceptionResolver - Resolving exception from handler [public com.fasterxml.jackson.databind.JsonNode controllers.AlertController.getAlertsForRest(org.springframework.http.HttpHeaders,java.lang.String)]: controllers.exceptions.InvalidHeaderException: Invalid test-field in header
09:08:14.439 [http-bio-8080-exec-1] DEBUG org.springframework.web.servlet.mvc.annotation.ResponseStatusExceptionResolver - Resolving exception from handler [public com.fasterxml.jackson.databind.JsonNode controllers.AlertController.getAlertsForRest(org.springframework.http.HttpHeaders,java.lang.String)]: controllers.exceptions.InvalidHeaderException: Invalid test-field in header
09:08:14.439 [http-bio-8080-exec-1] DEBUG org.springframework.web.servlet.mvc.support.DefaultHandlerExceptionResolver - Resolving exception from handler [public com.fasterxml.jackson.databind.JsonNode controllers.AlertController.getAlertsForRest(org.springframework.http.HttpHeaders,java.lang.String)]: controllers.exceptions.InvalidHeaderException: Invalid test-field in header
09:08:14.443 [http-bio-8080-exec-1] DEBUG org.springframework.web.servlet.DispatcherServlet - Could not complete request
controllers.exceptions.InvalidHeaderException: Invalid test-field in header
    controllers.util.ControllerUtil.validateHeaders(ControllerUtil.java:12)
    controllers.TestController.fooRestTest(TestController.java:77)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    at java.lang.reflect.Method.invoke(Method.java:497)
    at org.springframework.web.method.support.InvocableHandlerMethod.doInvoke(InvocableHandlerMethod.java:222)
    at org.springframework.web.method.support.InvocableHandlerMethod.invokeForRequest(InvocableHandlerMethod.java:137)
    at org.springframework.web.servlet.mvc.method.annotation.ServletInvocableHandlerMethod.invokeAndHandle(ServletInvocableHandlerMethod.java:110)
    at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.invokeHandlerMethod(RequestMappingHandlerAdapter.java:814)
    at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.handleInternal(RequestMappingHandlerAdapter.java:737)
    at org.springframework.web.servlet.mvc.method.AbstractHandlerMethodAdapter.handle(AbstractHandlerMethodAdapter.java:85)
    at org.springframework.web.servlet.DispatcherServlet.doDispatch(DispatcherServlet.java:959)
    at org.springframework.web.servlet.DispatcherServlet.doService(DispatcherServlet.java:893)
    at org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:969)
    at org.springframework.web.servlet.FrameworkServlet.doPost(FrameworkServlet.java:871)
    at javax.servlet.http.HttpServlet.service(HttpServlet.java:650)
    at org.springframework.web.servlet.FrameworkServlet.service(FrameworkServlet.java:845)
    at javax.servlet.http.HttpServlet.service(HttpServlet.java:731)
    at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:303)
    at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:208)
    at org.apache.tomcat.websocket.server.WsFilter.doFilter(WsFilter.java:52)
    at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:241)
    at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:208)
    at org.springframework.boot.context.web.ErrorPageFilter.doFilter(ErrorPageFilter.java:120)
    at org.springframework.boot.context.web.ErrorPageFilter.access$000(ErrorPageFilter.java:61)
    at org.springframework.boot.context.web.ErrorPageFilter$1.doFilterInternal(ErrorPageFilter.java:95)
    at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107)
    at org.springframework.boot.context.web.ErrorPageFilter.doFilter(ErrorPageFilter.java:113)
    at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:241)
    at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:208)
    at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:220)
    at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:122)
    at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:505)
    at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:170)
    at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:103)
    at org.apache.catalina.valves.AccessLogValve.invoke(AccessLogValve.java:957)
    at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:116)
    at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:423)
    at org.apache.coyote.http11.AbstractHttp11Processor.process(AbstractHttp11Processor.java:1079)
    at org.apache.coyote.AbstractProtocol$AbstractConnectionHandler.process(AbstractProtocol.java:620)
    at org.apache.tomcat.util.net.JIoEndpoint$SocketProcessor.run(JIoEndpoint.java:316)
    at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142)
    at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617)
    at org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:61)
    at java.lang.Thread.run(Thread.java:745)

您是否有類似java.lang.IllegalStateException: No suitable resolver for argument消息java.lang.IllegalStateException: No suitable resolver for argument日志文件中java.lang.IllegalStateException: No suitable resolver for argument

嘗試在handleHeaderError方法參數處使用相同的異常類型: InvalidHeaderException而不是Exception 像這樣:

@ControllerAdvice
@EnableWebMvc
public class AppErrorController {

@ExceptionHandler(InvalidHeaderException.class)
public ModelAndView handleHeaderError(HttpServletRequest req, InvalidHeaderException ex) {
    ModelAndView mav = new ModelAndView();
    mav.addObject("exception", ex);
    mav.addObject("url", req.getRequestURL());
    mav.addObject("timestamp", LocalDateTime.now());
    mav.addObject("status", 400);
    return mav;
}

}

可能還有其他處理程序正在處理此請求( from first 5 lines of console output )。 這可能在項目的構建路徑中的任何jar中。

我們需要將您的處理程序的優先級設置為“最高”,因此控制首先出現在這里。

我認為在@EnableWebMvc之后添加@Order(Ordered.HIGHEST_PRECEDENCE)可能會解決問題。

@ControllerAdvice
@EnableWebMvc
@Order(Ordered.HIGHEST_PRECEDENCE)
public class AppErrorController {

@ExceptionHandler(InvalidHeaderException.class)
public ModelAndView handleHeaderError(HttpServletRequest req, InvalidHeaderException ex) {
    ModelAndView mav = new ModelAndView();
    mav.addObject("exception", ex);
    mav.addObject("url", req.getRequestURL());
    mav.addObject("timestamp", LocalDateTime.now());
    mav.addObject("status", 400);
    return mav;
}

另外,如果不起作用,請嘗試將InvalidHeaderException.class更改為Exception.class (無論控制什么異常,都將在此處出現)。 同樣,調試將對您有幫助。

暫無
暫無

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

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