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

SpringWS(Kotlin)报错:带@Endpoint和@RequestPayload的端点无适配

解决Spring WS中"No adapter for endpoint"错误的方案

我之前也踩过这个Spring Web Service的坑!这个错误的核心是Spring无法找到合适的适配器来处理你的@Endpoint方法,通常和几个常见的配置疏漏有关,咱们一步步排查解决:

1. 确认Endpoint类被Spring正确扫描

首先要保证你的CountryEndpoint所在的包被Spring的组件扫描覆盖到:

  • 要么在启动类上通过scanBasePackages指定扫描范围,比如:
    @SpringBootApplication(scanBasePackages = ["jp.tamagotchi.soap.endpoints", "io.spring.guides.gs_producing_web_service"])
    class SoapApplication
    
    fun main(args: Array<String>) {
        runApplication<SoapApplication>(*args)
    }
    
  • 或者给CountryEndpoint显式加上@Component注解(虽然@Endpoint本身应该被Spring识别,但有些场景下显式声明更稳妥)

2. 检查Spring WS配置类是否完整

你需要一个带有@EnableWs注解的配置类,继承WsConfigurerAdapter(或实现WsConfigurer),并定义必要的Bean:

@Configuration
@EnableWs
class WebServiceConfig : WsConfigurerAdapter() {

    // 配置消息分发Servlet
    @Bean
    fun messageDispatcherServlet(applicationContext: ApplicationContext): MessageDispatcherServlet {
        val servlet = MessageDispatcherServlet()
        servlet.setApplicationContext(applicationContext)
        servlet.isTransformWsdlLocations = true
        return servlet
    }

    // 定义WSDL
    @Bean(name = ["countries"])
    fun defaultWsdl11Definition(countriesSchema: XsdSchema): Wsdl11Definition {
        val wsdlDefinition = DefaultWsdl11Definition()
        wsdlDefinition.setPortTypeName("CountriesPort")
        wsdlDefinition.setLocationUri("/ws") // 这个是SOAP请求的基础路径
        wsdlDefinition.setTargetNamespace("http://spring.io/guides/gs-producing-web-service") // 和XSD的命名空间一致
        wsdlDefinition.setSchema(countriesSchema)
        return wsdlDefinition
    }

    // 加载XSD Schema
    @Bean
    fun countriesSchema(): XsdSchema {
        return SimpleXsdSchema(ClassPathResource("countries.xsd"))
    }
}

3. 验证Endpoint方法的注解是否正确

@RequestPayload不能单独使用,必须配合@PayloadRoot来指定请求的命名空间和根元素名称,示例如下:

@Endpoint
class CountryEndpoint {
    private val countryData = mapOf(
        "Japan" to Country("Japan", "Tokyo", "Asia", 125700000),
        "Germany" to Country("Germany", "Berlin", "EU", 83200000)
    )

    // 关键:@PayloadRoot必须指定正确的namespace和localPart
    @PayloadRoot(
        namespace = "http://spring.io/guides/gs-producing-web-service",
        localPart = "getCountryRequest"
    )
    @ResponsePayload
    fun getCountry(@RequestPayload request: GetCountryRequest): GetCountryResponse {
        val response = GetCountryResponse()
        response.country = countryData[request.name] ?: throw RuntimeException("Country not found: ${request.name}")
        return response
    }
}

这里的namespace要和XSD文件中的目标命名空间完全一致,localPart要对应SOAP请求XML的根元素名称(比如你的请求XML根节点是<getCountryRequest>,这里就填getCountryRequest)

4. 检查参数类型与XSD生成类的匹配度

确保GetCountryRequest是通过XSD正确生成的类,并且带有正确的JAXB注解(比如@XmlRootElement、@XmlType),命名空间也要和配置中的一致。如果是用spring-boot-maven-plugin或spring-boot-gradle-plugin生成的类,要保证生成过程没有报错。

5. 确认依赖是否齐全

在你的build.gradle.kts中,要包含Spring WS的核心依赖:

dependencies {
    implementation("org.springframework.boot:spring-boot-starter-web-services")
    implementation("wsdl4j:wsdl4j:1.6.3")
    // Java 9+ 需要添加JAXB依赖
    implementation("com.sun.xml.bind:jaxb-impl:2.3.8")
    implementation("javax.xml.bind:jaxb-api:2.3.1")
}

按照上面的步骤排查,基本就能解决这个"No adapter for endpoint"的问题了!

内容的提问来源于stack exchange,提问作者J. Pichardo

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.20 11:10:53