prakharjain
prakharjain

Reputation: 274

Create custom annotations for different output from same POJO class

So I have a POJO class, which maps a json document (that I receive) to java object.

@JsonInclude(JsonInclude.Include.NON_EMPTY)
@JsonAutoDetect(fieldVisibility = ANY, getterVisibility = NONE, setterVisibility = NONE)
public class Product implements Serializable, UniqueKeyAware {

    private static final long serialVersionUID = -7311148654827944888L;

    @JsonIgnore
    private String uniqueKey;

    @JsonProperty("uniqueKey")
    private String uniqueKeyV2;

    @JsonProperty("gtin")
    private String gtin;

    @JsonProperty("printedGtin")
    private String printedGtin;

    @JsonProperty("tpnb")
    private String tpnb;

    @JsonProperty("tpnc")
    private String tpnc;

    @JsonProperty("tpna")
    private String tpna;

    @JsonProperty("itemNumber")
    private String itemNumber;

    @JsonProperty("catId")
    private String catId;

    @JsonProperty("styleCode")
    private String styleCode;

    @JsonProperty("description")
    private String description;

    @JsonProperty("brand")
    private String brand;

    @JsonProperty("isOwnLabel")
    private Boolean isOwnLabel;

    @JsonProperty("regulatedProductName")
    private String regulatedProductName;

    @JsonProperty("country")
    private List<Country> region;

    ... // remove for simplicity

What I want is the best way to create 4 separate documents out of the json.

So, lets define 4 class which are subsets of this pojo class.

For configurability purpose, I need custom annotations like @public, @private, @partner, @priviledge which I will write above every field. And in runtime, if I specify for e.g. public class, the instance will be created for only those fields above which @public annotations is written.

I need to implement this. I think this is possible by creating some hooks in jackson library. Please I need to do it in one day, can anyone just guide how to do this.

Final product should like this:

@JsonInclude(JsonInclude.Include.NON_EMPTY)
@JsonAutoDetect(fieldVisibility = ANY, getterVisibility = NONE, setterVisibility = NONE)
public class Product implements Serializable, UniqueKeyAware {

    private static final long serialVersionUID = -7311148654827944888L;

    @JsonIgnore
    private String uniqueKey;

    @JsonProperty("uniqueKey") @public @private
    private String uniqueKeyV2;

    @JsonProperty("gtin") @public
    private String gtin;

    @JsonProperty("printedGtin") @public
    private String printedGtin;

    @JsonProperty("tpnb")@private
    private String tpnb;

    @JsonProperty("tpnc")@private
    private String tpnc;

    @JsonProperty("tpna")@priviledge
    private String tpna;

    ... // removed for simplicity

and in above e.g. @public instance will have uniqueKey, gtin, printedGtin as only attributes.

Upvotes: 1

Views: 417

Answers (1)

prakharjain
prakharjain

Reputation: 274

I found the solution. What we require was @JsonView annotation already present in jackson. We first need to create view class like this:

public class Views
{
    public static class Public{};
    public static class Partner extends Public{};
    public static class Priviledge extends Partner {};
    public static class Private extends Priviledge {};
}

Then, our main product class will be like this.

@JsonInclude(JsonInclude.Include.NON_EMPTY)
@JsonAutoDetect(fieldVisibility = ANY, getterVisibility = NONE, setterVisibility = NONE)
public class MyProduct implements Serializable, UniqueKeyAware {

    private static final long serialVersionUID = -7311148654827944888L;

    @JsonIgnore
    private String uniqueKey;

    @JsonProperty("uniqueKey")
    @JsonView(Views.Partner.class)
    private String uniqueKeyV2;

    @JsonProperty("gtin")
    @JsonView(Views.Public.class)
    private String gtin;

    @JsonProperty("printedGtin")
    @JsonView(Views.Public.class)
    private String printedGtin;

    @JsonProperty("tpnb")
    @JsonView(Views.Public.class)
    private String tpnb;

    // skipped other attributes and getter setter

Main function will look like:

ObjectMapper mapper = new ObjectMapper();
MyProduct product = mapper.readerWithView(Views.Public.class).forType(MyProduct.class).readValue(json)

Upvotes: 1

Related Questions