、カスタムJsonSerializer
を使用することができますMap
またはHashtable
などの使用データの袋:タイプのトークンがより正確にシリアライズ可能な列挙型を対象とし、内部のシリアル化された名前のマッピングをキャッシュするために使用されていることを
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
に登録する必要はありません(serialize
メソッドではおそらくキャッシング機構を使用して@SerializedName
のアノテーションを再解析する必要があります)あなたのためのデザインの選択。
フィールドの値が列挙型の場合はどうなりますか? (また、 'Hashtable'はほとんど新しいコードで使われるべきではなく、おそらく' HashMap'が必要です。) – chrylis
別のクラスのフィールドとしてenumを使うと動作します。シリアル化関数は、列挙型を小文字に変換します。 Btw、私は既存のコードで作業しているので、ハッシュマップをハッシュマップに変更するとコードが壊れる可能性があるので、今は触れません。 – itaied
マップキーとして '@ SerializedName'を使うことに特有の問題があるようですね? – chrylis