2015-07-09 6 views
2

Если класс расширяет карту и включает в себя дополнительные поля. E.G - последняя измененная дата, Джексон, похоже, игнорирует любую вещь, не содержащуюся в качестве свойства карты.Карта сериала Джексона с дополнительными полями

У меня есть класс, который выглядит некоторые вещи, как следующее:

import java.io.IOException; 
import java.time.OffsetDateTime; 
import java.util.HashMap; 
import java.util.Objects; 

import com.fasterxml.jackson.databind.ObjectMapper; 

public class Foo extends HashMap<String, String> { 

    private OffsetDateTime lastModifiedTime; 

    public Foo() { 
     super(); 
     lastModifiedTime = OffsetDateTime.now(); 
    } 

    public void setLastModifiedTime(OffsetDateTime newTime) { 
     this.lastModifiedTime = newTime; 
    } 

    public OffsetDateTime getLastModifiedTime() { 
     return this.lastModifiedTime; 
    } 

    public static void main(String[] args) throws IOException { 
     Foo f = new Foo(); 
     f.put("hello", "world"); 

     ObjectMapper om = new ObjectMapper(); 
     om.findAndRegisterModules(); 

     String result = om.writeValueAsString(f); 
     if(f.equals(om.readValue(result, Foo.class))) { 
     System.out.println("Wooo"); 
     } else { 
     System.out.println("Booo: " + result); 
     } 

    } 

    @Override 
    public boolean equals(Object obj) { 
     if (this == obj) { 
     return true; 
     } 
     if (!(obj instanceof Foo)) { 
     return false; 
     } 
     if (!super.equals(obj)) { 
     return false; 
     } 
     Foo foo = (Foo) obj; 
     return Objects.equals(getLastModifiedTime(), foo.getLastModifiedTime()); 
    } 

    @Override 
    public int hashCode() { 
     return Objects.hash(super.hashCode(), getLastModifiedTime()); 
    } 

} 

Когда это работает выводит booo: {"hello":"world"} Что не включает в себя дату последнего изменения.

Я попытался добавить @JsonInclude аннотации к свойству и геттерам, но это не приводит к добавлению дополнительного поля.

Каков правильный способ заставить Джексона включить это дополнительное поле?

+2

Не распространяйте HashMap. Создайте класс, в котором ** есть ** Карта и дополнительное поле вместо расширения HashMap. –

+1

[Например] (http://stackoverflow.com/a/31307233/2587435) –

+0

@JBNizet Ah, который работает. Был надеяться на аннотацию, чтобы избежать необходимости реализации ряда дополнительных методов (размер, пусто и т. Д.). Если кто-то из вас захочет выразить это как ответ, я соглашусь с ним. –

ответ

2

Это обычно считается плохой практикой продлить HashMap. Вместо этого вы должны создать класс, который имеет a Карта и дополнительное поле.

Это позволит решить вашу проблему, но также будет иметь дополнительные преимущества:

  • вы сможете инкапсулировать правила (например, предотвращая некоторые ключи/значения будут добавлены и т.д.)
  • вы будете быть в состоянии изменить реализацию карт, если это необходимо (LinkedHashMap, синхронизированный карта, параллельная карта)
1

По умолчанию ваша карта упадет до MapSerializer. Вы можете зарегистрировать модификатор сериализатора, чтобы добавить пользовательское свойство, но вы бы лучше вложенности карту как свойство Foo и разворачивая его:

@JsonUnwrapped 
private HashMap<String, String> fooMap; 
0

Вместо @JsonUnwrapped, вы можете использовать @JsonAnyGetter и @JsonAnySetter вроде этого:

public class Foo { 

    private OffsetDateTime lastModifiedTime; 
    private HashMap<String, String> additionalProperties = new HashMap<String, String>(); 

    public Foo() { 
     super(); 
     lastModifiedTime = OffsetDateTime.now(); 
    } 

    public void setLastModifiedTime(OffsetDateTime newTime) { 
     this.lastModifiedTime = newTime; 
    } 

    public OffsetDateTime getLastModifiedTime() { 
     return this.lastModifiedTime; 
    } 

    @JsonAnyGetter 
    public Map<String, String> any() { 
     return this.additionalProperties; 
    } 

    @JsonAnySetter 
    public void set(String name, String value) { 
     this.additionalProperties.put(name, value); 
    } 
} 
Смежные вопросы