java - 如何反序列化包含带有时间戳数据的数组列表的类

标签 java json gson

我有一个如下的 jsonstring

{"coaList":[{"iD":324,"strName":"Cash","hasChildren":false,"amount":3500.0,"transDate":1421346600000},{"iD":326,"strName":"Cash","hasChildren":false,"amount":2000.0,"transDate":1421346600000},{"iD":328,"strName":"HDFC Bank","hasChildren":false,"amount":2500.0,"transDate":1421346600000}]}

我需要将此字符串转换为 CoaAccountList 类对象。下面是 CoaAccountList 类。 CoaAccountList.java:

public class CoaAccountList implements Serializable  {

private List<COAAccount> coaList;

public List<COAAccount> getCoaList() {
    return coaList;
}

public void setCoaList(List<COAAccount> coaList) {
    this.coaList = coaList;
}

}

其中 COAAccount 类包含 transDate 作为 TimeStamp 变量,在 json 字符串中包含 Long 变量,因此我的转换过程会导致此长 transDate 值出现 com.google.gson.JsonSyntaxException。下面是我用来转换 json 字符串的代码到 CoaAccountList

Gson gson = new Gson();
CoaAccountList transHisList=gson.fromJson(jsonString, CoaAccountList.class);

下面是 COAAccount 类。

COAAccount.java:

public class COAAccount implements Serializable {
private int iD;
private String strName;
private boolean hasChildren;
private float amount;
private Timestamp transDate;

public COAAccount() {
    super();
    // TODO Auto-generated constructor stub
}

public COAAccount(int iD, String strName, boolean hasChildren, float amount, Timestamp transDate) {
    super();
    this.iD = iD;
    this.strName = strName;
    this.hasChildren = hasChildren;
    this.amount = amount;
    this.transDate = transDate;
}

public int getiD() {
    return iD;
}

public void setiD(int iD) {
    this.iD = iD;
}

public String getStrName() {
    return strName;
}

public void setStrName(String strName) {
    this.strName = strName;
}

public boolean isHasChildren() {
    return hasChildren;
}

public void setHasChildren(boolean hasChildren) {
    this.hasChildren = hasChildren;
}

public float getAmount() {
    return amount;
}

public void setAmount(float amount) {
    this.amount = amount;
}

public Timestamp getTransDate() {
    return transDate;
}

public void setTransDate(Timestamp transDate) {
    this.transDate = transDate;
}

@Override
public String toString() {
    return strName;
}
}

请帮我将此 json 字符串转换为 CoaAccountList 对象。

最佳答案

在需要使用自定义反序列化模式的情况下,Gson 允许您根据类型注册自己的反序列化代码。

为此,您首先需要从 GsonBuilder 实例化 Gson,而不是使用以下代码:

GsonBuilder gson = new GsonBuilder();

那么在处理 Timestamp 类型时,您需要将 JsonDeserializer 实例附加到 GsonBuilder 中,如下所示:

gson.registerTypeAdapter(Timestamp.class, new GsonTimestampDeserializer());

注意:GsonTimestampDeserializer 是我们在下面创建的自定义类,从技术上讲,您可以将其命名为任何您想要的名称。

注册自定义反序列化器,当需要从原始类型(int、string、double等)转换为指定的注册类型时,Gson将根据需要自动调用 JsonDeserializer 接口(interface)的 deserialize() 方法。为了利用这一点,我们实现解串器如下:

private class GsonTimestampDeserializer implements JsonDeserializer<Timestamp>{
    public Timestamp deserialize(JsonElement json, Type typeOfT, JsonDeserializationContext context) throws JsonParseException{
        return new Timestamp(json.getAsJsonPrimitive().getAsLong());
    }
}

注意:我假设您正在使用 java.sql 中的 Timestamp 对象,该对象提供了一个需要很长时间的构造函数。

把它们放在一起:

GsonBuilder gson = new GsonBuilder();
gson.registerTypeAdapter(Timestamp.class, new GsonTimestampDeserializer());

private class GsonTimestampDeserializer implements JsonDeserializer<Timestamp>{
    public Timestamp deserialize(JsonElement json, Type typeOfT, JsonDeserializationContext context) throws JsonParseException{
        return new Timestamp(json.getAsLong());
    }
}

Gson gsonInstance = gson.create();

CoaAccountList transHisList = gsonInstance.fromJson(jsonString, CoaAccountList.class);

当 Gson 解析 JSON 字符串并尝试填充相应的值时,它在 transDate 上遇到 Timestamp 类型,并且没有使用 java 具有的默认对象反序列化方案,而是使用我们提供的自定义反序列化方案将 long 转换为 Timestamp 对象。

该方法可以推广到各种复杂的容器类,这些容器类可以将其数据存储为单个基元类型,并且等效地可以使用 GsonSerializer 来实现相反的目的。

关于java - 如何反序列化包含带有时间戳数据的数组列表的类,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/30211699/

相关文章:

java - 我们如何在 Java 中进行异步 REST api 调用?

java - 在具有滚动功能的 JTextArea 中显示数组

python - 没有 Spark 的 Kafka 到 Pandas 数据框

json - 需要使用 REST - SharePoint 托管应用程序将文件夹添加到 SharePoint 2013 中的文档库

php - 通过ajax将隐藏输入发送到php脚本不起作用

javascript - Gson.fromJson 卡在线上

java - OWL java对两个类使用相同的数据属性

java - 除了javafx中的小动画时间线,还有什么解决办法吗?

java - 改造 2.1.0 + Gson。序列化作为子类的@Body

java - 通用反序列化的 Gson 类型 token 问题