Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to map json response object to a preferred format using Jackson / other library?

I am getting the below JSON response format from a third party web service:

{
    "meta": {
        "code": 200,
        "requestId": "1"
    },
    "response": {
        "locations": [
            {
                "id": "1",
                "name": "XXX",
                "contact": {
                    phone: '123',
                    email: 'abc'
                },
                "location": {
                    "address": [
                        "Finland"
                    ]
                }
            },
            {
                // another location
            }
        ]
    }
}

And here is what I should return as a response from my own web service:

[
    {
        "id": "1",
        "name": "XXX",
        "phone": '123',
        "address": "Finland"
    },
    {
        // another location
    }
]

What should I do? I've read some good stuff about Jackson but there are only a few simple examples where you map some simple JSON obj as is to POJO. In my case, I need to remove a few nodes, and also traverse deeper down the hierarchy to get the nested value. This is my baby step so far in my spring boot app:

    @GET
    @Path("{query}")
    @Produces("application/json")
    public String getVenues(@PathParam("query") String query){
        return client.target(url).queryParam("query",query).request(...).get(String.class)
    }

Any helps, pointers, recommendations are welcomed!

like image 947
Great Question Avatar asked Sep 25 '22 11:09

Great Question


1 Answers

You are using JAX-RS annotations instead of the Spring web service annotations. You can make this work, but I would recommend going with the default Spring annotations because those are all autoconfigured for you if you're using the spring boot starter dependencies.

First thing - you need to create classes that are set up like the request and response. Something like this:

public class ThirdPartyResponse {   
    MetaData meta;
    Response response;
}

public class Response {
    List<Location> locations;
}

public class MetaData {
    String code;
    String requestId;    
}

public class Location {
    String id;
    String name;
    Contact contact;
    LocationDetails location;
}

public class Contact {
    String phone;
    String email;
}

public class LocationDetails {
    List<String> address;
}

You can use Jackson annotations to customize the deserialization, but by default it maps pretty logically to fields by name and the types you might expect (a JSON list named "locations" gets mapped to a List in your object named "locations", etc).

Next you'll want to use a @RestController annotated class for your service, which makes the service call to the third party service using RestTemplate, something like:

@RestController
public class Controller {

    @Value("${url}")
    String url;

    @RequestMapping("/path"
            method = RequestMethod.GET,
            produces = MediaType.APPLICATION_JSON_VALUE)
    public List<Location> locations(@RequestParam String query) {

        // RestTemplate will make the service call and handle the 
        // mapping from JSON to Java object

        RestTemplate restTemplate = new RestTemplate();
        ThirdPartyResponse response = restTemplate.getForObject(url, ThirdPartyResponse.class);

        List<Location> myResponse = new List<>();            

        // ... do whatever processing you need here ...

        // this response will be serialized as JSON "automatically"
        return myResponse;
    }
}

As you can see, Spring Boot abstracts away a lot of the JSON processing and makes it pretty painless.

Take a look at Spring's guides which are pretty helpful:

Consuming a service with RestTemplate http://spring.io/guides/gs/consuming-rest/

Creating a web service using @RestController https://spring.io/guides/gs/rest-service/

like image 144
nerdherd Avatar answered Oct 16 '22 09:10

nerdherd