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

2022-02-19 00:00:00 spring java tomcat

TL;DR:我有一个Spring MVCHello, World!应用程序可以在Tomcat 9上运行。Tomcat 10上的同一应用程序在Web请求映射方面会出现404错误。

问题

将Spring MVC 5Hello,World!应用程序部署到Tomcat 10时,该应用程序针对Web请求映射给出404错误。相同的Hello,World!应用程序适用于Tomcat 9。它在Tomcat 9上显示Hello,World!消息。

我所期望的

我希望应用程序在Tomcat 10上显示Hello,World!消息。

环境

  • MS Windows 10
  • Tomcat 10.0.2
  • Spring MVC 5.3.3

我进行的研究

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

如何复制

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

文件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>

文件ProjectInitializer.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;
    }
}

文件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;
    }

}

文件TutorialController.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";
    }
}

文件home.jsp

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

此项目在Tomcat 9上运行正常。它显示Hello,World!消息。但是,当我在Tomcat 10上运行时,收到404错误消息。


解决方案

TL;DR:Spring MVC5无法在Tomcat10上运行,因为包从javax.*重命名为jakarta.*

经过进一步研究,我终于找到了问题的答案。Spring MVC 5不支持在Tomcat 10上运行,这是因为Tomcat 10基于Jakarta EE10,其中API的包名已从javax.*更改为jakarta.*

Tomcat 10在download webpage上提到了这一点:

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

对于Spring MVC 5,Spring MVCDispatcherServlet依赖于javax.servlet.*包命名空间。这是使用JavaEE8javax包命名。由于Tomcat 10基于Jakarta EE9,因此不支持javax命名包。这就解释了为什么Spring-MVC-5不能在Tomcat-10上运行。

与Spring框架相关的GitHub问题:

Spring core 5 is not starting on Tomcat 10

Support for Jakarta EE 9 (annotations and interfaces in jakarta.* namespace)

就我而言,我不会迁移到Tomcat 10,而是会一直使用Tomcat 9,直到Spring框架升级到雅加达EE 9为止。

相关文章