Dmitry K
Dmitry K

Reputation: 1312

Jackson serialization. Force to wrap each field as object

I know that similar question was already asked. But that solution don't suit me.

I have two POJOs with quite a lot of fields:

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

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

}

And

@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

Jackson produces JSON as expected:

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

However I need to wrap each property as JSON Object. Something like this:

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

I don't want to create separate POJO for every field. The other way is to create Map for every field, but this is a bad decision.

Maybe there are some other ways to do it?

Upvotes: 5

Views: 1360

Answers (1)

Manos Nikolaidis
Manos Nikolaidis

Reputation: 22254

The Jackson databind module, that I presume you tried to use, is meant to bind JSON documents and Java classes with the same structure. For reasons that I trust are important, you want a JSON document with a different structure, multiple single-field objects instead of a single multi-field object as you have in the Java class. I'd argue you shouldn't use databind in this case. That's not its intended use even if a custom serializer solves the problem.

You can get the JSON you want by obtaining a tree, reshaping it to the desired structure and serliazing the modified tree. Assuming you have ObjectMapper mapper and Profile profile you can do:

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

When you then serialize with something like:

mapper.writeValueAsString(profileRoot)

you'll get the JSON in your question

Upvotes: 1

Related Questions