在 Tomcat 10.x 上部署 Spring 5.x

2022-09-02 03:30:55

TL;DR:我有一个适用于Tomcat 9的Spring MVC Hello, World!应用程序。Tomcat 10 上的同一应用程序为 Web 请求映射提供了 404 错误。

问题

将 Spring MVC 5 Hello, World! 应用程序部署到 Tomcat 10 时,该应用程序会为 Web 请求映射提供 404 错误。同样的 Hello, World! 应用程序适用于 Tomcat 9。它在Tomcat 9上显示“你好,世界!”消息。

我的期望

我预计应用程序会在 Tomcat 10 上显示 Hello, World! 消息。

环境

  • 微软视窗 10
  • 雄猫 10.0.2
  • 弹簧 MVC 5.3.3

我进行的研究

我在春季参考手册中进行了研究,关于Web Servlet的部分。我还在线测试了Spring MVC教程。这些教程适用于Tomcat 9。但是,相同的教程在Tomcat 10上失败了。我还在Tomcat 10上进行了谷歌搜索。我看到了对Jakarta EE的引用,但我不确定这是否是问题的根源。Java EE 8 和 Jakarta EE 8 是向后兼容的。

如何复制

我创建了一个非常基本的Hello,World!项目来测试它。以下是我用于该项目的代码。

File pom.xml

<project xmlns="http://maven.apache.org/POM/4.0.0"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">

    <modelVersion>4.0.0</modelVersion>
    <groupId>com.example.spring</groupId>
    <artifactId>example-spring</artifactId>
    <version>1.0</version>
    <packaging>war</packaging>

    <properties>
        <maven.compiler.target>11</maven.compiler.target>
        <maven.compiler.source>11</maven.compiler.source>
    </properties>

    <dependencies>
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-webmvc</artifactId>
            <version>5.3.3</version>
        </dependency>

        <dependency>
            <groupId>javax.servlet</groupId>
            <artifactId>javax.servlet-api</artifactId>
            <version>4.0.0</version>
        </dependency>
    </dependencies>

    <build>
        <plugins>
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-war-plugin</artifactId>
                <version>3.3.1</version>
            </plugin>
        </plugins>
    </build>
</project>

文件项目初始化程序.java

package com.example;

import org.springframework.web.servlet.support.AbstractAnnotationConfigDispatcherServletInitializer;

public class ProjectInitializer extends AbstractAnnotationConfigDispatcherServletInitializer {

    @Override
    protected Class<?>[] getServletConfigClasses() {
        return new Class[] { PureJavaConfig.class };
    }

    @Override
    protected String[] getServletMappings() {
        return new String[] { "/" };
    }

    @Override
    protected Class<?>[] getRootConfigClasses() {
        return null;
    }
}

File PureJavaConfig.java

package com.example;

import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.ViewResolver;
import org.springframework.web.servlet.config.annotation.EnableWebMvc;
import org.springframework.web.servlet.view.InternalResourceViewResolver;

@Configuration
@EnableWebMvc
@ComponentScan("com.example")
public class PureJavaConfig {

    @Bean
    public ViewResolver viewResolver() {
        InternalResourceViewResolver resolver = new InternalResourceViewResolver();
        resolver.setSuffix(".jsp");
        resolver.setPrefix("/WEB-INF/jsp/");
        return resolver;
    }

}

文件教程控制器.java

package com.example;

import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.GetMapping;

@Controller
public class TutorialController {

    @GetMapping("/")
    public String home() {
        return "home";
    }
}

文件主页.jsp

<html>
    <body>Hello, World! of Spring! <%= java.time.LocalDateTime.now() %></body>
</html>

这个项目在Tomcat 9上运行良好。它显示“你好,世界!”消息。但是,当我在Tomcat 10上运行时,我收到404错误消息。


答案 1

TL;DR:Spring MVC 5 无法在 Tomcat 10 上运行,因为该软件包从 javax.* 重命名为 jakarta.*

经过进一步的研究,我能够找到我问题的答案。Spring MVC 5在Tomcat 10上不起作用。这是因为 Tomcat 10 基于 Jakarta EE 9,其中 API 的包名称已从 更改为 。javax.*jakarta.*

Tomcat 10在下载网页上提到了这一点:

Tomcat 10 以后的用户应该知道,作为 Java EE 转移到 Eclipse 基金会的一部分,由于从 Java EE 迁移到 Jakarta EE,所有已实现的 API 的主包都已从 更改为 。这几乎肯定需要更改代码,以使应用程序能够从Tomcat 9及更早版本迁移到Tomcat 10及更高版本。javax.*jakarta.*

对于Spring MVC 5,Spring MVC DispatcherServlet依赖于包命名空间。这是使用 Java EE 8 包命名。由于Tomcat 10基于Jakarta EE 9,因此不支持用于命名的软件包。这就解释了为什么Spring MVC 5在Tomcat 10上不起作用。javax.servlet.*javaxjavax

关于这一点,有针对Spring框架的GitHub问题:

Spring Core 5 没有在 Tomcat 10 上启动

支持 Jakarta EE 9(jakarta.* 命名空间中的注释和接口)

就我而言,我不会迁移到Tomcat 10,而是会留在Tomcat 9上,直到Spring框架升级到Jakarta EE 9。


答案 2

推荐