【发布时间】:2018-12-01 08:24:17
【问题描述】:
我想使用 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。
澄清一下:
- 一方面,我想控制简单的类字段如何转换为字符串。我不想使用 Jackson 的内置转换器。
- 另一方面,对于复杂字段,将
String值返回给 Jackson 会导致错误行为。
我相信我可以通过在我的所有课程中添加公共toJson() 方法来解决这个问题。该方法将返回一个Map<String, JsonNode>,其中值是简单字段的字符串节点和复杂字段的toJson() 的输出。不幸的是,这会污染我的公共 API 的实现细节。
如何在不污染类的公共 API 的情况下实现所需的行为?
更新:我刚刚在https://stackoverflow.com/a/9599585/14731 看到了一个有趣的答案...也许我可以将复杂字段的字符串值转换回JsonNode,然后再将它们传递给Jackson。
【问题讨论】:
-
问题是您的地图存储的是字符串,而不是对象。存储在那里的字符串是
{\n\"value\" : \"AZ4RPBb1kSkH4RNewi4NXNkBu7BX9DmecJ\",\n \"tag\" : null... -
@LuiggiMendoza 我理解,但我不想让杰克逊将对象转换为字符串。我已经用这个澄清更新了这个问题。
-
我还是不明白你的目的。根据描述,您不想使用
put("address", address),而是以某种方式继续使用put("address", address.toString())。也许您可以添加地图而不是您的对象,例如put("address", ImmutableMap.<String, Object>builder().put("value", address.getValue()). put("tag", address.getTag()).build())。 -
@LuiggiMendoza 对于简单的字段,我想直接控制转换。对于某些字段,我调用
String.value()。对于像BigDecimal这样的其他人,我调用BigDecimal.toPlainString()。对于复杂的字段,我希望它们能够控制自己的转换,因此我需要它们返回一些值,我可以不加修改地传递给 Jackson。