Map Nested JSON Objects to Java Classes with Spring RestTemplate
Asked Answered
D

8

14

I know this may be simple. However, I just can't get it to work.

So I am trying to use Spring RestTemplate to map my JSON data. I have following JSON response from a rest call.

{
  "message":"ok",
  "status":"ok",
  "data":[
      {"Name":"Yo",
       "Address":"100 Test Rd"},
      {...},
      {...}
   ]
}

And here is the class I am trying to map it to.

@JsonIgnoreProperties(ignoreUnknown = true)
public class Response implements Serializable {

  private String message;
  private String status;
  private List<Data> data;

  // I could also use a array instead
  // private Data[] data;
}

Here is my Data class:

@JsonIgnoreProperties(ignoreUnknown = true)
public class Data implements Serializable {

  private String Name;
  private String Address;
}

Here is the code I used to call RestTemplate:

public Reponse getResponse() {
    ResponseEntity<Reponse> responseEntity = restTemplate.getForEntity(Url, Reponse.class);

    return responseEntity.getBody();
}

Now here comes the problem. I was able to get "message" and "status", But when I try to log/print data, it shows null. Not exactly sure what's going on here. I really could use some help. Thanks.

Dysprosium answered 6/3, 2015 at 6:59 Comment(2)
i'm having the same issue did you find a solution for this?Avebury
DId you find any solution? thanks.Happy
A
5

I was having a similar issue with RestTemplate not mapping nested JSON objects to my class model also, after much frustration I decided to retrieve my JSON as a String(instead of converting directly to my target object) using RestTemplate and then use the google Gson library to convert my String to my target entity.

pom.xml

<dependency>
        <groupId>com.google.code.gson</groupId>
        <artifactId>gson</artifactId>
        <version>2.2.4</version>
    </dependency>

code to call RestTemplate:

 ResponseEntity<String> responseEntity = restTemplate.getForEntity(Url,String.class);
Gson gson = new GsonBuilder().create();
Response reponse = gson.fromJson(responseEntity , Response.class);

Unfortunately I was unable to find out why my nested objects were not mapped using RestTemplate the first place but I hope this workaround helps!

Antetype answered 22/1, 2017 at 14:24 Comment(1)
I removed the nested class and created another classParyavi
G
4

I had a similar issue when reading Json data from REST API using Rest Template. To resolve declare getters and setters for the List:

@JsonIgnoreProperties(ignoreUnknown = true)
public class Response implements Serializable {

  private String message;
  private String status;
  private List<Data> data;

 // getters and Setters for the list. 


}

The RestTemplate will internally map the values from the listarray to the corresponding array.

Giantism answered 22/7, 2017 at 20:4 Comment(0)
C
2

I ran into the same issue. Annotate with @JsonProperty:

@JsonIgnoreProperties(ignoreUnknown = true)
public class Data implements Serializable {

    @JsonProperty("Name")
    private String name;

    @JsonProperty("Address")
    private String address;

    // getters / setters for name and address

}

The fields of your Data class should now get populated, and you can name your fields independent of the JSON representation (e.g. name instead of Name).

Cowley answered 28/2, 2018 at 22:13 Comment(0)
P
1

Annotate property "data" with @JsonUnwrapped as below

@JsonIgnoreProperties(ignoreUnknown = true)
public class Response implements Serializable {
    private String message;
    private String status;
    @JsonUnwrapped
    private List<Data> data;
}
Peccable answered 22/8, 2017 at 13:53 Comment(0)
I
1

I know this is an old thread.

But for anyone having the same problem, you can use MappingJackson2HttpMessageConverter for this purpose with Jackson.

Please refer the answer given in this thread.

Ikhnaton answered 11/4, 2019 at 13:29 Comment(0)
B
1

Change this

private String message; private String status; private List<Data> data;

To This

public String message; public String status; public List<Data> data;

That worked for me !

Bonucci answered 8/12, 2021 at 7:40 Comment(0)
K
0

Please use private List<Data> data = new AllarList<Data>( ); and please provide getters( ) and setters( ) methods in both the classes.

Put @JsonInclude(Include.NON_EMPTY) above Data class

Please add below dependencies under section at your main POM.xml file and do maven compile. Then I guess your issue will get resolved.

        <dependency>
            <groupId>com.fasterxml.jackson.core</groupId>
            <artifactId>jackson-annotations</artifactId>
            <version>2.2.3</version>
        </dependency>

        <dependency>
            <groupId>com.fasterxml.jackson.core</groupId>
            <artifactId>jackson-databind</artifactId>
            <version>2.2.3</version>
        </dependency>

        <dependency>
            <groupId>com.fasterxml.jackson.datatype</groupId>
            <artifactId>jackson-datatype-joda</artifactId>
            <version>2.1.1</version>
        </dependency>

        <dependency>
            <groupId>org.codehaus.jackson</groupId>
            <artifactId>jackson-mapper-asl</artifactId>
            <version>1.8.8</version>
        </dependency>
Knapweed answered 6/3, 2015 at 7:8 Comment(2)
I didn't put up setters and getters here to avoid messes. Tried to initialize "data". Still returns null. Also compile error on "Include.NON_EMPTY", "Include cannot be resolved to a variable"? Thanks.Dysprosium
please import this : import com.fasterxml.jackson.annotation.JsonInclude;Knapweed
P
-1

If you need only print data, you can do this

RestTemplate restTemplate = new RestTemplate();
ResponseEntity<String> response = restTemplate.getForEntity(
    "your url",
    String.class);

System.out.println(response);
Pipsissewa answered 27/3, 2016 at 7:9 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.