kotlin Jackson无法将jsonstring反序列化为Textract对象

disbfnqx  于 2023-08-06  发布在  Kotlin
关注(0)|答案(1)|浏览(119)

无法从AWS Java SDK v2反序列化Textract模型对象,如DocumentMetadata -https://sdk.amazonaws.com/java/api/latest/software/amazon/awssdk/services/textract/model/DocumentMetadata.html。获取以下错误:

Cannot construct instance of `software.amazon.awssdk.services.textract.model.DocumentMetadata` (no Creators, like default constructor, exist): cannot deserialize from Object value (no delegate- or property-based Creator)
 at [Source: (StringReader); line: 1, column: 57] (through reference chain: com.amazon.fdmextractionserviceextractfromdocument.data.internal.AnalyseExpenseResponse["DocumentMetadata"]): com.fasterxml.jackson.databind.exc.InvalidDefinitionException
com.fasterxml.jackson.databind.exc.InvalidDefinitionException: Cannot construct instance of `software.amazon.awssdk.services.textract.model.DocumentMetadata` (no Creators, like default constructor, exist): cannot deserialize from Object value (no delegate- or property-based Creator)
 at [Source: (StringReader); line: 1, column: 57] (through reference chain: com.amazon.fdmextractionserviceextractfromdocument.data.internal.AnalyseExpenseResponse["DocumentMetadata"])
    at com.fasterxml.jackson.databind.exc.InvalidDefinitionException.from(InvalidDefinitionException.java:67)
    at com.fasterxml.jackson.databind.DeserializationContext.reportBadDefinition(DeserializationContext.java:1764)
    at com.fasterxml.jackson.databind.DatabindContext.reportBadDefinition(DatabindContext.java:400)
    at com.fasterxml.jackson.databind.DeserializationContext.handleMissingInstantiator(DeserializationContext.java:1209)
    at com.fasterxml.jackson.databind.deser.BeanDeserializerBase.deserializeFromObjectUsingNonDefault(BeanDeserializerBase.java:1415)
    at com.fasterxml.jackson.databind.deser.BeanDeserializer.deserializeFromObject(BeanDeserializer.java:363)
    at com.fasterxml.jackson.databind.deser.BeanDeserializer.deserialize(BeanDeserializer.java:196)
    at com.fasterxml.jackson.databind.deser.impl.MethodProperty.deserializeAndSet(MethodProperty.java:129)
    at com.fasterxml.jackson.databind.deser.BeanDeserializer.vanillaDeserialize(BeanDeserializer.java:325)
    at com.fasterxml.jackson.databind.deser.BeanDeserializer.deserialize(BeanDeserializer.java:188)
    at com.fasterxml.jackson.databind.deser.DefaultDeserializationContext.readRootValue(DefaultDeserializationContext.java:322)
    at com.fasterxml.jackson.databind.ObjectMapper._readMapAndClose(ObjectMapper.java:4593)
    at com.fasterxml.jackson.databind.ObjectMapper.readValue(ObjectMapper.java:3548)
    at com.fasterxml.jackson.databind.ObjectMapper.readValue(ObjectMapper.java:3516)
    at com.amazon.fdmextractionserviceextractfromdocument.data.TextractOutputBuilder.getTextractOutput(TextractOutputBuilder.kt:22)
    at com.amazon.fdmextractionserviceextractfromdocument.domainlogic.ExtractDataComponent.extractData(ExtractDataComponent.kt:12)
    at com.amazon.fdmextractionserviceextractfromdocument.service.ExtractDataActivity.extractData(ExtractDataActivity.kt:14)
    at com.amazon.fdmextractionserviceextractfromdocument.LambdaMain.handleRequest(LambdaMain.kt:23)
    at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(Unknown Source)
    at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source)
    at java.base/java.lang.reflect.Method.invoke(Unknown Source)

字符串

  • 大多数在线资源都提到使用Jackson的注解。在这种情况下,这是无效的,因为模型是从AWS服务导入的。我也试过用Gson。最坏情况的解决方案,在本地创建模型。*
e3bfsja2

e3bfsja21#

在检查DocumentMetadata的模型类的实现时,默认构造函数和属性getter和setter是其Builder接口实现的一部分。这个实现的类可以通过使用DocumentMetadata上的静态方法.serializableBuilderClass()获得(在本例中)。
在数据类属性上使用Jackson注解@JsonDeserialize,可以指示jackson使用上面的类来构造DocumentMetadata(而不是POJO本身)。下面的Kotlin数据类代码示例对我很有用:

data class AnalyseExpenseResponse(
    @JsonDeserialize(using = DocumentMetadataDeserializer::class)
    var documentMetadata: DocumentMetadata? = null
) {

    class DocumentMetadataDeserializer : JsonDeserializer<DocumentMetadata>() {

        override fun deserialize(
            jsonParser: JsonParser,
            deserializationContext: DeserializationContext
        ): DocumentMetadata {
            return jsonParser.readValueAs(DocumentMetadata.serializableBuilderClass()).build()
        }
    }
}

字符串
或者,使用AWS Java SDK v1中的Texextract模型即可开箱即用,无需像上面这样的任何额外解决方法,从而保持代码的整洁。这也有助于嵌套模型,而无需在代码中重新创建数据类。例如,整个AnalyzeExpenseResult可以简单地通过以下方式获得:

objectMapper.readValue(jsonString, AnalyzeExpenseResult::class.java)


(Am Java和Kotlin的新手,但这是我能弄清楚的,请让我知道是否有更优雅的方法让Jackson为v2版本的SDK工作)

相关问题