根据另一个字段值序列化和反序列化一个字段

Posted

技术标签:

【中文标题】根据另一个字段值序列化和反序列化一个字段【英文标题】:Serialize and deserialize a field according to another field value 【发布时间】:2019-04-20 22:54:47 【问题描述】:

如何根据同一类中的另一个字段值对字段进行序列化或反序列化?

在下面的例子中,当序列化或反序列化Packet 类时,我希望type 字段将确定如何 payload 字段将被序列化和反序列化。

PayloadType 枚举

public enum PayloadType 
    HTTP,
    HTTPS,
    FTP

包类

public class Packet 
    private final String payload;
    // This field should determine how "payload" field is serialized.
    private final PayloadType type;     
    private final Date creationTime;

@JsonCreator
public Packet(String payload, PayloadType type) 
    this.payload = payload;
    this.type = type;
    this.creationTime = new Date();


public String getPayload() 
    return this.payload;


public PayloadType getType() 
    return this.type;


public Date getCreationTime() 
    return this.creationTime;

测试

public class PacketTests 
@Test
public void packetSerialization_fromHttpType() throws JsonProcessingException 
    // Given
    ObjectMapper jackson = new ObjectMapper();
    String payload = "hello world";
    PayloadType type = PayloadType.HTTP;
    Packet packet = new Packet(payload, type);
    String json;

    // When
    json = jackson.writeValueAsString(packet);

    // Then
    System.out.println(json);

电流输出

"payload":"hello world","type":"HTTP","creationTime":1542538836041

预期产出

"payload":"(http) hello world","type":"HTTP","creationTime":1542538836041
"payload":"(https) hello world","type":"HTTPS","creationTime":1542538836041
"payload":"X9hnahj83","type":"FTP","creationTime":1542538836041

FTPpayload 是 base64 字符串。

【问题讨论】:

你需要一个custom seralizer 和一个custom deseralizer @guleryuz 你说得对,但我没有找到任何直接的方法来使用自定义序列化器和反序列化器。 一种更简单的方法可能是在Packet 类中放置一个新方法,例如public String getPayloadLong() return "(" + getType().name().toLowerCase() + ") " + getPayload(); ,然后您将在json 中看到一个名为payloadLong 的新字段。这样你就不需要custom (de)seralizers @guleryuz 我写的代码只是一个例子,所以,作为另一个例子,考虑 FTP 类型的 payload 是字符串基 64 字节数组。 【参考方案1】:

类似于@comment 更新payload getter 以返回不同的输出值

 public String getPayload() 
     return "(" + getType().name().toLowerCase() + ") " +  this.payload;
 

【讨论】:

查看我的comment for @guleryu,我还更新了问题中的预期结果(特别是FTP 类型) @Eido95 你可以自己做,不是吗? 作为一种解决方法,我确实可以自己做,但这就是为什么我要问,是否可以使用 Jackson 来做 - 也许不是。

以上是关于根据另一个字段值序列化和反序列化一个字段的主要内容,如果未能解决你的问题,请参考以下文章

spring/jackson:实现对保存JSON字符串的字段自动序列化和反序列化

Spring Boot LocalDate 字段序列化和反序列化

JOOQ 类中的布尔字段未由 Jackson/RestEasy 一致地序列化和反序列化

DRF序列化和反序列化(二:ModelSerializer)

使用Newtonsoft.Json.dll序列化和反序列化

Jackson关于Boolean类型反序列化问题