You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

SpringBoot 3项目控制器返回404错误,寻求排查帮助

Spring Boot 3 控制器返回404问题排查与解决

问题概述

使用IntelliJ内置向导或spring.io创建的Spring Boot 3.3.5项目(仅含Spring Web依赖),打包为WAR部署到Tomcat 9.4.1后,访问控制器接口返回404。Java版本为17,旧的Spring Boot 2.x项目可正常运行,已尝试修改server.servlet.context-path为/te或空值,均无效。

项目核心配置与代码

POM依赖

<dependencies>
    <!-- Spring Boot Web Starter -->
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-web</artifactId>
        <version>3.3.5</version>
    </dependency>

    <!-- Spring Boot Logging -->
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-logging</artifactId>
    </dependency>

    <!-- Spring Boot Actuator -->
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-actuator</artifactId>
    </dependency>
</dependencies>

POM父依赖

<parent>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-parent</artifactId>
    <version>3.3.5</version> 
    <relativePath/> 
</parent>       

application.properties

spring.application.name=te
server.servlet.context-path=/te  # 已尝试设为空值
server.port=8080

启动类TeApplication

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;

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

Servlet初始化类

import org.springframework.boot.builder.SpringApplicationBuilder;
import org.springframework.boot.web.servlet.support.SpringBootServletInitializer;

public class ServletInitializer extends SpringBootServletInitializer {

    @Override
    protected SpringApplicationBuilder configure(SpringApplicationBuilder application) {
        return application.sources(TeApplication.class);
    }

}

控制器类AboutController

import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

@RestController
@RequestMapping("/te")
public class AboutController
{
    private static final Logger log = LogManager.getLogger(AboutController.class);

    @GetMapping(value = "/about")
    public String aboutMessage()
    {
        return "Hello from About!";
    }
}

问题排查与解决方案

1. 路径匹配错误

当前配置下,实际有效访问路径应为localhost:8080/te/te/about,原因是:

  • server.servlet.context-path=/te 是应用全局上下文路径
  • 控制器的@RequestMapping("/te")是控制器级别的路径前缀
  • 方法的@GetMapping("/about")是接口具体路径

若要实现localhost:8080/te/about的访问,需修改控制器注解:

@RestController
// 删除或注释@RequestMapping("/te")
public class AboutController {
    @GetMapping(value = "/about")
    public String aboutMessage() {
        return "Hello from About!";
    }
}

2. Tomcat版本不兼容(核心问题)

Spring Boot 3.x基于Jakarta EE 9+规范,而Tomcat 9.x仍使用Java EE 8规范,两者API包名从javax.*改为jakarta.*,直接部署会导致Spring容器无法正确初始化控制器。

解决方法:

  • 升级Tomcat到10.1.x及以上版本(推荐10.1.18+,适配Spring Boot 3.3.5)
  • 若必须使用Tomcat 9,需添加Jakarta兼容桥接依赖,但不推荐,优先升级Tomcat版本

3. 组件扫描验证

虽然启动类位于控制器上级包,可显式指定扫描包确保控制器被加载:

@SpringBootApplication(scanBasePackages = "你的项目根包路径") // 替换为实际包名,如com.example.te
public class TeApplication {
    // ...
}

4. 日志验证控制器加载状态

查看项目启动日志,搜索AboutController或Mapping GET关键字:

  • 若未找到相关日志,说明控制器未被Spring容器扫描,需检查:
    • 包结构是否正确,启动类是否在控制器的父包或同级包
    • 控制器类是否被正确编译到WAR包的target/classes目录中

内容的提问来源于stack exchange,提问作者Morkus

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.16 09:05:55