【发布时间】:2020-10-27 21:34:07
【问题描述】:
我在创建具有 application/xml 类型的简单 REST 控制器时遇到问题。 我正在使用 Kotlin 并通过在 Gradle KTS 中提供依赖项来注册 Jackson 转换器
“实施”(组=“com.fasterxml.jackson.dataformat”,名称=“jackson-dataformat-xml”,版本=jacksonXmlVersion)
Controller 使用 Swagger,看起来像这样:
@ApiOperation(
value = "Epcis capture point",
response = EPCISDocResponse::class,
httpMethod = "POST"
)
@PostMapping(
"/capture",
consumes = [MediaType.APPLICATION_XML_VALUE],
produces = [MediaType.APPLICATION_XML_VALUE]
)
fun capture(@RequestBody request: EPCISDocumentType): ResponseEntity<EPCISDocResponse> {
doSomething()
}
我的模型类是由 XJC 生成的,看起来像这样:
@XmlAccessorType(XmlAccessType.FIELD)
@XmlType(name = "EPCISDocumentType", propOrder = {
"epcisHeader",
"epcisBody",
"extension",
"any"
})
@XmlRootElement(name = "EPCISDocument", namespace = "urn:epcglobal:epcis:xsd:1")
public class EPCISDocumentType
extends Document
{
问题是 Spring Boot 找不到 application/xml 对应的转换器,并尝试将其解析为 JSON,给我下一个错误:
.w.s.m.s.DefaultHandlerExceptionResolver:已解决 [org.springframework.http.converter.HttpMessageNotReadableException:JSON 解析错误:无法反序列化
java.util.ArrayList<java.lang.Object>的实例,超出 VALUE_STRING 令牌;嵌套异常是 com.fasterxml.jackson.databind.exc.MismatchedInputException: Cannot deserialize instance ofjava.util.ArrayList<java.lang.Object>out of VALUE_STRING token 在 [来源:(PushbackInputStream);行:4,列:2](通过引用链:epcis.capture.EPCISDocumentType["any"])]
我为 SOAPTemplate 定义了一个 Jaxb2 编组器,它可能会干扰:
@Bean
fun marshaller(): Jaxb2Marshaller? {
val marshaller = Jaxb2Marshaller()
marshaller.setClassesToBeBound(
epcis.capture.EPCISDocumentType::class.java,
CaptureEPCISDocResponse::class.java,
LeanEPCISDocResponse::class.java
)
return marshaller
}
非常感谢任何帮助,这是我第一次看到杰克逊映射到内容类型的问题。
在应用程序上下文中注册的转换器列表:
org.springframework.http.converter.StringHttpMessageConverter@531bfe4b
org.springframework.http.converter.ResourceHttpMessageConverter@2c8f7d6a
org.springframework.http.converter.ResourceRegionHttpMessageConverter@77331437
org.springframework.http.converter.xml.SourceHttpMessageConverter@98a0842
org.springframework.http.converter.support.AllEncompassingFormHttpMessageConverter@56f569e
org.springframework.http.converter.xml.MappingJackson2XmlHttpMessageConverter@525c0f74
org.springframework.http.converter.json.MappingJackson2HttpMessageConverter@3da12ba4
更新
我能够通过删除 MappingJackson2XmlHttpMessageConverter 来解决这个问题,因为我的模型包含 XmlRootElement 并且应该由 Jaxb2RootElementHttpMessageConverter 编组,但现在问题更加奇怪了。 现在,Jaxb2Root 转换器没有将它编组到我的对象中,而是为我的控制器提供了 JAXBElement:
Method [public org.springframework.http.ResponseEntity<com.movilizer.lean.model.epcis.LeanEPCISDocResponse> com.movilizer.lean.leanepcis.controller.EpcisController.capture(epcis.capture.EPCISDocumentType)] with argument values:
[0] [type=javax.xml.bind.JAXBElement] [value=javax.xml.bind.JAXBElement@76e6ecc4] ] with root cause
根据我的发现,似乎是特定的 sun jaxb-impl 负责此问题,因此解析器提供 JAXBElement 而不是有效负载本身。 有什么帮助吗?
【问题讨论】:
标签: java spring spring-boot rest kotlin