Spring GetMapping访问/refer时Tomcat提示资源不可用问题求助
问题描述
使用Tomcat 10.1、Maven和Eclipse IDE开发Spring应用,运行后可正常访问index.jsp,但访问/refer路径时返回404错误:
The requested resource [/lab57/refer] is not available
源服务器未找到目标资源的当前表示或不愿披露其存在
已重装Tomcat,问题仍未解决。项目代码与结构如下:
[项目结构图片]
项目代码
HelloController.java
package ru.autoportal.lab; import org.springframework.stereotype.Controller; import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.RequestMapping; @Controller public class HelloController { @GetMapping("/refer") public String sayHello() { return "hello_world"; } }
DispatcherServleteInitializer.java
package ru.autoportal.lab.config; import org.springframework.web.servlet.support.AbstractAnnotationConfigDispatcherServletInitializer; public class DispatcherServleteInitializer extends AbstractAnnotationConfigDispatcherServletInitializer { @Override protected Class<?>[] getRootConfigClasses() { return null; } @Override protected Class<?>[] getServletConfigClasses() { return new Class[]{SpringConfig.class}; } @Override protected String[] getServletMappings() { return new String[]{"/"}; } }
SpringConfig.java
package ru.autoportal.lab.config; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.context.ApplicationContext; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.ComponentScan; import org.springframework.context.annotation.Configuration; import org.springframework.web.servlet.config.annotation.EnableWebMvc; import org.springframework.web.servlet.config.annotation.ViewResolverRegistry; import org.springframework.web.servlet.config.annotation.WebMvcConfigurer; import org.thymeleaf.spring5.SpringTemplateEngine; import org.thymeleaf.spring5.templateresolver.SpringResourceTemplateResolver; import org.thymeleaf.spring5.view.ThymeleafViewResolver; @Configuration @ComponentScan("ru.autoportal.lab") @EnableWebMvc public class SpringConfig implements WebMvcConfigurer { private final ApplicationContext applicationContext; @Autowired public SpringConfig(ApplicationContext applicationContext) { this.applicationContext = applicationContext; } @Bean public SpringResourceTemplateResolver templateResolver() { SpringResourceTemplateResolver templateResolver = new SpringResourceTemplateResolver(); templateResolver.setApplicationContext(applicationContext); templateResolver.setPrefix("/WEB-INF/views/"); templateResolver.setSuffix(".html"); return templateResolver; } @Bean public SpringTemplateEngine templateEngine() { SpringTemplateEngine templateEngine = new SpringTemplateEngine(); templateEngine.setTemplateResolver(templateResolver()); templateEngine.setEnableSpringELCompiler(true); return templateEngine; } @Override public void configureViewResolvers(ViewResolverRegistry registry) { ThymeleafViewResolver resolver = new ThymeleafViewResolver(); resolver.setTemplateEngine(templateEngine()); registry.viewResolver(resolver); } }
hello_world.html
<html xmlns:th="http://www.thymeleaf.org" lang="en"> <head> <meta charset="ISO-8859-1"> <title>My app</title> </head> <body> <p>Hello!</p> </body> </html>
pom.xml
<?xml version="1.0" encoding="UTF-8"?> <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>ru.portal.autos</groupId> <artifactId>lab57</artifactId> <version>0.0.1-SNAPSHOT</version> <packaging>war</packaging> <name>lab57 Maven Webapp</name> <!-- FIXME change it to the project's website --> <url>http://www.example.com</url> <properties> <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding> <maven.compiler.source>1.7</maven.compiler.source> <maven.compiler.target>1.7</maven.compiler.target> <spring.version>5.2.1.RELEASE</spring.version> </properties> <dependencies> <dependency> <groupId>junit</groupId> <artifactId>junit</artifactId> <version>4.11</version> <scope>test</scope> </dependency> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-core</artifactId> <version>${spring.version}</version> </dependency> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-context</artifactId> <version>${spring.version}</version> </dependency> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-web</artifactId> <version>${spring.version}</version> </dependency> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-webmvc</artifactId> <version>${spring.version}</version> </dependency> <dependency> <groupId>org.thymeleaf</groupId> <artifactId>thymeleaf-spring5</artifactId> <version>3.0.11.RELEASE</version> </dependency> <dependency> <groupId>javax.servlet</groupId> <artifactId>javax.servlet-api</artifactId> <version>4.0.1</version> <scope>provided</scope> </dependency> </dependencies> <build> <finalName>spring-mvc-app1</finalName> <pluginManagement><!-- lock down plugins versions to avoid using Maven defaults (may be moved to parent pom) --> <plugins> <plugin> <artifactId>maven-clean-plugin</artifactId> <version>3.1.0</version> </plugin> <!-- see http://maven.apache.org/ref/current/maven-core/default-bindings.html#Plugin_bindings_for_war_packaging --> <plugin> <artifactId>maven-resources-plugin</artifactId> <version>3.0.2</version> </plugin> <plugin> <artifactId>maven-compiler-plugin</artifactId> <version>3.8.0</version> </plugin> <plugin> <artifactId>maven-surefire-plugin</artifactId> <version>2.22.1</version> </plugin> <plugin> <artifactId>maven-war-plugin</artifactId> <version>3.2.2</version> </plugin> <plugin> <artifactId>maven-install-plugin</artifactId> <version>2.5.2</version> </plugin> <plugin> <artifactId>maven-deploy-plugin</artifactId> <version>2.8.2</version> </plugin> </plugins> </pluginManagement> </build> </project>
问题排查与解决
1. 初始化类名拼写错误(核心问题)
你的DispatcherServleteInitializer类名多了一个字母e,正确类名应为DispatcherServletInitializer。Spring MVC通过识别继承AbstractAnnotationConfigDispatcherServletInitializer的类来自动注册DispatcherServlet,类名拼写错误会导致Spring无法识别该类,DispatcherServlet未被初始化,所有@RequestMapping请求都无法被处理,直接返回404。
解决: 将类名修改为DispatcherServletInitializer,重新编译部署。
2. Tomcat与Spring版本不兼容
Spring 5.x依赖的是javax.servlet包,而Tomcat 10.1使用的是Jakarta EE 9+规范,包名已改为jakarta.servlet,两者不兼容。
解决:
- 方案一:降级Tomcat到9.x(支持Servlet API 4.x,与Spring 5.x兼容)
- 方案二:升级Spring到6.x(支持Jakarta EE 9+,需同步修改pom.xml中依赖的包名,将
javax.servlet改为jakarta.servlet)
3. 上下文路径不匹配
pom.xml中<finalName>设置为spring-mvc-app1,但错误信息中显示的上下文路径是/lab57,说明部署时的上下文路径与预期不符。
解决:
- 检查Eclipse中Tomcat部署配置,确认项目的上下文路径是否为
/lab57或/spring-mvc-app1,访问时使用正确的路径(如http://localhost:8080/spring-mvc-app1/refer) - 或修改pom.xml的
<finalName>为lab57,保持上下文路径一致
4. 视图文件路径验证
SpringConfig中配置的视图前缀为/WEB-INF/views/,需确保hello_world.html确实放在WEB-INF/views/目录下,路径错误会导致视图无法找到。
解决: 检查项目结构,将hello_world.html移动到WEB-INF/views/目录中。
内容的提问来源于stack exchange,提问作者Behemoth

