2013-10-15 2 views
3

Разве Jackson позволяет настроить, как он сериализует ключи EnumMap? Например, если у меня естьСегментация ключей Jackson EnumMap

public enum MyKey 
{ 
    ABC, DEF, XYZ; 

    public String getKey() 
    { 
     return "my-key-" + ordinal(); 
    } 
} 

и некоторые

public class MyObject 
{ 
    private final Map<MyKey,String> map = new EnumMap<>(MyKey.class); 

    public MyObject() 
    { 
     map.put(MyKey.ABC, "foo"); 
     map.put(MyKey.DEF, "bar"); 
     map.put(MyKey.XYZ, "baz"); 
    } 

    public Map<MyKey,String> getMap() 
    { 
     return map; 
    } 
} 

тогда Джексон будет сериализовать MyObject в

{"map":{"ABC":"foo","DEF":"bar","XYZ":"baz"}}.

Вместо этого, я хочу, чтобы сериализовать его как

{"map":{"my-key-0":"foo","my-key-1":"bar","my-key-2":"baz"}}. Я не хочу переопределять toString(), чтобы это работало. Это вообще возможно в Джексоне?

Я попытался сделать это:

public class MyKeySerializer extends JsonSerializer<MyKey> 
{ 
    @Override 
    public void serialize(MyKey value, JsonGenerator jgen, SerializerProvider provider) throws IOException, JsonProcessingException 
    { 
     jgen.writeString(value.getKey()); 
    } 
} 

затем добавить

public class MyObject 
{ 
    ... 

    @JsonSerialize(keyUsing = MyKeySerializer.class) 
    public Map<MyKey,String> getMap() 
    { 
     return map; 
    } 

    ... 
} 

, но это не удается с org.codehaus.jackson.JsonGenerationException: Can not write text value, expecting field name исключением.

Любые идеи ???

ответ

4

Использовать jgen.writeFieldName(value.getKey()); вместо jgen.writeString(value.getKey()); в MyKeySerializer. Как видно из сообщения об ошибке, Джексон ожидает, что вы будете писать имя поля (а не текст напрямую) при сериализации ключей.

Я пробовал это сделать, и получил ожидаемый результат. Надеюсь это поможет!

+0

Этот подход работает для HashMap, хотя в моем конкретном случае 'MyKey' является перечислением, и я фактически использую EnumMap. К сожалению, даже с этим обновленным сериализатором Jackson выводит имя enum() вместо использования его метода getId(), который я определил, даже если используется @JsonValue. Вы знаете другой подход, который может работать для EnumMap? – ManRow

+0

Можете ли вы разместить ссылку на свой код с 'enum's? Я преобразовал 'MyKey' (из предыдущего примера) в' enum' (с неповрежденным методом 'getKey'), и сериализованный вывод был таким же, как и раньше. – Jackall

+0

Но что, если вы используете «EnumMap» вместо HashMap? Я обновил свой код в исходном сообщении, чтобы отразить это. – ManRow