【问题标题】:Servlet context isn't set only when building a WARServlet 上下文不仅在构建 WAR 时设置
【发布时间】:2021-08-19 07:49:41
【问题描述】:

我们正在从 Spring WebInitializer 迁移到 Spring boot 2.5.0 SpringBootServletInitializer

我们需要为我们的 Servlet 调度器添加一个上下文路径,代码如下:

@SpringBootApplication(exclude = { JmsAutoConfiguration.class, ActiveMQAutoConfiguration.class,
            SecurityAutoConfiguration.class, ManagementWebSecurityAutoConfiguration.class })
    public class WebServerConfig extends SpringBootServletInitializer implements ApplicationContextAware {
    @Bean
   public WebServerFactoryCustomizer<ConfigurableServletWebServerFactory> webServerFactoryCustomizer() {
       return factory -> {
           factory.setRegisterDefaultServlet(true);
           factory.setContextPath("/servlet");
       };
   }
}

在运行 Maven WAR 常规 Tomcat 8.5 时,未设置 Servlet 上下文,记录:

o.a.c.c.C.[Catalina].[localhost].[/]     : Initializing Spring DispatcherServlet 'dispatcherServlet'

普通主线

public static void main(String[] args) {
    SpringApplication.run(WebServerConfig.class, args);
}

当运行嵌入式 Tomcat 代码按预期工作时:

o.a.c.c.C.[.[localhost].[/servlet]       : Initializing Spring DispatcherServlet 'dispatcherServlet'

Maven pom:

<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-web</artifactId>
    <version>${springframework.boot-version}</version>
</dependency>
<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-tomcat</artifactId>
    <version>${springframework.boot-version}</version>
    <scope>provided</scope>
</dependency>

我也有configure方法:

@Override
protected SpringApplicationBuilder configure(
  SpringApplicationBuilder builder) {
    return builder.sources(WebServerConfig.class);
}

在构建 WAR 时是否缺少启用 Servlet 上下文的代码/属性?

我发现较早的 questionquestion2 没有真正的答案,除非使用不同的战争名称。

【问题讨论】:

  • 您需要覆盖/实现SpringBootServletInitializerconfigure 方法,否则它不会做任何事情。
  • @M.Deinum 我还在我的问题中添加了configure 方法
  • 从那些 sn-ps 无法分辨,而且您的配置看起来也很奇怪。另外取决于您的 Spring Boot 版本,Tomcat 8.5 可能太低,您需要 Tomcat 9。
  • 当然WebServerFactoryCustomizer 在部署为war 文件时不适用。那是为了控制嵌入式tomcat的创建,spring Boot无法控制外部tomcat。所以不会设置上下文路径(与 servletcontext 不同(让我失望))。
  • @M.Deinum 与 tomcat 9 相同的结果,那么相当于 Spring ServletRegistration.Dynamic dispatcher = servletContext.addServlet("Mydispatcher", ds); dispatcher.addMapping("/servlet/*");

标签: java spring spring-boot maven


【解决方案1】:

使用以下应用程序属性设置 Spring Boot 应用程序的上下文路径。 如果您使用的是 yaml 配置。

server:
   servlet:
     context-path: /servlet

如果您使用的是 application.properties

server.servlet.context-path = /servlet

【讨论】:

  • 它只影响嵌入式 tomcat 而不是部署战争时
  • 您的 war 文件名将是第一个上下文路径示例 application.war,然后您的上下文路径将是 host:port/applicaiton/contextpathInProperty/controllermappingPath。将战争名称作为根上下文路径
  • 我使用root所以我的文件名是ROOT.war
  • 你想在war中还是在根路径之后改变根上下文?
  • 听起来一样,我正在构建 Spring Boot 应用程序并部署到战争,我需要 /servlet 作为上下文路径,尽管我的战争是 ROOT.war
【解决方案2】:

我们通过在SpringApplicationBuilder 中添加属性解决了这个问题:

@Override
protected SpringApplicationBuilder configure(SpringApplicationBuilder builder) {
    Properties bootProperties = new Properties();
    bootProperties.setProperty("spring.mvc.servlet.path", "/servlet");
    return builder.sources(WebServerConfig.class).properties(bootProperties);
}

【讨论】:

    猜你喜欢
    • 2011-02-05
    • 2023-03-07
    • 2016-01-12
    • 2016-10-29
    • 1970-01-01
    • 1970-01-01
    • 2019-03-07
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多