Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Duplicate fields in JSON Response

I'm using Spring boot Jackson dependency and lombok in my project, and in response i'm getting duplicate fields because of underscore

This is my model class:

 @Getter
 @Setter
 @Accessors(chain = true)
 @NoArgsConstructor
 @ToString
 public class TcinDpciMapDTO {

 @JsonProperty(value = "tcin")
 private String tcin;
 @JsonProperty(value = "dpci")
 private String dpci;

 @JsonProperty(value = "is_primary_tcin_in_dpci_relation")
 private boolean is_primaryTcin = true;

 }

If i'm using underscore in is_primaryTcin field i'm getting below response with duplicate fields

 {
    "_primaryTcin": true,
    "tcin": "12345",
    "dpci": "12345",
    "is_primary_tcin_in_dpci_relation": true
 }

If i remove underscore from field isprimaryTcin then i'm getting correct response

{
    "tcin": "12345",
    "dpci": "12345",
    "is_primary_tcin_in_dpci_relation": true
}

Is this because of underscore? but underscore is prefered to use in variable names right?

like image 779
Deadpool Avatar asked Jan 27 '23 18:01

Deadpool


2 Answers

This is what your class look like after delomboking:

public class TcinDpciMapDTO {
    @JsonProperty("tcin")
    private String tcin;
    @JsonProperty("dpci")
    private String dpci;
    @JsonProperty("is_primary_tcin_in_dpci_relation")
    private boolean is_primaryTcin = true;

    public String getTcin() {
        return this.tcin;
    }

    public String getDpci() {
        return this.dpci;
    }

    public boolean is_primaryTcin() {
        return this.is_primaryTcin;
    }

    public TcinDpciMapDTO setTcin(String tcin) {
        this.tcin = tcin;
        return this;
    }

    public TcinDpciMapDTO setDpci(String dpci) {
        this.dpci = dpci;
        return this;
    }

    public TcinDpciMapDTO set_primaryTcin(boolean is_primaryTcin) {
        this.is_primaryTcin = is_primaryTcin;
        return this;
    }

    public TcinDpciMapDTO() {
    }

    public String toString() {
        return "TcinDpciMapDTO(tcin=" + this.getTcin() + ", dpci=" + this.getDpci() + ", is_primaryTcin=" + this.is_primaryTcin() + ")";
    }
}

If generated property name is not specified, Jackson generates it by stripping prefix is or get from the getter if using getter or by using Java field name if serializing field without using a getter. By default Jackson only uses getters during serialization. Because you put @JsonProperty on the fields, Jackson uses both fields and getters and checks if the field is already serialized by matching generated property name (this last part is my guess anyway) it does not recognize property generated from field is_primaryTcin and property generated from getter is_primaryTcin() as the same (one is internally named is_primaryTcin and the other _primaryTcin) - notice that if you rename is_primaryTcin to as_primaryTcin problem vanishes.

like image 148
Konrad Botor Avatar answered Jan 31 '23 07:01

Konrad Botor


When you use is_primaryTcin that is not using underscore, it's using a mix of both. You can fix it by using PropertyNamingStrategy.

If you do

...
@JsonNaming(PropertyNamingStrategy.LowerCaseWithUnderscoresStrategy.class)
public class TcinDpciMapDTO {
    private String tcin;
    private String dpci;
    private boolean isPrimaryTcinInDpciRelation = true;
}

The JSON output will be

{
    "tcin": "12345",
    "dpci": "12345",
    "is_primary_tcin_in_dpci_relation": true
}
like image 35
naturaljoin Avatar answered Jan 31 '23 08:01

naturaljoin