提问人:Ioannis Zisis 提问时间:11/3/2023 最后编辑:Ioannis Zisis 更新时间:11/6/2023 访问量:75
@ExceptionHandler没有按预期工作
@ExceptionHandler not working as it was supposed to
问:
我正在观看有关 RESTful Web 服务的教程,并且正在创建一个基本的 API。在某些时候,它向我介绍了异常处理,因此为了测试它,我创建了以下类:
@ControllerAdvice
public class AppExceptionsHandler extends ResponseEntityExceptionHandler {
@ExceptionHandler(value = {Exception.class})
public ResponseEntity<CustomErrorMessage> handleAnyException(Exception ex, WebRequest request) {
String customErrorMessageDescription = ex.getLocalizedMessage();
if (customErrorMessageDescription == null)
customErrorMessageDescription = ex.toString();
CustomErrorMessage customErrorMessage = new CustomErrorMessage(new Date(), customErrorMessageDescription);
return new ResponseEntity<CustomErrorMessage>(customErrorMessage, new HttpHeaders(), HttpStatus.INTERNAL_SERVER_ERROR);
}
}
我展示的一个简单的测试是在 UserController 类中实现的 getUser 方法中捕获具有预期错误的 NullPointerException:
@GetMapping(path = "/{userId}", produces = { MediaType.APPLICATION_JSON_VALUE, MediaType.APPLICATION_XML_VALUE })
public ResponseEntity<UserRest> getUser(@PathVariable String userId) {
String firstName = null;
int length = firstName.length();
if (users.containsKey(userId)) {
return new ResponseEntity<UserRest>(users.get(userId), HttpStatus.OK);
} else {
return new ResponseEntity<UserRest>(HttpStatus.NO_CONTENT);
}
}
在本教程中,它显示,当运行代码并通过 Postman 发送 GET 请求时,您会在处理程序中收到相应的正文和信息,在控制台中没有回溯,但我在控制台中收到带有回溯的 NullPointerException 错误,而在 Postman 中,我得到了数据的默认结构,如下所示:
{
"timestamp": 1699010452939,
"status": 500,
"error": "Internal Server Error",
"path": "/users/bb3bd1f5-ab81-40f0-a025-d009e8e30ada"
}
我得到的回溯是这样的:
2023-11-03T13:20:52.933+02:00 ERROR 21760 --- [nio-8080-exec-1] o.a.c.c.C.[.[.[/].[dispatcherServlet] : Servlet.service() for servlet [dispatcherServlet] in context with path [] threw exception [Request processing failed: java.lang.NullPointerException: Cannot invoke "String.length()" because "firstName" is null] with root cause
java.lang.NullPointerException: Cannot invoke "String.length()" because "firstName" is null
at com.appsdeveloperblog.app.ws.mobileappws.ui.controller.UserController.getUser(UserController.java:34) ~[classes/:na]
at java.base/jdk.internal.reflect.DirectMethodHandleAccessor.invoke(DirectMethodHandleAccessor.java:103) ~[na:na]
at java.base/java.lang.reflect.Method.invoke(Method.java:580) ~[na:na]
at org.springframework.web.method.support.InvocableHandlerMethod.doInvoke(InvocableHandlerMethod.java:253) ~[spring-web-6.1.0-RC2.jar:6.1.0-RC2]
at org.springframework.web.method.support.InvocableHandlerMethod.invokeForRequest(InvocableHandlerMethod.java:181) ~[spring-web-6.1.0-RC2.jar:6.1.0-RC2]
at org.springframework.web.servlet.mvc.method.annotation.ServletInvocableHandlerMethod.invokeAndHandle(ServletInvocableHandlerMethod.java:118) ~[spring-webmvc-6.1.0-RC2.jar:6.1.0-RC2]
at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.invokeHandlerMethod(RequestMappingHandlerAdapter.java:917) ~[spring-webmvc-6.1.0-RC2.jar:6.1.0-RC2]
at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.handleInternal(RequestMappingHandlerAdapter.java:829) ~[spring-webmvc-6.1.0-RC2.jar:6.1.0-RC2]
at org.springframework.web.servlet.mvc.method.AbstractHandlerMethodAdapter.handle(AbstractHandlerMethodAdapter.java:87) ~[spring-webmvc-6.1.0-RC2.jar:6.1.0-RC2]
at org.springframework.web.servlet.DispatcherServlet.doDispatch(DispatcherServlet.java:1089) ~[spring-webmvc-6.1.0-RC2.jar:6.1.0-RC2]
at org.springframework.web.servlet.DispatcherServlet.doService(DispatcherServlet.java:979) ~[spring-webmvc-6.1.0-RC2.jar:6.1.0-RC2]
at org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:1014) ~[spring-webmvc-6.1.0-RC2.jar:6.1.0-RC2]
at org.springframework.web.servlet.FrameworkServlet.doGet(FrameworkServlet.java:903) ~[spring-webmvc-6.1.0-RC2.jar:6.1.0-RC2]
at jakarta.servlet.http.HttpServlet.service(HttpServlet.java:564) ~[tomcat-embed-core-10.1.15.jar:6.0]
at org.springframework.web.servlet.FrameworkServlet.service(FrameworkServlet.java:885) ~[spring-webmvc-6.1.0-RC2.jar:6.1.0-RC2]
at jakarta.servlet.http.HttpServlet.service(HttpServlet.java:658) ~[tomcat-embed-core-10.1.15.jar:6.0]
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:205) ~[tomcat-embed-core-10.1.15.jar:10.1.15]
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:149) ~[tomcat-embed-core-10.1.15.jar:10.1.15]
at org.apache.tomcat.websocket.server.WsFilter.doFilter(WsFilter.java:51) ~[tomcat-embed-websocket-10.1.15.jar:10.1.15]
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:174) ~[tomcat-embed-core-10.1.15.jar:10.1.15]
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:149) ~[tomcat-embed-core-10.1.15.jar:10.1.15]
at org.springframework.web.filter.ServerHttpObservationFilter.doFilterInternal(ServerHttpObservationFilter.java:109) ~[spring-web-6.1.0-RC2.jar:6.1.0-RC2]
at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:116) ~[spring-web-6.1.0-RC2.jar:6.1.0-RC2]
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:174) ~[tomcat-embed-core-10.1.15.jar:10.1.15]
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:149) ~[tomcat-embed-core-10.1.15.jar:10.1.15]
at org.springframework.web.filter.CharacterEncodingFilter.doFilterInternal(CharacterEncodingFilter.java:201) ~[spring-web-6.1.0-RC2.jar:6.1.0-RC2]
at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:116) ~[spring-web-6.1.0-RC2.jar:6.1.0-RC2]
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:174) ~[tomcat-embed-core-10.1.15.jar:10.1.15]
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:149) ~[tomcat-embed-core-10.1.15.jar:10.1.15]
at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:167) ~[tomcat-embed-core-10.1.15.jar:10.1.15]
at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:90) ~[tomcat-embed-core-10.1.15.jar:10.1.15]
at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:482) ~[tomcat-embed-core-10.1.15.jar:10.1.15]
at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:115) ~[tomcat-embed-core-10.1.15.jar:10.1.15]
at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:93) ~[tomcat-embed-core-10.1.15.jar:10.1.15]
at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:74) ~[tomcat-embed-core-10.1.15.jar:10.1.15]
at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:340) ~[tomcat-embed-core-10.1.15.jar:10.1.15]
at org.apache.coyote.http11.Http11Processor.service(Http11Processor.java:391) ~[tomcat-embed-core-10.1.15.jar:10.1.15]
at org.apache.coyote.AbstractProcessorLight.process(AbstractProcessorLight.java:63) ~[tomcat-embed-core-10.1.15.jar:10.1.15]
at org.apache.coyote.AbstractProtocol$ConnectionHandler.process(AbstractProtocol.java:896) ~[tomcat-embed-core-10.1.15.jar:10.1.15]
at org.apache.tomcat.util.net.NioEndpoint$SocketProcessor.doRun(NioEndpoint.java:1744) ~[tomcat-embed-core-10.1.15.jar:10.1.15]
at org.apache.tomcat.util.net.SocketProcessorBase.run(SocketProcessorBase.java:52) ~[tomcat-embed-core-10.1.15.jar:10.1.15]
at org.apache.tomcat.util.threads.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1191) ~[tomcat-embed-core-10.1.15.jar:10.1.15]
at org.apache.tomcat.util.threads.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:659) ~[tomcat-embed-core-10.1.15.jar:10.1.15]
at org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:61) ~[tomcat-embed-core-10.1.15.jar:10.1.15]
at java.base/java.lang.Thread.run(Thread.java:1583) ~[na:na]
如果有人想查看 CustomErrorMessage 类:
public class CustomErrorMessage {
private Date timestamp;
private String message;
public CustomErrorMessage() {
}
public CustomErrorMessage(Date timestamp, String message) {
this.timestamp = timestamp;
this.message = message;
}
public Date getTimestamp() {
return timestamp;
}
public void setTimestamp(Date timestamp) {
this.timestamp = timestamp;
}
public String getMessage() {
return message;
}
public void setMessage(String message) {
this.message = message;
}
}
我还在处理程序中放置了一个断点,但它从未在应用程序中使用过。我是否必须添加其他内容才能调用它?
我还更改了注释中的注释,以防万一它会捕获错误,但没有任何变化。我是Spring Boot的初学者,所以我很快就用完了想法。
这真的很令人沮丧,因为我完全按照教程中显示的内容做了,但我的不起作用。Exception.class
@ExceptionHandler
NullPointerException.class
编辑
我做到了。似乎包含我的处理程序的包最初没有被 Spring 扫描,因此它无法使用我拥有的注释。在应用程序的主类中使用 @ComponentScan(“包的名称”)
注解,一切正常。
答:
0赞
Ahmed Nabil
11/3/2023
#1
我尝试过与您的环境相同的环境,并且有效。 这可能看起来很傻,但请尝试重新运行您的应用程序:)
评论
0赞
Ioannis Zisis
11/3/2023
哈哈,不是,但我尝试了很多次,仍然试图希望会有所改变
0赞
Ahmed Nabil
11/4/2023
我从字面上复制粘贴了您的代码,它工作:D
评论