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

Spring Boot中@RestController除主类外调用返回404错误问题求助

问题描述

我的项目结构如下:
项目结构示意图

我通过Postman调用ApartmentController中定义的Get接口时,返回404错误,接口定义代码如下:

@RestController
@RequestMapping("/api/apartment")
class ApartmentController(private val apartmentService: ApartmentService) {
  @GetMapping
  fun getAllApartments(apartment: Apartment): List<Apartment> {
      return apartmentService.getAllApartments()
  }

  @PostMapping
  fun createApartment(apartment: Apartment): Apartment {
      return apartmentService.createApartment(apartment)
  }
}

但我将相同逻辑的接口写在启动类LeaderRealEstateApiApplication所在文件中时,调用返回200正常响应,代码如下:

@SpringBootApplication()
class LeaderRealEstateApiApplication

fun main(args: Array<String>) {
  runApplication<LeaderRealEstateApiApplication>(*args)
}

@RestController
@RequestMapping("/api/apartments")
class TestResource(private val apartmentService: ApartmentService) {
  @GetMapping
  fun test(): List<Apartment> {
      return apartmentService.getAllApartments()
  }
}

我已经尝试在@SpringBootApplication注解中添加scanBasePackages配置:@SpringBootApplication(scanBasePackages = ["com.leaderrealestate"]) ,但问题依然存在,请问是什么原因导致的?该如何解决?


问题原因及解决方案

核心原因

404报错说明ApartmentController没有被Spring容器成功注册为Bean,对应的接口路径没有被系统映射,本质是类扫描/Bean注册失败导致,常见原因如下:

  1. Kotlin类默认final导致代理失败
    如果项目中没有引入kotlin-spring(spring-all-open)插件,Kotlin定义的类默认是final类型,Spring无法为@RestController这类注解的类生成代理对象,就会导致Bean注册失败。和启动类写在同一个文件的TestResource能正常工作,是因为Spring Boot对启动类同文件的类有特殊的扫描和处理逻辑。
  2. 包扫描路径配置不匹配
    即使配置了scanBasePackages = ["com.leaderrealestate"],如果ApartmentController没有放在com.leaderrealestate包或者它的子包下,依然无法被扫描到,比如把Controller放在com.other这类和配置路径无关的包下就会失效。
  3. 注解导包错误
    @RestController、@RequestMapping等注解导错了包,比如导入了Jersey或者其他框架的同名注解,Spring无法识别。
  4. 接口路径拼写错误
    ApartmentController的映射路径是/api/apartment(单数),而测试用的TestResource路径是/api/apartments(复数),如果调用时误把带s的路径用在前者上也会返回404。

解决步骤

  • 优先检查kotlin-spring插件配置:
    如果你用Gradle,在build.gradle.kts中添加以下配置:
    plugins {
        id("org.springframework.boot") version "你的Spring Boot版本"
        id("io.spring.dependency-management") version "对应依赖管理版本"
        kotlin("jvm") version "你的Kotlin版本"
        kotlin("plugin.spring") version "你的Kotlin版本" // 核心是添加这个插件
    }
    
    如果你用Maven,在pom.xml中添加:
    <build>
        <plugins>
            <plugin>
                <groupId>org.jetbrains.kotlin</groupId>
                <artifactId>kotlin-maven-plugin</artifactId>
                <version>${kotlin.version}</version>
                <executions>
                    <execution>
                        <id>compile</id>
                        <goals>
                            <goal>compile</goal>
                        </goals>
                        <configuration>
                            <args>
                                <arg>-Xjsr305=strict</arg>
                            </args>
                            <compilerPlugins>
                                <plugin>spring</plugin> <!-- 开启spring插件 -->
                            </compilerPlugins>
                        </configuration>
                    </execution>
                </executions>
                <dependencies>
                    <dependency>
                        <groupId>org.jetbrains.kotlin</groupId>
                        <artifactId>kotlin-maven-allopen</artifactId>
                        <version>${kotlin.version}</version>
                    </dependency>
                </dependencies>
            </plugin>
        </plugins>
    </build>
    
    不想加插件的话也可以手动给ApartmentController类和方法加open关键字:
    @RestController
    @RequestMapping("/api/apartment")
    open class ApartmentController(private val apartmentService: ApartmentService) {
      @GetMapping
      open fun getAllApartments(apartment: Apartment): List<Apartment> {
          return apartmentService.getAllApartments()
      }
    }
    
  • 检查ApartmentController的包路径,确认它确实在com.leaderrealestate包及其子包下,正确路径示例:com.leaderrealestate.controller.ApartmentController。
  • 核对注解的导包,确保所有Spring Web注解都来自org.springframework.web.bind.annotation包。
  • 调用时确认路径是GET /api/apartment(不带s),和ApartmentController配置的路径一致。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.26 05:57:02