java – 杰克逊序列化.强制将每个字段包装为对象

我知道类似的问题已经是
asked了.但是这个解决方案并不适合我.

我有两个POJO,有很多字段:

@JsonInclude(JsonInclude.Include.NON_NULL)
public class Profile {

    @JsonProperty("userAttrs")
    private List<UserAttr> userAttrs;

}

@JsonInclude(JsonInclude.Include.NON_NULL)
public class UserAttr {

  @JsonProperty("ordercode")
  private String ordercode;

  @JsonProperty("transactionid")
  private String transactionid;

  @JsonProperty("receiptno")
  private String receiptno;

  // A lot more fields

杰克逊按预期生产JSON:

"profile" : {
  "userAttrs" : [ {
    "ordercode" : 123,
    "transactionid" : 12345,
    "reference" : 123456789,
    "orderpaymenttypecode" : 1231341,
    ... more properties ...
  } ]
}

但是我需要将每个属性包装为JSON对象.像这样的东西:

"profile" : {
  "userAttrs" : [ 
    {"ordercode" : 123},
    {"transactionid" : 12345},
    {"reference" : 123456789},
    {"orderpaymenttypecode" : 1231341},
    ... more properties ...
  ]
}

我不想为每个字段创建单独的POJO.另一种方法是为每个字段创建Map,但这是一个糟糕的决定.

也许有其他方法可以做到这一点?

最佳答案 我认为您尝试使用的Jackson数据库模块旨在将JSON文档和Java类绑定到相同的结构.由于我信任的重要原因,您需要一个具有不同结构的JSON文档,多个单字段对象而不是Java类中的单个多字段对象.我认为你不应该在这种情况下使用数据绑定.即使自定义序列化程序解决了这个问题,这也不是它的预期用途.

您可以通过获取树来获取所需的JSON,将其重新整形为所需的结构并对修改后的树进行处理.假设你有ObjectMapper映射器和Profile配置文件,你可以这样做:

JsonNode profileRoot = mapper.valueToTree(profile);
ArrayNode userAttrs = (ArrayNode) profileRoot.get("userAttrs");
userAttrs.get(0).fields().forEachRemaining(userAttrs::addPOJO);
userAttrs.remove(0); // remove original multi-field object

然后,当您使用以下内容序列化时:

mapper.writeValueAsString(profileRoot)

你会在你的问题中得到JSON

点赞