简体   繁体   English

杰克逊:使用类方法序列化POJO

[英]Jackson: Serialise POJO using class method

I know I can use (new ObjectMapper()).convertValue(this, ObjectNode.class) to serialise given object to JSON . 我知道我可以使用(new ObjectMapper()).convertValue(this, ObjectNode.class)将给定对象序列化为JSON Is there a way to tell the lib to use a method inside that class to serialise it ? 有没有办法告诉lib使用该类内部的方法来序列化它?

My classes: 我的课程:

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;
  }
}

Now if I call (new A()).toJSON() I will get: 现在,如果我调用(new A()).toJSON()我将得到:

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

Instead of: 代替:

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

I understand that this happens because the first method modifies the serialised class but is not called by jackson when it goes into child objects. 我知道发生这种情况是因为第一种方法会修改序列化的类,但杰克逊在进入子对象时不会调用它。

Is there a way to tell jaskson to use toJSON method to create the child with tokens as well ? 有没有办法告诉jaskson也使用toJSON方法来创建带有令牌的子对象?

To take a slightly different approach, @JsonAnyGetter provides a way to include the keys of the tokens map directly in the parent JSON: 为了采取稍微不同的方法, @ JsonAnyGetter提供了一种将tokens映射的键直接包含在父JSON中的方法:

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);
    }

}

Then such as: 然后如:

new ObjectMapper().writeValueAsString(foo);

returns: 收益:

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

Try the Jackson annotation @com.fasterxml.jackson.annotation.JsonValue on your toJSON() method. toJSON()方法上尝试Jackson注释@com.fasterxml.jackson.annotation.JsonValue From the javadoc : 从javadoc:

Marker annotation similar to javax.xml.bind.annotation.XmlValue that indicates that results of the annotated "getter" method (which means signature must be that of getters; non-void return type, no args) is to be used as the single value to serialize for the instance. 类似于javax.xml.bind.annotation.XmlValue的标记注释,它指示将带注释的“ getter”方法的结果(这意味着签名必须是getter的结果;非无效返回类型,无args)将作为单个实例序列化的值。 Usually value will be of a simple scalar type (String or Number), but it can be any serializable type (Collection, Map or Bean). 通常,值将是简单的标量类型(字符串或数字),但也可以是任何可序列化的类型(集合,映射或Bean)。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM