Jackson:使用类方法序列化POJO

时间:2018-04-13 14:57:30

标签: java spring jackson

我知道我可以使用(new ObjectMapper()).convertValue(this, ObjectNode.class)将给定对象序列化为JSON。有没有办法告诉lib使用该类中的方法来序列化它?

我的课程:

interface A {
  ObjectNode toJSON();
}

abstract class Tokens {
  Map<String, String> tokends;
}

class Foo extends Tokens implements A {
  private long id;
  private Bar bar;

  // Constructors, getters & setters...

  @Override
  public ObjectNode toJSON() {
    ObjectNode node = (new ObjectMapper()).convertValue(this, ObjectNode.class);
    tokens.forEach(node::put);

    return node;
  }
}

class Bar extends Tokens implements A {
  private long id;

  // Constructors, getters & setters...

  @Override
  public ObjectNode toJSON() {
    ObjectNode node = (new ObjectMapper()).convertValue(this, ObjectNode.class);
    tokens.forEach(node::put);

    return node;
  }
}

现在,如果我致电(new A()).toJSON(),我会得到:

{
  "id": 1,
  "bar": {
    "id": 2
  },
  "token1": "...",
  "token2": "...:,
}

而不是:

{
  "id": 1,
  "bar": {
    "id": 2,
    "token3": "...",
    "token4": "..."
  },
  "token1": "...",
  "token2": "...:,
}

我知道这是因为第一个方法修改了序列化类,但是当它进入子对象时不被jackson调用。

有没有办法告诉jaskson使用toJSON方法创建带有令牌的孩子?

2 个答案:

答案 0 :(得分:2)

采用稍微不同的方法,@JsonAnyGetter提供了一种直接在父JSON中包含tokens地图的键的方法:

abstract class Tokens {
    Map<String, String> tokens = new LinkedHashMap<>();

    @JsonAnyGetter
    public Map<String, String> getTokens() {
        return tokens;
    }

    @JsonAnySetter
    public void addToken(String key, String value) {
        tokens.put(key, value);
    }

}

然后如:

new ObjectMapper().writeValueAsString(foo);

返回:

{
  "id" : 1,
  "bar" : {
    "id" : 2,
    "token3" : "three",
    "token4" : "four"
  },
  "token1" : "one",
  "token2" : "two"
}

答案 1 :(得分:0)

@com.fasterxml.jackson.annotation.JsonValue方法上尝试杰克逊注释toJSON()。来自javadoc:

  

类似于javax.xml.bind.annotation.XmlValue的标记注释,指示带注释的&#34; getter&#34;的结果。方法(表示签名必须是getter;非void返回类型,无args)将用作实例序列化的单个值。通常,value将是一个简单的标量类型(String或Number),但它可以是任何可序列化的类型(Collection,Map或Bean)。