Reputation: 301
Facing issue while making call to retrieve a json response and parse it.
[
{
"name": "john doe",
"age": "24",
"address": "{\"state\":\"LA\",\"country\":\"US\"}"
}
]
Models:
Person.java
@Data
@NoArgsConstructor
@JsonIgnoreProperties(ignoreUnknown = true)
public class Person {
private String name;
private String age;
private Address address;
}
Address .java
@Data
@NoArgsConstructor
@JsonIgnoreProperties(ignoreUnknown = true)
public class Address {
private String state;
private String country;
}
Code to read this data,
ResponseEntity<List<Person>> response = restTemplate.exchange(builder.toUriString(), HttpMethod.GET,requestEntity,new ParameterizedTypeReference<List<Person>>() {});
However i get below exception,
RestClientException while invoking ABS ServiceError while extracting response for type
[java.util.List<com.bp.model.Person>]
and content type [application/json;charset=UTF-8]; nested exception is org.springframework.http.converter.HttpMessageNotReadableException: JSON parse error: Cannot construct instance ofcom.bp.model.Address
(although at least one Creator exists): no String-argument constructor/factory method to deserialize from String value ('{"state":"LA","country":"US"}'); nested exception is com.fasterxml.jackson.databind.exc.MismatchedInputException: Cannot construct instance ofcom.bp.model.Address
(although at least one Creator exists): no String-argument constructor/factory method to deserialize from String value ('{"state":"IN","brand":"anthem"}') at [Source: (PushbackInputStream); line: 1, column: 325] (through reference chain: java.util.ArrayList[0]->com.bp.model.Person["address"])
Upvotes: 16
Views: 99763
Reputation: 1199
JSON string to Map:
String json = "{"name":"mkyong", "age":"37"}";
Output {name=mkyong, age=37}
public static void main(String[] args) {
ObjectMapper mapper = new ObjectMapper();
String json = "{\"name\":\"mkyong\", \"age\":\"37\"}";
try {
// convert JSON string to Map
Map<String, String> map = mapper.readValue(json, Map.class);
// it works
//Map<String, String> map = mapper.readValue(json, new TypeReference<Map<String, String>>() {});
System.out.println(map);
} catch (IOException e) {
e.printStackTrace();
}
}
Map to JSON string:
{"name":"mkyong","age":"37"}
{
"name" : "mkyong",
"age" : "37"
}
public static void main(String[] args) {
ObjectMapper mapper = new ObjectMapper();
Map<String, String> map = new HashMap<>();
map.put("name", "mkyong");
map.put("age", "37");
try {
// convert map to JSON string
String json = mapper.writeValueAsString(map);
System.out.println(json); // compact-print
json = mapper.writerWithDefaultPrettyPrinter().writeValueAsString(map);
System.out.println(json); // pretty-print
} catch (JsonProcessingException e) {
e.printStackTrace();
}
}
In Jackson, we can use mapper.readValue(json, Map.class) to convert a JSON string to a Map. Dependency
<dependency> <groupId>com.fasterxml.jackson.core</groupId> <artifactId>jackson-databind</artifactId> <version>2.9.8</version> </dependency>
Upvotes: 1
Reputation: 1
Here we can try to set the values during runtime.
@JsonProperty("address")
public void setCustomAddress(String addressFromJson){
this.address = new Gson().fromJson(addressFromJson, Address.class);
}
Upvotes: 0
Reputation: 2639
The code is correct but there's a problem with the JSON. The address is a string and not a JSON object. For it to work, it would need to be something like:
"address": {"state": "LA", "country": "US"}
Without the outer quotes and the escape characters.
Upvotes: 17