Ashish
Ashish

Reputation: 341

Handling different JSON Request Jackson

I am working in a project where I need to send a request to remote service with 2 different formats

Format 1:

{
"templateId": "template1",
"configurationData": {
   "inboundHeaders": [
     {
      "key": "header1",
      "value": "value1"
     }, {
      "key": "header2",
      "value": "value2"
     }, {
      "key": "header3",
      "value": "value3"
     }
    ],
    "outboundHeaders": [
     {
      "key": "header4",
      "value": "value4"
     }, {
      "key": "header5",
      "value": "value5"
     }, {
      "key": "header6",
      "value": "value6"
     }
    ]
}
}

Format 2

{
    "templateId": "template1",
    "configurationData": {
           "inboundHeaders": "head1",
           "outboundHeaders" : "head2,head3"
        }
}

Now I have created one class

@JsonPropertyOrder({ "inboundHeaders", "outboundHeaders"})

public class ConfigurationData {

@JsonProperty("inboundHeaders")
private List<Header> inboundHeaders = null;

@JsonIgnore
@JsonProperty("outboundHeaders")
private List<Header> outboundHeaders = null;

@JsonProperty("inboundHeaders")
private String inboundHeader = null;

@JsonProperty("outboundHeaders")
private String outboundHeader = null;

}

Getters and Setters would go here....

But when I am executing this program. Obviously, I am getting following exception like

com.fasterxml.jackson.databind.JsonMappingException: Multiple fields representing property

How to handle these two different version (java.util.List vs java.lang.String) of requests in one Json POJO?

Upvotes: 2

Views: 332

Answers (3)

pirho
pirho

Reputation: 12215

The answer from Francisco Pérez is absolutely correct but you later clarified your question. The possibilities to limit new classes are - well - limited. You either need to create a class representinng each different DTO or make some sort of manual serializing.

One thing you can do is that you create an interface for different types of configuration data DTOs, so just:

interface IConfigurationData {}

then you have this template create or change it so that configurationData is of type tha interface:

@Getter @Setter
public class Template {
    private String templateId;
    private IConfigurationData configurationData;
}

Then using the DTO classes in above mentioned answer let them implement this interface, like:

public class ConfigurationDataLists implements IConfigurationData {...}

and

public class ConfigurationDataString implements IConfigurationData {...}

Then you will be able to do two different queries like this:

Template template1 = new Template();
template1.setTemplateId("1");
template1.setConfigurationData(new ConfigurationDataLists());

Template template2 = new Template();
template2.setTemplateId("2");
template2.setConfigurationData(new ConfigurationDataString());

Upvotes: 1

Francisco P&#233;rez
Francisco P&#233;rez

Reputation: 537

I think you have two options.

  1. Create two classes and two methods to call remote service like:

Lists:

@JsonPropertyOrder({ "inboundHeaders", "outboundHeaders"})
public class ConfigurationDataLists {
    @JsonProperty("inboundHeaders")
    private List<Header> inboundHeaders = null;

    @JsonIgnore
    @JsonProperty("outboundHeaders")
    private List<Header> outboundHeaders = null;
}

Strings:

@JsonPropertyOrder({ "inboundHeaders", "outboundHeaders"})
public class ConfigurationDataString {
    @JsonProperty("inboundHeaders")
    private String inboundHeader = null;

    @JsonProperty("outboundHeaders")
    private String outboundHeader = null;
}
  1. Use Map

I will prefer option 1.

Upvotes: 3

Atul
Atul

Reputation: 3357

You cannot use the same name to different properties like you did. E.g. - inboundHeaders.

You have to change one of the propertyname. In simple words you have to keep the @JsonProperty unique.

Upvotes: 0

Related Questions