Gson Enum序列化

时间:2017-02-07 08:46:23

标签: java serialization enums gson

我在我的java网络应用程序中使用SELECT * FROM income_table WHERE date BETWEEN datetime('now', '-6 days') AND datetime('now', 'localtime'); 将我的api模型序列化为json对象。
我已经成功地将其注释用于版本化模型,但是我没有序列化gson个对象。

Action.class

Enum

尝试序列化public enum Action { @SerializedName("create") CREATE, @SerializedName("read") READ; } 或使用此枚举的另一个pojo,我得到大写字母的字符串。

Hashtable

我做错了什么?

2 个答案:

答案 0 :(得分:1)

除了对您的问题(MapTypeAdapterFactory不是@SerializedName - 知晓)的评论之外,它解释了为什么它不适用于地图并建议在可能的情况下更改数据交换模型,您可以使用自定义JsonSerializer如果您真的使用MapHashtable等数据包:

private static final TypeToken<?> actionToUnknownHashtableTypeToken = new TypeToken<Hashtable<Action, ?>>() {
};

请注意,类型标记用于更精确地定位可序列化枚举并缓存内部序列化名称映射:

final Gson gson = new GsonBuilder()
        .registerTypeAdapter(actionToUnknownHashtableTypeToken.getType(), getSerializedNameEnumHashtableJsonSerializer(Action.class))
        .create();
final Hashtable<Action, String> table = new Hashtable<>();
table.put(CREATE, "item");
out.println(gson.toJson(table, actionToUnknownHashtableTypeToken.getType()));

另请注意toJson方法的使用方法。因此,您知道的每个特定枚举可以单独注册。@SerializedName。和序列化器本身:

final class SerializedNameEnumHashtableJsonSerializer<K extends Enum<K>, V>
        implements JsonSerializer<Hashtable<K, V>> {

    private final Map<K, String> serializedNames;

    private SerializedNameEnumHashtableJsonSerializer(final Map<K, String> serializedNames) {
        this.serializedNames = serializedNames;
    }

    static <K extends Enum<K>, V> JsonSerializer<Hashtable<K, V>> getSerializedNameEnumHashtableJsonSerializer(final Class<K> enumClass) {
        try {
            final Map<K, String> serializedNames = new HashMap<>();
            for ( final K enumConstant : enumClass.getEnumConstants() ) {
                final String enumName = enumConstant.name();
                final Field field = enumClass.getField(enumName);
                final SerializedName serializedName = field.getAnnotation(SerializedName.class);
                if ( serializedName != null ) {
                    serializedNames.put(enumConstant, serializedName.value());
                }
            }
            return new SerializedNameEnumHashtableJsonSerializer<>(unmodifiableMap(serializedNames));
        } catch ( final NoSuchFieldException ex ) {
            throw new AssertionError(ex);
        }
    }

    @Override
    public JsonElement serialize(final Hashtable<K, V> hashtable, final Type type, final JsonSerializationContext context) {
        final JsonObject jsonObject = new JsonObject();
        for ( final Entry<K, V> e : hashtable.entrySet() ) {
            final K key = e.getKey();
            final String nameCandidate = serializedNames.get(key);
            final String serializedName = nameCandidate != null ? nameCandidate : key.name();
            jsonObject.add(serializedName, context.serialize(e.getValue()));
        }
        return jsonObject;
    }

}

另请注意,上面的序列化程序仅处理SerializedName.value,而不关心SerializedName.alternate。输出:

  

{ “创建”: “项目”}

请注意,这仅适用于键,不会影响可能出现在序列化地图中作为值的枚举的@SerializedName。上面的示例也可以重新编写,以自动处理任何枚举,并且不要求在GsonBuilder中注册每个这样的地图或散列表(必须在每个@SerializedName重新分析serialize注释方法可能使用缓存机制),但它会为你设计一些选择。

答案 1 :(得分:1)

enableComplexMapKeySerialization选项添加到Gson实例时,您的代码按预期工作。

https://google.github.io/gson/apidocs/com/google/gson/GsonBuilder.html#enableComplexMapKeySerialization--

Gson gson = new GsonBuilder().enableComplexMapKeySerialization().create();