如何将 serialize/deserialize 嵌套哈希表 JSON?

How to serialize/deserialize nested hashtable to JSON?

我有一个 android 应用程序。我使用以下结构在 SharedPreferences 中存储一些数据:

Hashtable<Integer, Hashtable<Size, Time>> 

我按以下方式进行序列化:

private static String serialize(Hashtable<Integer, Hashtable<Size, Time>> results) {
    Gson gson = new GsonBuilder().create();
    return gson.toJson(results);
}

和反序列化:

private Hashtable<Integer, Hashtable<Size, Time>> deserialize(String resultsJsonStr) {

    if (resultsJsonStr == null)
        return new Hashtable<>();
    else {
        Type typeOfHashMap = new TypeToken<Hashtable<Integer, Hashtable<Size, Time>>>() {}.getType();
        return new Gson().fromJson(resultsJsonStr, typeOfHashMap);
    }
}

然而,当我尝试反序列化时,我收到异常:

com.google.gson.JsonSyntaxException: java.lang.IllegalStateException: Expected BEGIN_OBJECT but was STRING at line 1 column 8 path $

我的序列化字符串看起来像: {"3":{"4x4":"01:12:37 AM"}}

问题是 Time 对象不可序列化,您应该为它提供序列化和反序列化机制。我假设您代码中的 Time class 是 java.sql.Time,它是 java.util.Date 的子 class,因此它同时具有:

public long getTime() { ... }

public void setTime(long time) { ... }

我已经为它开发了示例代码,你可以随意更改它:

import com.google.gson.Gson;
import com.google.gson.GsonBuilder;
import com.google.gson.JsonDeserializationContext;
import com.google.gson.JsonDeserializer;
import com.google.gson.JsonElement;
import com.google.gson.JsonParseException;
import com.google.gson.JsonPrimitive;
import com.google.gson.JsonSerializationContext;
import com.google.gson.JsonSerializer;
import com.google.gson.reflect.TypeToken;

import java.lang.reflect.Type;
import java.sql.Time;
import java.util.Hashtable;

public class SerializeHelper {

    private static Gson gson;

    static {
        JsonSerializer<Time> serializer = new JsonSerializer<Time>() {
            @Override
            public JsonElement serialize(Time src, Type type, JsonSerializationContext context) {
                return src == null ? null : new JsonPrimitive(src.getTime());
            }
        };

        JsonDeserializer<Time> deserializer = new JsonDeserializer<Time>() {
            @Override
            public Time deserialize(JsonElement json, Type type, JsonDeserializationContext context) throws JsonParseException {
                return json == null ? null : new Time(json.getAsLong());
            }
        };

        gson = new GsonBuilder()
                .registerTypeAdapter(Time.class, serializer)
                .registerTypeAdapter(Time.class, deserializer).create();
    }

    public static String serialize(Hashtable<Integer, Hashtable<Size, Time>> results) {
        return gson.toJson(results);
    }

    public Hashtable<Integer, Hashtable<Size, Time>> deserialize(String resultsJsonStr) {
        if (resultsJsonStr == null)
            return new Hashtable<>();
        else {
            Type typeOfHashMap = new TypeToken<Hashtable<Integer, Hashtable<Size, Time>>>() {
            }.getType();
            return gson.fromJson(resultsJsonStr, typeOfHashMap);
        }
    }

}