如何在 Spring Boot 应用程序中配置 DispatcherServlet?

Posted

技术标签:

【中文标题】如何在 Spring Boot 应用程序中配置 DispatcherServlet?【英文标题】:How to configure DispatcherServlet in a Spring Boot application? 【发布时间】:2016-05-09 08:45:43 【问题描述】:

在传统的 Spring Web 应用中,是否可以覆盖 AbstractDispatcherServletInitializer.createDispatcherServlet,调用 super.createDispatcherServlet,然后在返回的实例上设置以下 init 参数?

setThreadContextInheritable
setThrowExceptionIfNoHandlerFound

如何在 Spring Boot 应用中实现这一点?

【问题讨论】:

尝试添加一个 DispatcherServlet 类型的 @Bean 并直接设置您需要的任何属性。 @Shaheer 这样做需要我自己完全配置DispatcherServlet。正如我在问题中所说,传统方法使用super.createDispatcherServlet 调用让超类完成繁重的工作。这应该是比重新发明***更好的方法。 最后一个只是application.properties spring.mvc.throwExceptionIfNoHandlerFound=true 中的一个属性(默认是false 顺便说一句!)。对于另一个,创建BeanPostProcessor 可能是最简单的,因为您可以手动配置DispatcherServlet 或使用属性。另一方面,您只需要一个DispatcherServlet,Spring Boot 仍然会处理其他所有事情。 @M.Deinum 我会在尝试BeanPostProcessor 方法后立即回复。 【参考方案1】:

您可以定义自己的配置并实现这一点,如下所示:

@Configuration
public class ServletConfig 

@Bean
public DispatcherServlet dispatcherServlet() 
    DispatcherServlet dispatcherServlet = new DispatcherServlet();
    dispatcherServlet.setThreadContextInheritable(true);
    dispatcherServlet.setThrowExceptionIfNoHandlerFound(true);
    return dispatcherServlet;


@Bean
public ServletRegistrationBean dispatcherServletRegistration() 

    ServletRegistrationBean registration = new ServletRegistrationBean(dispatcherServlet());
    registration.setLoadOnStartup(0);
    registration.setName(DispatcherServletAutoConfiguration.DEFAULT_DISPATCHER_SERVLET_REGISTRATION_BEAN_NAME);

    return registration;

【讨论】:

你读过我的评论吗,从上到下第二个?【参考方案2】:

对于任何试图解决这个问题的人,我们都是这样解决的:

@Configuration
public class ServletConfig 

  @Autowired
  RequestContextFilter filter;

  @Autowired
  DispatcherServlet servlet;

  @PostConstruct
  public void init() 
    // Normal mode
    filter.setThreadContextInheritable(true);

    // Debug mode
    servlet.setThreadContextInheritable(true);

    servlet.setThrowExceptionIfNoHandlerFound(true);
  

由于某种原因,在非调试模式下运行我们的 Spring Boot 应用程序时,Spring 的 RequestContextFilter 覆盖了 DispatcherServlet ThreadContextInheritable 属性。在调试模式下设置 servlet 就足够了。

【讨论】:

如果您说的是您所展示的内容仅在调试模式下有效,那显然不是解决方案。 debug 模式用于调试,在 Prod 中没有人在 debug 模式下运行他们的应用程序 @AbhijitSarkar 这不是我想说的,如果它还没有准备好生产,我显然不会发布它。我的意思是,出于某种原因,Spring boot 在调试模式下以不同的方式自动配置应用程序。在调试模式下DispatcherServlet bean 优先于RequestContextFilter,因此设置 servlet 的属性足以使调试模式工作。以“生产模式”启动应用程序的优先级是相反的。我们在代码中所做的是设置它们,以便无论应用程序运行在何种模式下它都可以工作。 这听起来像是一个错误,你应该在他们的 GitHub 上报告它。

以上是关于如何在 Spring Boot 应用程序中配置 DispatcherServlet?的主要内容,如果未能解决你的问题,请参考以下文章

如何在 Spring Boot + Spring Security 应用程序中配置 CORS?

Spring Boot实战 Spring常用配置

如何在 Spring Boot 应用程序中配置 DispatcherServlet?

具有嵌入式 init.d 脚本的 Spring Boot 应用程序未在重新启动时启动

spring boot d多层级mapper

spring boot 在 application.properties 中使用 spring.profile.default 时未加载默认配置文件