spring-boot - Kotlin Unmarshalling 中的 SOAP Web 服务失败
问题描述
一开始这是一个非常普遍的问题,但有没有人使用 Spring Boot 在 Kotlin 中构建 SOAP Web 服务。我正在 Kotlin 中构建一个 SOAP Web 服务,并面临一个关于 Kotlin 数据类的非常奇怪的问题,尽管我正在使用jackson-module-kotlin
.
问题是:
Resolving exception from endpoint [public com.abdulsamadsyed.webservice.model.WebserviceResponse com.abdulsamadsyed.webservice.endpoint.WebserviceEndpoint.getCountry(com.abdulsamadsyed.webservice.model.WebserviceRequest)]: com.sun.xml.bind.v2.runtime.IllegalAnnotationsException: 1 counts of IllegalAnnotationExceptions
com.abdulsamadsyed.webservice.model.WebserviceRequest does not have a no-arg default constructor.
this problem is related to the following location:
at com.abdulsamadsyed.webservice.model.WebserviceRequest
这是我的 xsd 文件
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:tns="http://com.abdulsamadsyed/guides/webservice"
targetNamespace="http://com.abdulsamadsyed/guides/webservice" elementFormDefault="qualified">
<xs:element name="WebserviceRequest">
<xs:complexType>
<xs:sequence>
<xs:element name="name" type="xs:string"/>
</xs:sequence>
</xs:complexType>
</xs:element>
<xs:element name="WebserviceResponse">
<xs:complexType>
<xs:sequence>
<xs:element name="country">
<xs:complexType>
<xs:sequence>
<xs:element name="name" type="xs:string"/>
<xs:element name="population" type="xs:int"/>
<xs:element name="capital" type="xs:string"/>
</xs:sequence>
</xs:complexType>
</xs:element>
</xs:sequence>
</xs:complexType>
</xs:element>
</xs:schema>
请求的数据类:
@XmlAccessorType(XmlAccessType.FIELD)
@XmlType(name = "", propOrder = ["name"])
@XmlRootElement(name = "WebserviceRequest")
class WebserviceRequest(@JsonProperty("name") val name: String)
响应的数据类:
@XmlAccessorType(XmlAccessType.FIELD)
@XmlRootElement(name = "WebserviceResponse")
class WebserviceResponse (
@JsonProperty("name") val name: String,
@JsonProperty("population") val population: Int,
@JsonProperty("capital") val capital: String
)
配置 kotlin 模块的简单配置类:
@Configuration
class WebserviceConfig {
@Bean
fun objectMapper(): ObjectMapper = ObjectMapper()
.registerKotlinModule()
.registerModule(JavaTimeModule())
}
SOAP 请求的配置类:
@EnableWs
@Configuration
class SOAPRequestConfig {
@Bean
fun messageDispatcherServlet(applicationContext: ApplicationContext): ServletRegistrationBean<MessageDispatcherServlet> {
val servlet = MessageDispatcherServlet()
servlet.setApplicationContext(applicationContext)
servlet.isTransformWsdlLocations = true
return ServletRegistrationBean(servlet, "/findcountry/*")
}
@Bean(name = arrayOf("countries"))
fun defaultWsdl11Definition(scoringSchema: XsdSchema?): DefaultWsdl11Definition {
val wsdl11Definition = DefaultWsdl11Definition()
wsdl11Definition.setPortTypeName("CountriesPort")
wsdl11Definition.setLocationUri("/findcountry")
wsdl11Definition.setTargetNamespace("http://com.abdulsamadsyed/guides/webservice")
wsdl11Definition.setSchema(scoringSchema)
return wsdl11Definition
}
@Bean
fun serviceSchema(): XsdSchema {
return SimpleXsdSchema(ClassPathResource("service.xsd"))
}
}
我的 POM(我正在使用 Java 11):
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web-services</artifactId>
</dependency>
<dependency>
<groupId>com.fasterxml.jackson.module</groupId>
<artifactId>jackson-module-kotlin</artifactId>
</dependency>
<dependency>
<groupId>org.jetbrains.kotlin</groupId>
<artifactId>kotlin-reflect</artifactId>
</dependency>
<dependency>
<groupId>org.jetbrains.kotlin</groupId>
<artifactId>kotlin-stdlib-jdk8</artifactId>
</dependency>
<dependency>
<groupId>com.fasterxml.jackson.dataformat</groupId>
<artifactId>jackson-dataformat-xml</artifactId>
<version>2.12.4</version>
</dependency>
<dependency>
<groupId>wsdl4j</groupId>
<artifactId>wsdl4j</artifactId>
</dependency>
<dependency>
<groupId>com.fasterxml.jackson.module</groupId>
<artifactId>jackson-module-kotlin</artifactId>
<version>2.12.4</version>
</dependency>
<dependency>
<groupId>com.h2database</groupId>
<artifactId>h2</artifactId>
</dependency>
<!-- Using jpa because it has Jaxb implemetation-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-jpa</artifactId>
<version>2.5.4</version>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
<!-- <dependency>-->
<!-- <groupId>javax.xml.bind</groupId>-->
<!-- <artifactId>jaxb-api</artifactId>-->
<!-- </dependency>-->
<!-- <!– JAXB Implementation –>-->
<!-- <dependency>-->
<!-- <groupId>com.sun.xml.bind</groupId>-->
<!-- <artifactId>jaxb-impl</artifactId>-->
<!-- <version>3.0.0</version>-->
<!-- <scope>runtime</scope>-->
<!-- </dependency>-->
<!-- <dependency>-->
<!-- <groupId>javax.xml.bind</groupId>-->
<!-- <artifactId>jaxb-api</artifactId>-->
<!-- </dependency>-->
<!-- <!– https://mvnrepository.com/artifact/javax.activation/activation –>-->
<!-- <dependency>-->
<!-- <groupId>javax.activation</groupId>-->
<!-- <artifactId>activation</artifactId>-->
<!-- <version>1.1</version>-->
<!-- </dependency>-->
<!-- <!– https://mvnrepository.com/artifact/org.glassfish.jaxb/jaxb-runtime –>-->
<!-- <dependency>-->
<!-- <groupId>org.glassfish.jaxb</groupId>-->
<!-- <artifactId>jaxb-runtime</artifactId>-->
<!-- </dependency>-->
</dependencies>
它只接受请求并返回一个包含 3 个字段的响应。
现在是我的 Endpoint 类,它接收请求并返回响应对象
@Endpoint
class WebserviceEndpoint {
@PayloadRoot(namespace = "http://com.abdulsamadsyed/guides/webservice", localPart = "WebserviceRequest")
@ResponsePayload
fun getCountry(@RequestPayload request: WebserviceRequest): WebserviceResponse {
print("---------------------------" + request.name + "-------------------------")
return WebserviceResponse(request.name, 20000, "helsinki")
}
}
当我使用以下国家-request.xml 运行它时
<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/"
xmlns:gs="http://com.abdulsamadsyed/guides/webservice">
<soapenv:Header/>
<soapenv:Body>
<gs:WebserviceRequest>
<gs:name>Spain</gs:name>
</gs:WebserviceRequest>
</soapenv:Body>
</soapenv:Envelope>
用这个命令
curl --header "content-type: text/xml" -d @countries-request.xml http://localhost:8081/findcountry
它给了我以下错误,我也粘贴在上面。
Resolving exception from endpoint [public com.abdulsamadsyed.webservice.model.WebserviceResponse com.abdulsamadsyed.webservice.endpoint.WebserviceEndpoint.getCountry(com.abdulsamadsyed.webservice.model.WebserviceRequest)]: com.sun.xml.bind.v2.runtime.IllegalAnnotationsException: 1 counts of IllegalAnnotationExceptions
com.abdulsamadsyed.webservice.model.WebserviceRequest does not have a no-arg default constructor.
this problem is related to the following location:
at com.abdulsamadsyed.webservice.model.WebserviceRequest
实际上,当请求到来时,解组应该起作用,因为我正在使用 jackson-module-kotlin
并且它说我们不需要为数据类属性提供默认值。https://github.com/FasterXML/jackson-module-kotlin
任何帮助都将受到高度评价,因为我无法找到许多使用 Kotlin 构建 SOAP Web 服务的资源。
解决方案
推荐阅读
- angular - 角度扁平化可观察流
- python - 有没有办法在嗖嗖声的 QueryParser 中返回距离
- jenkins - Where's the list of available functions or API available to me by default in a Jenkinsfile?
- java - 无法让我的 MouseListener 为高中的口袋妖怪游戏工作
- git - 在具有许多子模块的项目中实现 git flow 的最佳方法是什么
- r - 如何在ggplot2中创建日期为月份的极坐标图
- c++ - 链表的这个赋值运算符是否进行深层复制?
- batch-file - 如何将字符串和用户输入回显到文件中
- laravel - Smtp Gmail 无法正常工作,正如我在实时服务器中所尝试的那样
- php - PHP:忘记密码模块意外工作