在 Tomcat 10.x 上部署 Spring 5.x
Deploying Spring 5.x on Tomcat 10.x
TL;DR:我有一个 Spring MVC Hello, World! 应用程序可在 Tomcat 9 上运行。相同的应用程序在 Tomcat 10 为 Web 请求映射提供 404 错误。
问题
将 Spring MVC 5 Hello, World! 应用程序部署到 Tomcat 10 时,该应用程序会针对 Web 请求映射给出 404 错误。同一个 Hello, World! 应用程序在 Tomcat 9 上运行。它在 Tomcat 上显示 Hello, World! 消息9.
如我所料
我希望应用程序在 Tomcat10 上显示 Hello, World! 消息。
环境
- MS Windows 10
- Tomcat 10.0.2
- SpringMVC 5.3.3
我进行的研究
我在 Spring 参考手册的 Web Servlet 部分进行了研究。我还在线测试了 Spring MVC 教程。这些教程适用于 Tomcat 9。但是,相同的教程在 Tomcat 10 上失败了。我还在 Tomcat 10 上执行了 Google 搜索。我看到了对 Jakarta 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 MVC 5 在 Tomcat 10 上没有 运行 因为包从 javax.*
重命名为 jakarta.*
.
经过进一步研究,我找到了问题的答案。 Spring MVC 5 不 在 Tomcat 10 上工作。这是因为 Tomcat 10 基于 Jakarta EE 9,其中 API 的包名称已更改从 javax.*
到 jakarta.*
.
Tomcat 10 人在 download webpage 上提到了这个:
Users of Tomcat 10 onwards should be aware that, as a result of the
move from Java EE to Jakarta EE as part of the transfer of Java EE to
the Eclipse Foundation, the primary package for all implemented APIs
has changed from javax.*
to jakarta.*
. This will almost certainly
require code changes to enable applications to migrate from Tomcat 9
and earlier to Tomcat 10 and later.
对于 Spring MVC 5,Spring MVC DispatcherServlet 依赖于 javax.servlet.*
包命名空间。这是使用 Java EE 8 javax
包命名。由于 Tomcat 10 基于 Jakarta EE 9,因此不支持 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 框架升级到 Jakarta EE 9。
TL;DR:我有一个 Spring MVC Hello, World! 应用程序可在 Tomcat 9 上运行。相同的应用程序在 Tomcat 10 为 Web 请求映射提供 404 错误。
问题
将 Spring MVC 5 Hello, World! 应用程序部署到 Tomcat 10 时,该应用程序会针对 Web 请求映射给出 404 错误。同一个 Hello, World! 应用程序在 Tomcat 9 上运行。它在 Tomcat 上显示 Hello, World! 消息9.
如我所料
我希望应用程序在 Tomcat10 上显示 Hello, World! 消息。
环境
- MS Windows 10
- Tomcat 10.0.2
- SpringMVC 5.3.3
我进行的研究
我在 Spring 参考手册的 Web Servlet 部分进行了研究。我还在线测试了 Spring MVC 教程。这些教程适用于 Tomcat 9。但是,相同的教程在 Tomcat 10 上失败了。我还在 Tomcat 10 上执行了 Google 搜索。我看到了对 Jakarta 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 MVC 5 在 Tomcat 10 上没有 运行 因为包从 javax.*
重命名为 jakarta.*
.
经过进一步研究,我找到了问题的答案。 Spring MVC 5 不 在 Tomcat 10 上工作。这是因为 Tomcat 10 基于 Jakarta EE 9,其中 API 的包名称已更改从 javax.*
到 jakarta.*
.
Tomcat 10 人在 download webpage 上提到了这个:
Users of Tomcat 10 onwards should be aware that, as a result of the move from Java EE to Jakarta EE as part of the transfer of Java EE to the Eclipse Foundation, the primary package for all implemented APIs has changed from
javax.*
tojakarta.*
. This will almost certainly require code changes to enable applications to migrate from Tomcat 9 and earlier to Tomcat 10 and later.
对于 Spring MVC 5,Spring MVC DispatcherServlet 依赖于 javax.servlet.*
包命名空间。这是使用 Java EE 8 javax
包命名。由于 Tomcat 10 基于 Jakarta EE 9,因此不支持 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 框架升级到 Jakarta EE 9。