杰克逊序列化地图与额外的字段

时间:2015-07-09 14:49:43

标签: java json jackson

如果一个类扩展了Map并包含一些额外的字段。 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注释添加到属性和getter中,但这并不会导致它包含额外字段。

让杰克逊包括这个额外领域的正确方法是什么?

3 个答案:

答案 0 :(得分:4)

扩展HashMap通常被认为是不好的做法。相反,您应该创建一个具有地图的类,以及附加字段。

这将解决您的问题,但也有其他优势:

  • 您将能够封装规则(例如阻止添加某些键/值等)。
  • 如果需要,您将能够更改Map实现(LinkedHashMap,同步地图,并发地图)

答案 1 :(得分:3)

默认情况下,您的地图会落入MapSerializer。您可以注册一个序列化修饰符来添加自定义属性,但最好将地图嵌套为Foo的属性并将其展开:

@JsonUnwrapped
private HashMap<String, String> fooMap;

答案 2 :(得分: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); } }

analysis1.py