0

I am trying to Map a JSON response to a Java POJO which has a different field name from different API. I need an efficient way to do this reducing boilerplate codes.

I have tried mapping the JSON property field in Java POJO. However, the problem is I am fetching data from different sources.

Let's say I have below user class

    Class User{
       String name;
       String contact;
    }

The JSON I may receive from different sources can be

{"name": "ABC" , "contact": "123456"}

or
{"userName": "XYZ" , "mobileNo":"4354665"}

There may be more variations as we go on integrating more API's

Is there a way I can archive this? above is just a simple example

there could be more complex JSON object I may need to read. like List of User etc.

ShailendraChoudhary
  • 143
  • 1
  • 3
  • 10
  • Have you tried using the `@Entity` above `Class User` and `@JsonProperty` above each variable? – Prav Jun 29 '19 at 18:53
  • 1
    I am not sure if @JsonProperty can get coupled for different values like in my example I have JSON Property as "name" and "userName" from 2 different API. Also as I have stated earlier there are chances of integrating more API's. adding a JSON property for each integrated API on POJO will make it bulky. I need some sort of converter rather. It's ok for me to create a different converter for each integrated class but I need to make my code loosely coupled. – ShailendraChoudhary Jun 29 '19 at 19:03
  • one way I believe I can do it is get the response as String, then using Object mapper map it to its respective fields. Is there a better method than this? – ShailendraChoudhary Jun 29 '19 at 19:11
  • `@JsonAlias()` are the easiest way of doing it but that comes with the cost of your Entities are tightly coupled with the data sources. IMO writing object mapper per data source might be the cleanest option; that will leave you with code base coupled enough for it to work and also be completely decoupled from the data sources. I personally never needed to do this so I can't suggest any other way that you already know. – Prav Jun 29 '19 at 19:18

2 Answers2

2

You can use the @JsonAlias() to give the variable more than one JSON key binding.

@JsonAlias is introduced in Jackson 2.9 release. @JsonAlias defines one or more alternative names for a property to be accepted during deserialization i.e. setting JSON data to Java object. But at the time of serialization i.e. while getting JSON from Java object, only actual logical property name is used and not alias. @JsonAlias is defined as follows.

@Entity
Class User{

   @JsonProperty()
   @JsonAlias({"name", "userName"})
   String name;

   @JsonProperty()
   @JsonAlias({"contact", "mobileNo"})
   String contact;
}
Prav
  • 2,785
  • 1
  • 21
  • 30
0

You could use the @JsonSetter annotation like :

public class User{
    public String contact;
    public String name;

    @JsonSetter("name")
    public void setName(String name) {
      this.name = name;
    }

    @JsonSetter("userName")
    public void setName(String name) {
      this.name = name;
    }
}

Instead of directly mapping to an entity class , you should have a DTO object or model in between to map the json response. Then, you can convert that into any entity you may choose.If you are fetching the data from different sources , it means you are calling different endpoints, why don't you create different DTO 's for that.In that way even if one of the endpoints introduce a change , it won't affect the rest of the endpoint calls.

Vice-versa you could have different DTO objects being returned from the two endpoints instead of returning the same Entity class as well, that way you can have control over which attributes should be there in the response.

To reduce the boiler plate code, you could use library such as MAP STRUCT to enable conversion between entity and DTO objects easily

Read here about the advantages of using a DTO .

Ananthapadmanabhan
  • 5,706
  • 6
  • 22
  • 39