使用 Jackson 实现不带注释的 toString()



我想使用 Jackson 来实现toString()以返回对象的 JSON 表示形式,但我不想在我的代码中使用任何 Jackson 注释。

我尝试了如下方式的实现:

public String toString()
{
Map<String,Object> ordered = ImmutableMap.<String, Object>builder().
put("createdAt", createdAt.toString()).
put("address", address.toString()).
build();
ObjectMapper om = new ObjectMapper();
om.enable(SerializationFeature.INDENT_OUTPUT);
try
{
return om.writeValueAsString(object);
}
catch (JsonProcessingException e)
{
// Unexpected
throw new AssertionError(e);
}
}

这适用于简单字段,但如果"地址"有自己的字段,则不要得到这个:

{
"address" : {
"value" : "AZ4RPBb1kSkH4RNewi4NXNkBu7BX9DmecJ",
"tag" : null
}

我得到这个输出:

{
"address" : "{n"value" : "AZ4RPBb1kSkH4RNewi4NXNkBu7BX9DmecJ",n        "tag" : null"
}

换句话说,地址值被视为字符串而不是JsonNode

澄清一下:

  • 一方面,我想控制如何将简单的类字段转换为字符串。我不想使用杰克逊的内置转换器。
  • 另一方面,对于复杂字段,将String值返回给杰克逊会导致错误的行为。

我相信我可以通过向所有类添加公共toJson()方法来解决此问题。该方法将返回一个Map<String, JsonNode>,其中值是简单字段的字符串节点和复杂字段的toJson()输出。不幸的是,这会用实现细节污染我的公共 API。

如何在不污染类的公共 API 的情况下实现所需的行为?

更新:我刚刚在 https://stackoverflow.com/a/9599585/14731 看到了一个有趣的答案......也许我可以将复杂字段的字符串值转换回JsonNode,然后再将它们传递给杰克逊。

我认为您应该在每个类中实现两种方法 - 一种用于转储数据,另一种用于从原始数据结构构建 JSON。你需要把它分开,否则每次封装嵌套的toString()调用时,你都会把它嵌套得越来越深。

举个例子:

class Address {
private BigDecimal yourField;
/* …cut… */
public Map<String, Object> toMap() {
Map<String, Object> raw = new HashMap<>();
raw.put("yourField", this.yourField.toPlainString());
/* more fields */
return raw;
}
@Override
public String toString() {
// add JSON processing exception handling, dropped for readability
return new ObjectMapper().writeValueAsString(this.toMap());
}
}
class Employee {
private Address address;
/* …cut… */
public Map<String, Object> toMap() {
Map<String, Object> raw = new HashMap<>();
raw.put("address", this.address.toMap());
/* more fields */
return raw;
}
@Override
public String toString() {
// add JSON processing exception handling, dropped for readability
return new ObjectMapper().writeValueAsString(this.toMap());
}
}

最新更新