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
相关产品推荐
相关产品推荐

