Spring Boot - 处理 NoHandlerFoundException [英] Spring Boot - Handling NoHandlerFoundException

查看:28
本文介绍了Spring Boot - 处理 NoHandlerFoundException的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

阅读Spring关于如何处理 NoHandlerFoundException 的参考指南,发现 Spring 默认将 throwExceptionIfNoHandlerFound 设置为 false.

Read the Spring Reference Guide on how to handle NoHandlerFoundException and found that Spring sets, by default, throwExceptionIfNoHandlerFound to false.

知道这一点后,我认为将此参数设置为 true 是个好主意.

Knowing that, I thought it was a good idea to set this parameter to true.

我正在使用 Spring Boot.

I'm using 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);

        // ...
    }
}

好的,现在 throwExceptionIfNoHandlerFound 等于 true.然而,这并没有像预期的那样奏效.DispatcherServlet 继续不抛出 NoHandlerFoundException.这样一来,我就受不了了.

Alright, now throwExceptionIfNoHandlerFound is equals true. However, that didn't worked as expected. The DispatcherServlet continued not throwing the NoHandlerFoundException. This way, I was unable to handle it.

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 ...
    }

}

经过一番搜索,发现添加@EnableWebMvc 应该可以.然后,我确实将此注释添加到了我的 CustomExceptionHandler

After a bit of search, found that adding @EnableWebMvc should work. Then, I did add this annotation to my 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 ...
    }

}

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

This way, the handle works. However, I'm using Spring Boot. The Spring Boot docs suggests that if I insert @EnableWebMvc, I would lose some Spring Boot MVC Auto-configuration features, since I would take complete controll of Spring MVC. (See here).

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

"If you want to take complete control of Spring MVC, you can add your own @Configuration annotated with @EnableWebMvc."

我会失去 Spring MVC 自动配置吗?我的意思是,@EnableWebMvc,就我而言,它不在 @Configuration 类中.

Would I lose Spring MVC Auto-configuration? I mean, the @EnableWebMvc, in my case, it's not in a @Configuration class.

我的问题是基于这样一个事实,即我不确定上面的代码是如何工作的,我想知道是否有另一种方法可以在不丢失 Spring MVC 自动配置的情况下执行此操作.有人能解释一下吗?

My question is based on the fact that I'm not sure how this code above works, and I want to know if there's another way of doing this without losing the Spring MVC Auto-configuration. Could someone explain?

推荐答案

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

Spring Boot auto-configuration will automatically add a ResourceHttpRequestHandler to deal with serving static resource. By default this handler is mapped against /** and is the last item in the handler chain.

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

What this means is the DispatcherServlet won't throw a NoHandlerFoundException because it found the resource handler. The resource handler processes the request and calls response.sendError(HttpServletResponse.SC_NOT_FOUND) to return a 404.

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

If you don't want this behavior, you can add the following to your application.properties:

spring.mvc.throw-exception-if-no-handler-found=true
spring.resources.add-mappings=false

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

The will configure the dispatcher servlet to throw the exception and also tell Spring Boot not to register the resource handler.

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

Before you go too far down that route, you might want to look at this section of the reference docs to see if it wouldn't be better to handle those errors in a different way. It's not totally clear from your question what you're actually trying to do in your error handler, but if it's just dealing with 404s then there's probably a better way.

这篇关于Spring Boot - 处理 NoHandlerFoundException的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆