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

Spring Boot3+Kotlin+Gradle环境下Apache CXF最简配置失效排查

Spring Boot 3 + Kotlin + Gradle + Apache CXF 端点404问题

我尝试用Spring Boot 3、Kotlin和Gradle搭建最小化的Apache CXF Web应用,但唯一的端点始终返回404。网上的CXF+Spring Boot教程大多过时,官方文档甚至停留在3.1版本(当前CXF是4.0),但我查的资料里代码看起来没问题。

SpringKotlinInterfaceTestApplication.kt

import com.fasterxml.jackson.annotation.JsonInclude
import com.fasterxml.jackson.databind.ObjectMapper
import com.fasterxml.jackson.datatype.joda.JodaModule
import com.fasterxml.jackson.jakarta.rs.json.JacksonJsonProvider
import jakarta.ws.rs.*
import org.apache.cxf.Bus
import org.apache.cxf.endpoint.Server
import org.apache.cxf.jaxrs.JAXRSServerFactoryBean
import org.springframework.boot.autoconfigure.SpringBootApplication
import org.springframework.boot.runApplication
import org.springframework.context.annotation.Bean
import org.springframework.context.annotation.Configuration
import org.springframework.stereotype.Component

@Component
@Consumes("application/json")
@Produces("application/json")
class PreconditionApiImpl {
    @GET @Path("/pingx")
    fun pingx(): String = "{status: OK}"
}

@SpringBootApplication
class SpringKotlinInterfaceTestApplication

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

@Configuration
class RsConfig {
    @Bean
    fun getRsServer(bus: Bus, api: PreconditionApiImpl): Server = JAXRSServerFactoryBean().apply {
        setBus(bus)
        address = "/"
        setServiceBeans(listOf(api))
        setProvider(
            JacksonJsonProvider().apply {
                setMapper(ObjectMapper().apply {
                    registerModule(JodaModule())
                    setSerializationInclusion(JsonInclude.Include.NON_EMPTY)
                })
            }
        )
    }.create()
}

build.gradle.kts

import org.jetbrains.kotlin.gradle.tasks.KotlinCompile

plugins {
    id("org.springframework.boot") version "3.0.9"
    id("io.spring.dependency-management") version "1.0.15.RELEASE"
    val kotlinVersion = "1.9.0"
    kotlin("jvm") version kotlinVersion
    kotlin("plugin.spring") version kotlinVersion
}

group = "com.example"
version = "0.0.1-SNAPSHOT"

java {
    sourceCompatibility = JavaVersion.VERSION_17
}

repositories {
    mavenCentral()
}

dependencies {
    implementation("org.springframework.boot:spring-boot-starter-web")
    implementation("com.fasterxml.jackson.module:jackson-module-kotlin")
    implementation("org.springframework.boot:spring-boot-starter-actuator")
    implementation("org.jetbrains.kotlin:kotlin-reflect")

    val jacksonVersion = "2.14.3"
    implementation("com.fasterxml.jackson.jakarta.rs:jackson-jakarta-rs-json-provider:$jacksonVersion")
    implementation("com.fasterxml.jackson.datatype:jackson-datatype-joda:$jacksonVersion")

    val cxfVersion = "4.0.2"
    implementation("org.apache.cxf:cxf-spring-boot-starter-jaxrs:$cxfVersion")
    implementation("org.apache.cxf:cxf-rt-rs-client:$cxfVersion")
    implementation("org.apache.cxf:cxf-rt-transports-http:$cxfVersion")
    implementation("org.apache.cxf:cxf-rt-frontend-jaxws:$cxfVersion")
}

tasks.withType<KotlinCompile> {
    kotlinOptions {
        freeCompilerArgs += "-Xjsr305=strict"
        jvmTarget = "17"
    }
}

问题

向http://localhost:8080/pingx发送GET请求返回404,遗漏了什么配置?难道cxf-spring-boot-starter-jaxrs没有完成所有基础自动装配?


解决思路

1. 解决Spring Web与CXF的冲突

你引入了spring-boot-starter-web,它自带Spring MVC和Tomcat,会抢占根路径的请求处理权,导致CXF的端点无法被路由。有两种处理方式:

  • 替换为基础starter:把implementation("org.springframework.boot:spring-boot-starter-web")改成implementation("org.springframework.boot:spring-boot-starter"),去掉Spring MVC依赖,让CXF接管HTTP请求。
  • 排除Spring MVC自动配置:如果需要保留Spring Web的其他功能,修改启动类:
    @SpringBootApplication(exclude = [org.springframework.boot.autoconfigure.web.servlet.WebMvcAutoConfiguration::class])
    class SpringKotlinInterfaceTestApplication
    

2. 调整CXF基础路径配置

默认情况下,CXF starter会把所有端点挂载在/services路径下。即使你在代码中设置address = "/",实际访问路径可能是http://localhost:8080/services/pingx。

可以在application.properties中添加配置,让CXF直接挂载到根路径:

cxf.path=/

3. 验证CXF Bean初始化状态

你已经引入了spring-boot-starter-actuator,可以开启beans端点查看CXF相关Bean是否正常初始化:
在application.properties中添加:

management.endpoints.web.exposure.include=beans

访问http://localhost:8080/actuator/beans,搜索org.apache.cxf相关条目,确认Server和Bus实例已成功创建。

4. 移除多余依赖

你引入的cxf-rt-frontend-jaxws是JAX-WS相关依赖,当前用的是JAX-RS,这个依赖完全多余,可以删除,避免潜在冲突。


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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.14 22:59:53