Spring Boot - 处理NoHandlerFoundException

Mat*_*llo 0 java spring spring-mvc spring-boot

阅读Spring参考指南,了解如何处理NoHandlerFoundException,并发现Spring默认设置throwExceptionIfNoHandlerFoundfalse.

知道了,我认为将此参数设置为是个好主意true.

我正在使用Spring Boot.

这样做了:

MyConfig.java

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.context.ConfigurableApplicationContext;
import org.springframework.web.servlet.DispatcherServlet;

@SpringBootApplication
public class MyConfig {

    public static void main(String[] args) {
        ConfigurableApplicationContext context = SpringApplication.run(MyConfig.class, args);
        context.getBean(DispatcherServlet.class).setThrowExceptionIfNoHandlerFound(true);

        // ...
    }
}
Run Code Online (Sandbox Code Playgroud)

好吧,现在throwExceptionIfNoHandlerFound是平等的true.但是,这没有按预期发挥作用.在DispatcherServlet持续不扔的NoHandlerFoundException.这样,我无法处理它.

CustomExceptionHandler.java (这没用)

import org.springframework.http.HttpHeaders;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.ControllerAdvice;
import org.springframework.web.context.request.WebRequest;
import org.springframework.web.servlet.NoHandlerFoundException;
import org.springframework.web.servlet.mvc.method.annotation.ResponseEntityExceptionHandler;

@ControllerAdvice
public class CustomExceptionHandler extends ResponseEntityExceptionHandler {

    @Override
    protected ResponseEntity <Object> handleNoHandlerFoundException(NoHandlerFoundException ex, HttpHeaders headers, HttpStatus status, WebRequest request) {
        // do my own handle ...

        // then, return ...
    }

}
Run Code Online (Sandbox Code Playgroud)

经过一番搜索,发现添加@EnableWebMvc应该有效.然后,我确实将这个注释添加到我的CustomExceptionHandler

CustomExceptionHandler.java (这确实有效)

import org.springframework.http.HttpHeaders;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.ControllerAdvice;
import org.springframework.web.context.request.WebRequest;
import org.springframework.web.servlet.NoHandlerFoundException;
import org.springframework.web.servlet.config.annotation.EnableWebMvc;
import org.springframework.web.servlet.mvc.method.annotation.ResponseEntityExceptionHandler;

@EnableWebMvc
@ControllerAdvice
public class CustomExceptionHandler extends ResponseEntityExceptionHandler {

    @Override
    protected ResponseEntity <Object> handleNoHandlerFoundException(NoHandlerFoundException ex, HttpHeaders headers, HttpStatus status, WebRequest request) {
        // do my own handle ...

        // then, return ...
    }

}
Run Code Online (Sandbox Code Playgroud)

这样,手柄就可以了.但是,我正在使用Spring Boot.Spring Boot文档建议,如果我插入@EnableWebMvc,我将丢失一些Spring Boot MVC自动配置功能,因为我将完全控制Spring MVC.(见这里).

"如果你想完全控制Spring MVC,你可以添加自己的@Configuration注释@EnableWebMvc."

我会失去Spring MVC自动配置吗?我的意思是@EnableWebMvc,在我的情况下,它不在@Configuration课堂上.

我的问题是基于这样一个事实:我不确定上面的代码是如何工作的,我想知道是否有另一种方法可以做到这一点而不会丢失Spring MVC自动配置.有人能解释一下吗

Phi*_*ebb 14

Spring Boot自动配置会自动添加一个ResourceHttpRequestHandler来处理服务静态资源.默认情况下,此处理程序是映射的,/**并且是处理程序链中的最后一项.

这意味着DispatcherServlet不会抛出一个NoHandlerFoundException因为它找到了资源处理程序.资源处理程序处理请求并调用response.sendError(HttpServletResponse.SC_NOT_FOUND)以返回404.

如果您不想要此行为,可以将以下内容添加到application.properties:

spring.mvc.throw-exception-if-no-handler-found=true
spring.resources.add-mappings=false
Run Code Online (Sandbox Code Playgroud)

将配置调度程序servlet以抛出异常,并告诉Spring Boot不要注册资源处理程序.

在你走太远之前,你可能想看一下参考文档的这一部分,看看以不同的方式处理这些错误是不是更好.从你的问题中你并没有完全清楚你在错误处理程序中实际尝试做什么,但如果它只是处理404s那么可能有更好的方法.

  • 在 Spring 的新版本中,`spring.resources.add-mappings` 被替换为 `spring.web.resources.add-mappings`。 (9认同)