我有一个spring boot 1.3.3应用程序。我有一个休息控制器,在某些情况下抛出异常。抛出异常并打印消息,但未触发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)
答案 0 :(得分:0)
您的日志文件中是否包含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;
}
}
答案 1 :(得分:0)
可能有一些处理此请求的其他处理程序(from first 5 lines of console output
)。这可能出现在项目构建路径中的任何jar中。
我们需要将处理程序的优先级设置为最高,因此控件首先来到这里。
我认为在@Order(Ordered.HIGHEST_PRECEDENCE)
之后添加@EnableWebMvc
可能会解决问题。
@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
(无论它控制的是什么异常,都会来到这里)。在你的情况下,调试也会有所帮助。