Have the following sets of json from a third party API : First type:
{
"mandateAuthDtls": {
"transactionID": "<Transaction ID>",
"mndtType": "< AMEND / CANCEL / SUSPEND/ REVOKE /CUSTOM_CANCEL>",
"mandateRequestDtl": {
"MandateReqDoc": "<Encrypted and Signed request XML>",
},
/*SUBCLASS INFORMATION STARTS HERE*/
"authMode": "PAN",
"panInfo": {
"pan": "<Encrypted PAN>”
}
}
}
Second Type:
{
"mandateAuthDtls": {
"transactionID": "<Transaction ID>",
"mndtType": "<AMEND / CANCEL / SUSPEND/ REVOKE /CUSTOM_CANCEL>",
"mandateRequestDtl": {
"MandateReqDoc": "<Encrypted and Signed request XML>",
},
/*SUBCLASS INFORMATION STARTS HERE*/
"authMode": "custid",
"custidInfo": {
"custid": "<Encrypted custid>”
}
}
}
The highlighted is the difference (these comments are not actually part of the JSON). I would like to leverage Jackson Subtypes to write cleaner code.
This is my code:
Top Level: MandateAuthDtls
:
@Data
@Builder
@Jacksonized
@JsonFormat(with = JsonFormat.Feature.ACCEPT_CASE_INSENSITIVE_PROPERTIES)
public class MandateAuthDtls {
@JsonProperty("transactionID")
private String transactionID;
@JsonProperty("mandateType")
private String mandateType;
@JsonProperty("mandateRequestDtl")
private MandateRequestDtl mandateRequestDtl;
@JsonProperty("authMode")
private String authMode;
//@JsonProperty
private AuthInfo authInfo;
}
@JsonTypeInfo(
use = JsonTypeInfo.Id.NAME,
include = JsonTypeInfo.As.EXTERNAL_PROPERTY,
property = "authMode",
defaultImpl = CardInfo.class,
visible = true
)
@JsonSubTypes({
@JsonSubTypes.Type(value = AadharInfo.class, name = "Aadhaar"),
@JsonSubTypes.Type(value = CustIDInfo.class, name = "custid"),
@JsonSubTypes.Type(value = PanInfo.class, name = "PAN")
})
public abstract class AuthInfo {
}
Derived Class:
@JsonTypeName("PAN")
public class PanInfo extends AuthInfo {
@JsonProperty("Pan")
private String pan;
public String getPan() {
return pan;
}
public void setPan(String pan) {
this.pan = pan;
}
}
when Spring Boot ( 3.3.2) ,Jackson 2.17.2, de-serializes first type JSON MandateAuthDtls.AuthInfo
is always null
. My expectation is it should be PanInfo
type.
Can I use the Subtypes
feature of Jackson to handle the above scenario of the 2 JSONs?
If not any better approach?
The problem is that "panInfo" is an object field so you need to define the relevant json object type. Here is an example.
@JsonTypeInfo(
...
)
@JsonSubTypes({
...
@JsonSubTypes.Type(value = PanInfoWrapper.class, name = "PAN")
})
public abstract class AuthInfo { }
public class PanInfo {
private String pan;
...
}
public class PanInfoWrapper extends AuthInfo {
private PanInfo panInfo;
}
For better readability, you can write inner class.