当前位置: 首页 > 知识库问答 >
问题:

具有泛型属性的类的Jackson序列化丢失泛型属性的类型信息

贡正诚
2023-03-14

当我使用Jackson ectivtMapper将有效负载序列化为字符串值时,我很难获取要维护的泛型属性的类型信息。

我想要达到的结果如下。

{"@type":"BlockChainWrapper","@id":1,"payload":{"@type":"TestClassA","@id":2,"helloWorld":"Hello World"},"nonce":255,"signature":"SGVsbG8gV29ybGQ="}

我实际得到的结果如下(注意TestClassA缺少@type信息)。

{"@type":"BlockChainWrapper","@id":1,"payload":{"@id":2,"helloWorld":"Hello World"},"nonce":255,"signature":"SGVsbG8gV29ybGQ="}

我使用的测试是:

class BlockChainWrapperTest extends Specification {

    def objectMapper = JacksonConfiguration.createObjectMapper()

    def "test Json marshalling"() {
        given: "A test payload"
        def payload = new BlockChainWrapper<TestClassA>(
                payload: new TestClassA(),
                nonce: 255,
                signature: "Hello World".getBytes(Charset.defaultCharset())
        )

        when:
        //ObjectWriter w = objectMapper.writerFor(new TypeReference<BlockChainWrapper<TestClassA>>() { });
        //def result = w.writeValueAsString(payload)
        def result = objectMapper.writeValueAsString(payload)

        then:
        assert result == "{\"@type\":\"BlockChainWrapper\",\"@id\":1,\"payload\":{\"@type\":\"TestClassA\",\"@id\":2,\"helloWorld\":\"Hello World\"},\"nonce\":255,\"signature\":\"SGVsbG8gV29ybGQ=\"}"
    }

    def "test TestClassA generates correct JSON"() {
        given:
        def payload = new TestClassA()

        when:
        def result = objectMapper.writeValueAsString(payload)

        then:
        assert result == "{\"@type\":\"TestClassA\",\"@id\":1,\"helloWorld\":\"Hello World\"}"
    }
}

“test JSON编组”测试中有两个版本。注释掉的版本和未注释的版本都会产生完全相同的结果。

第二个测试验证TestClassA本身是否生成了正确的类型信息。

只有当包含泛型类型的父类时,问题才会变成问题,随后会丢失类型信息,并导致反序列化返回TestClassA内容的LinkedHashMap。

TestClassA看起来像:

@JsonRootName("TestClassA")
@JsonTypeInfo(use = JsonTypeInfo.Id.NAME, property = "@type")
@JsonIdentityInfo(generator = ObjectIdGenerators.IntSequenceGenerator.class)
public class TestClassA implements Serializable {

    private String helloWorld = "Hello World";
}

泛型类如下所示:

@JsonRootName("BlockChainWrapper")
@JsonTypeInfo(use = JsonTypeInfo.Id.NAME, include= JsonTypeInfo.As.PROPERTY, property = "@type")
@JsonIdentityInfo(generator = ObjectIdGenerators.IntSequenceGenerator.class)
public class BlockChainWrapper<T> implements Serializable {

    private T payload;

为完整起见,Jackson ObjectMapper配置为

var mapper = new Jackson2ObjectMapperBuilder()
    .createXmlMapper(false)
    .modules(new JavaTimeModule(), new Jdk8Module())
    .serializationInclusion(JsonInclude.Include.NON_NULL)
    .build();
mapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);
mapper.configure(JsonGenerator.Feature.WRITE_BIGDECIMAL_AS_PLAIN, true);
mapper.configure(DeserializationFeature.USE_BIG_DECIMAL_FOR_FLOATS, true);
mapper.configure(DeserializationFeature.READ_DATE_TIMESTAMPS_AS_NANOSECONDS, false);
mapper.configure(DeserializationFeature.ADJUST_DATES_TO_CONTEXT_TIME_ZONE, false);
mapper.configure(SerializationFeature.WRITE_DATE_TIMESTAMPS_AS_NANOSECONDS, false);
mapper.disable(SerializationFeature.WRITE_DATES_AS_TIMESTAMPS);

共有1个答案

东云
2023-03-14

我想我已经解决了你的问题。我已经用这个解决方案创建了一个github项目。https://github.com/GaetanoPiazzolla/stackoverflow-question-61025761

简而言之,您还应该在有效负载字段中添加@JsonTypeInfo注释:

@JsonTypeInfo(use=JsonTypeInfo.Id.NAME, include=JsonTypeInfo.As.PROPERTY, property="@type")
private T payload;
 类似资料:
  • 如何使用多态反序列化和嵌套类型信息属性反序列化它?我在中使用嵌套属性,如下所示: 鉴于config Jackson抱怨无法找到属性:

  • 问题内容: 我正在尝试制作一个使用Jackson来反序列化POJO的类。 看起来像这样… 我对此实施有2个问题。 首先是我将类类型传递给方法,以便对象映射器知道应反序列化的类型。有使用泛型的更好方法吗? 同样在get方法中,我将一个从objectMapper返回的对象强制转换为T。这看起来特别讨厌,因为我必须在此处强制转换T,然后还必须从调用它的方法中强制转换对象类型。 我在该项目中使用了Robo

  • 我用Jackson编写了自己的序列化程序。它接受一个变量或类,并返回任何简单类型的值。 示例:serialize(new MyClass(2.0))将返回一个值为 2.0 的双精度值,其中 MyClass 如下所示: 因此,为了获得正确的值,我需要设置@JsonValue,但是,当我序列化一个没有@JsonValue注释的对象(例如UUID)时,它会返回预期的UUID字符串。 创建我自己的类没有@

  • 我需要将包含类型为Pair的对象的列表序列化为xml 首先,我创建了一个类PairList来保存对的列表,然后我创建了一个实际的类,它表示一对两个值,key和value。 然后,我尝试序列化它: 不幸的是,我遇到了一个异常:。欢迎任何关于如何避免此异常并序列化该类的想法。 如果我选择不序列化ttype和utype字段(通过将其设置为受保护或私有),则序列化有效。我不明白为什么它不想序列化类型字段。

  • 嗨,我是Java泛型的新手,我正在尝试访问泛型类中的属性。到目前为止,我已经找到了C#相关的答案,如果有人能指导我如何在java中做到这一点,那将是非常有帮助的。假设我有Class Car,它有整数型轮子和字符串型模型的属性。现在我有一个方法,比如