@ExceptionHandler没有按预期工作

@ExceptionHandler not working as it was supposed to

提问人:Ioannis Zisis 提问时间:11/3/2023 最后编辑:Ioannis Zisis 更新时间:11/6/2023 访问量:75

问:

我正在观看有关 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@ExceptionHandlerNullPointerException.class

编辑

我做到了。似乎包含我的处理程序的包最初没有被 Spring 扫描,因此它无法使用我拥有的注释。在应用程序的主类中使用 @ComponentScan(“包的名称”) 注解,一切正常。

java spring-boot 异常处理程序

评论

0赞 Roman C 11/3/2023
你有教程的链接吗?
0赞 Ioannis Zisis 11/3/2023
@RomanC 当然,就在这里,udemy.com/course/......
0赞 Arpit 11/3/2023
尝试进行一些基本的清理,例如删除类文件、重新编译和重新运行。在我看来,代码没有错。
0赞 Roman C 11/3/2023
您还应该发布建筑物详细信息。
0赞 Ioannis Zisis 11/3/2023
@Arpit我做到了,但仍然没有任何效果。我还对 Maven 进行了全新安装,以防万一我没有做任何事情但仍然没有做任何事情。

答:

0赞 Ahmed Nabil 11/3/2023 #1

我尝试过与您的环境相同的环境,并且有效。 这可能看起来很傻,但请尝试重新运行您的应用程序:)

评论

0赞 Ioannis Zisis 11/3/2023
哈哈,不是,但我尝试了很多次,仍然试图希望会有所改变
0赞 Ahmed Nabil 11/4/2023
我从字面上复制粘贴了您的代码,它工作:D