I have the following JSON object and I want to deserialize it using Google's GSON library. Unfortunately I am unable to get the list correctly. GSON finds the first list entry but not the second.
This is the code I use for invoking GSON:
Mentions result = gson.fromJson(response, Mentions.class);
Here is my JSON File:
{
"mentions": [
{
"allEntities": [
{
"kbIdentifier": "YAGO:Bob_Dylan",
"disambiguationScore": "0.63692"
}
],
"name": "Dylan",
"bestEntity": {
"kbIdentifier": "YAGO:Bob_Dylan",
"disambiguationScore": "0.63692"
}
},
{
"name": "Duluth",
"bestEntity": {
"kbIdentifier": "YAGO:Duluth\\u002c_Minnesota",
"disambiguationScore": "0.63149"
}
}
]
}
And these are the plain old java objects I have created:
public class Mentions {
public List<Mention> mentions = new ArrayList<>();
}
public class Mention {
#SerializedName("bestEntity")
public BestEntity entity;
#SerializedName("name")
public String name;
}
public class BestEntity {
#SerializedName("kbIdentifier")
public String kbIdentifier;
#SerializedName("disambiguationScore")
public Double disambiguationScore;
}
I also tried directly deserializing the list, but it just gives me an error, saying that GSON expects the list to start at the beginning of the input.
Type datasetListType = new TypeToken<Collection<Mention>>() {
}.getType();
List<Mention> mentions = gson.fromJson(response, datasetListType);
Try this -
AllEntity.java
import com.google.gson.annotations.Expose;
import com.google.gson.annotations.SerializedName;
public class AllEntity {
#SerializedName("kbIdentifier")
#Expose
private String kbIdentifier;
#SerializedName("disambiguationScore")
#Expose
private String disambiguationScore;
public String getKbIdentifier() {
return kbIdentifier;
}
public void setKbIdentifier(String kbIdentifier) {
this.kbIdentifier = kbIdentifier;
}
public String getDisambiguationScore() {
return disambiguationScore;
}
public void setDisambiguationScore(String disambiguationScore) {
this.disambiguationScore = disambiguationScore;
}
#Override
public String toString() {
return "AllEntity [kbIdentifier=" + kbIdentifier
+ ", disambiguationScore=" + disambiguationScore + "]";
}
}
BestEntity.java
import com.google.gson.annotations.Expose;
import com.google.gson.annotations.SerializedName;
public class BestEntity {
#SerializedName("kbIdentifier")
#Expose
private String kbIdentifier;
#SerializedName("disambiguationScore")
#Expose
private String disambiguationScore;
public String getKbIdentifier() {
return kbIdentifier;
}
public void setKbIdentifier(String kbIdentifier) {
this.kbIdentifier = kbIdentifier;
}
public String getDisambiguationScore() {
return disambiguationScore;
}
public void setDisambiguationScore(String disambiguationScore) {
this.disambiguationScore = disambiguationScore;
}
#Override
public String toString() {
return "BestEntity [kbIdentifier=" + kbIdentifier
+ ", disambiguationScore=" + disambiguationScore + "]";
}
}
Mention.java
import java.util.ArrayList;
import java.util.List;
import com.google.gson.annotations.Expose;
import com.google.gson.annotations.SerializedName;
public class Mention {
#SerializedName("allEntities")
#Expose
private List<AllEntity> allEntities = new ArrayList<AllEntity>();
#SerializedName("name")
#Expose
private String name;
#SerializedName("bestEntity")
#Expose
private BestEntity bestEntity;
public List<AllEntity> getAllEntities() {
return allEntities;
}
public void setAllEntities(List<AllEntity> allEntities) {
this.allEntities = allEntities;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public BestEntity getBestEntity() {
return bestEntity;
}
public void setBestEntity(BestEntity bestEntity) {
this.bestEntity = bestEntity;
}
#Override
public String toString() {
return "Mention [allEntities=" + allEntities + ", name=" + name
+ ", bestEntity=" + bestEntity + "]";
}
}
Main.java
import com.example.ElemntList;
import com.google.gson.Gson;
import com.google.gson.GsonBuilder;
public class Main {
private static Gson gson;
static {
gson = new GsonBuilder().create();
}
/**
* #param args
*/
public static void main(String[] args) {
String s = "{\"mentions\":[{\"allEntities\":[{\"kbIdentifier\":\"YAGO:Bob_Dylan\",\"disambiguationScore\":\"0.63692\"}],\"name\":\"Dylan\",\"bestEntity\":{\"kbIdentifier\":\"YAGO:Bob_Dylan\",\"disambiguationScore\":\"0.63692\"}},{\"name\":\"Duluth\",\"bestEntity\":{\"kbIdentifier\":\"YAGO:Duluth\\u002c_Minnesota\",\"disambiguationScore\":\"0.63149\"}}]}";
ElemntList info = gson.fromJson(s, ElemntList.class);
System.out.println(info);
}
}
Result is -
ElemntList [mentions=[Mention [allEntities=[AllEntity [kbIdentifier=YAGO:Bob_Dylan, disambiguationScore=0.63692]], name=Dylan, bestEntity=BestEntity [kbIdentifier=YAGO:Bob_Dylan, disambiguationScore=0.63692]], Mention [allEntities=[], name=Duluth, bestEntity=BestEntity [kbIdentifier=YAGO:Duluth,_Minnesota, disambiguationScore=0.63149]]]]
Shouldn't you use the class you've created ? I.E Mentions
gson.fromJson(response, Mentions.class);
And if I were you, I would map all fields just in case you may need it, you're missing allEntities.
Related
I am getting this response from my Express API Call.
Here's the Response:
{
"responseData": [{
"unitNames": [
"Matrices",
"Complex Numbers"
],
"subject": "maths",
"unitTopics": {
"1": [{
"topicName": "1.1 Introduction",
"topicURL": ""
},
{
"topicName": "1.2 Square Matrix",
"topicURL": ""
}
],
"2": [{
"topicName": "2.1 Numbers",
"topicURL": ""
}
]
}
}]
}
I got the response by using Retrofit in Android. It works great.But it can't parse Objects
Here's my Problem in Android Side.
{
"responseData": [{
"unitNames": [
"Matrices",
"Complex Numbers"
],
"subject": "maths",
"unitTopics": {
"1": [[Object],
[Object]
],
"2": [[Object]
]
}
}]
}
Its showing Object instead of my Data. How to fix this
Here's the Code:
System.out.println(response.body().getResponseData())
String received_data = response.body().getResponseData();
received_data_sub_units_topics_json = new JSONArray("["+received_data+"]");
System.out.println("MAIN2 "+received_data_sub_units_topics_json);
After converting to jsonarray, it shows like this,
{
"responseData": [{
"unitNames": [
"Matrices",
"Complex Numbers"
],
"subject": "maths",
"unitTopics": {
"1": [["Object"],
["Object"]
],
"2": [["Object"]
]
}
}]
}
Please help me with some solutions
For json i always use the library com.fasterxml.jackson.
You can use too org.json.JSONArray, org.json.JSONObject.
Here is an example of each one:
1- jackson
For implements this (is a bit long but you will convert it to java classes, so, you will can edit the values and obtain it more easily than if you use JSONObject), you have to create classes wich has the same structure than your json:
public class principalClass {
ArrayList<ResponseData> responseData;
...
//Getters, setters and constructors
}
public class ResponseData {
public ArrayList<String> unitNames;
public String subject;
public UnitTopics unitTopics;
...
//Getters, setters and constructors
}
public class UnitTopics {
public ArrayList<Topics> first;
public ArrayList<Topics> second;
...
//Getters, setters and constructors
}
public class Topics {
public String topicName;
public String topicURL;
...
//Getters, setters and constructors
}
Something like that, and then you use jackson to pass your json to you class principalClass:
ObjectMapper obj= new ObjectMapper();
PrincipalClass principal= obj.readValue(json, PrincipalClass.class);
The second posibility is to convert the values to JSONArray and JSONObject:
JSONObject bodyJSON = new JSONObject(json);
JSONArray responseData = bodyJSON.getJSONArray("responseData");
JSONArray unitNames= responseData.getJSONArray(0);
JSONObject subject= responseData.getJSONObject(1);
...
And if u want, u can loop through a JSONArray:
for (int i = 0; i < unitNames.length(); i++) {
String element = unitNames.getString(i);
}
You can use gson converter with retrofit to convert your json data to java object model class
implementation 'com.squareup.retrofit2:converter-gson:2.4.0'
Or you can convert json data to model class like
Gson gson = new Gson();
String jsonInString = "{your json data}";
ResponseModel response= gson.fromJson(jsonInString, ResponseModel.class);
Hey have you tried converting this JSON Object to a POJO.
I'd recommend using:
This website
It saves a lot of time and effort.
These will be your model classes:
package com.example.app;
import java.io.Serializable;
import java.util.List;
import javax.annotation.Generated;
import com.google.gson.annotations.Expose;
import com.google.gson.annotations.SerializedName;
public class ResponseDatum implements Serializable
{
#SerializedName("unitNames")
#Expose
private List<String> unitNames = null;
#SerializedName("subject")
#Expose
private String subject;
#SerializedName("unitTopics")
#Expose
private UnitTopics unitTopics;
public ResponseDatum() {
}
public ResponseDatum(List<String> unitNames, String subject, UnitTopics unitTopics) {
super();
this.unitNames = unitNames;
this.subject = subject;
this.unitTopics = unitTopics;
}
public List<String> getUnitNames() {
return unitNames;
}
public void setUnitNames(List<String> unitNames) {
this.unitNames = unitNames;
}
public String getSubject() {
return subject;
}
public void setSubject(String subject) {
this.subject = subject;
}
public UnitTopics getUnitTopics() {
return unitTopics;
}
public void setUnitTopics(UnitTopics unitTopics) {
this.unitTopics = unitTopics;
}
}
package com.example.app;
import java.io.Serializable;
import java.util.List;
import javax.annotation.Generated;
import com.google.gson.annotations.Expose;
import com.google.gson.annotations.SerializedName;
public class ResponseObject implements Serializable
{
#SerializedName("responseData")
#Expose
private List<ResponseDatum> responseData = null;
public ResponseObject() {
}
public ResponseObject(List<ResponseDatum> responseData) {
super();
this.responseData = responseData;
}
public List<ResponseDatum> getResponseData() {
return responseData;
}
public void setResponseData(List<ResponseDatum> responseData) {
this.responseData = responseData;
}
}
package com.example.app;
import java.io.Serializable;
import java.util.List;
import javax.annotation.Generated;
import com.google.gson.annotations.Expose;
import com.google.gson.annotations.SerializedName;
public class UnitTopics implements Serializable
{
#SerializedName("1")
#Expose
private List<com.example.app._1> _1 = null;
#SerializedName("2")
#Expose
private List<com.example.app._2> _2 = null;
public UnitTopics() {
}
public UnitTopics(List<com.example.app._1> _1, List<com.example.app._2> _2) {
super();
this._1 = _1;
this._2 = _2;
}
public List<com.example.app._1> get1() {
return _1;
}
public void set1(List<com.example.app._1> _1) {
this._1 = _1;
}
public List<com.example.app._2> get2() {
return _2;
}
public void set2(List<com.example.app._2> _2) {
this._2 = _2;
}
}
package com.example.app;
import java.io.Serializable;
import javax.annotation.Generated;
import com.google.gson.annotations.Expose;
import com.google.gson.annotations.SerializedName;
public class _1 implements Serializable
{
#SerializedName("topicName")
#Expose
private String topicName;
#SerializedName("topicURL")
#Expose
private String topicURL;
public _1() {
}
public _1(String topicName, String topicURL) {
super();
this.topicName = topicName;
this.topicURL = topicURL;
}
public String getTopicName() {
return topicName;
}
public void setTopicName(String topicName) {
this.topicName = topicName;
}
public String getTopicURL() {
return topicURL;
}
public void setTopicURL(String topicURL) {
this.topicURL = topicURL;
}
}
package com.example.app;
import java.io.Serializable;
import javax.annotation.Generated;
import com.google.gson.annotations.Expose;
import com.google.gson.annotations.SerializedName;
public class _2 implements Serializable
{
#SerializedName("topicName")
#Expose
private String topicName;
#SerializedName("topicURL")
#Expose
private String topicURL;
public _2() {
}
public _2(String topicName, String topicURL) {
super();
this.topicName = topicName;
this.topicURL = topicURL;
}
public String getTopicName() {
return topicName;
}
public void setTopicName(String topicName) {
this.topicName = topicName;
}
public String getTopicURL() {
return topicURL;
}
public void setTopicURL(String topicURL) {
this.topicURL = topicURL;
}
}
I have two POJOs (Person.java and User.java) that contain similar information. See below:
public class Person {
private String first_name;
private String last_name;
private Integer age;
private Integer weight;
private Integer height;
public String getFirst_name() {
return first_name;
}
public void setFirst_name(String first_name) {
this.first_name = first_name;
}
public String getLast_name() {
return last_name;
}
public void setLast_name(String last_name) {
this.last_name = last_name;
}
public Integer getAge() {
return age;
}
public void setAge(Integer age) {
this.age = age;
}
public Integer getWeight() {
return weight;
}
public void setWeight(Integer weight) {
this.weight = weight;
}
public Integer getHeight() {
return height;
}
public void setHeight(Integer height) {
this.height = height;
}
}
public class User {
private String name_first;
private String name_last;
private Integer my_age;
private Integer my_weight;
private String social_security;
public String getName_first() {
return name_first;
}
public void setName_first(String name_first) {
this.name_first = name_first;
}
public String getName_last() {
return name_last;
}
public void setName_last(String name_last) {
this.name_last = name_last;
}
public Integer getMy_age() {
return my_age;
}
public void setMy_age(Integer my_age) {
this.my_age = my_age;
}
public Integer getMy_weight() {
return my_weight;
}
public void setMy_weight(Integer my_weight) {
this.my_weight = my_weight;
}
public String getSocial_security() {
return social_security;
}
public void setSocial_security(String social_security) {
this.social_security = social_security;
}
}
I have defined a mapping.json file as shown below using GSON.
{
"columnMap": [
{
"userColumn": "name_first",
"personColumn": "first_name"
},
{
"userColumn": "last_first",
"personColumn": "first_last"
},
{
"userColumn": "my_age",
"personColumn": "age"
},
{
"userColumn": "my_weight",
"personColumn": "weight"
}
]
}
public class Mapping {
private ArrayList<Pair> columnMap;
public Mapping(){
columnMap = new ArrayList<>();
}
public ArrayList<Pair> getColumnMap() {
return columnMap;
}
public void setColumnMap(ArrayList<Pair> columnMap) {
this.columnMap = columnMap;
}
}
I am writing a utility class helper function that converts between a Person and User object the mapped pairs.
public class Pair {
private String userColumn;
private String personColumn;
public String getUserColumn() {
return userColumn;
}
public void setUserColumn(String userColumn) {
this.userColumn = userColumn;
}
public String getPersonColumn() {
return personColumn;
}
public void setPersonColumn(String personColumn) {
this.personColumn = personColumn;
}
public static void main(String args[]){
}
}
My question is below:
As you can see the returnVal object is being set by me (the programmer) to convert from a User POJO to a Person POJO. How do I leverage the pre-defined mapping.json to do this? The reason I am asking is in the future, the mapping.json file may change (maybe the weight mapping no longer exists). So I am trying to avoid re-programming this Utility.userToPerson() function. How can I achieve this? I am thinking Java reflection is the way to go, but I would like to hear back from the Java community.
public class Utility {
public static Person userToPerson(User u){
Person returnVal = new Person();
returnVal.setAge(u.getMy_age()); // <-- Question How do I leverage mapping.json here?
returnVal.setFirst_name(u.getName_first());
returnVal.setLast_name(u.getName_last());
returnVal.setWeight(u.getMy_weight());
return returnVal;
}
}
You can introspect the beans (i.e. User and Person) for the field names and call corresponding getter from User to fetch the value. Later call corresponding setter in Person.
Here I have taken userToPersonFieldsMap for mapping the field, you can load mapping from JSON file and construct the map accordingly.
Important code section is the for loop, where it dynamically calls getter and setter and does the job.
import java.beans.IntrospectionException;
import java.beans.PropertyDescriptor;
import java.lang.reflect.InvocationTargetException;
import java.util.HashMap;
import java.util.Map;
public class UserToPersonMapper {
public static void main(String[] args) throws IntrospectionException, InvocationTargetException, IllegalAccessException {
Map<String, String> userToPersonFieldsMap = new HashMap<>();
userToPersonFieldsMap.put("name_first", "first_name");
userToPersonFieldsMap.put("last_first", "first_last");
userToPersonFieldsMap.put("age", "personAge");
//existing user
User user = new User("Tony", "Stark", 20);
//new person - to be initialised with values from user
Person person = new Person();
for (Map.Entry<String, String> entry : userToPersonFieldsMap.entrySet()) {
Object userVal = new PropertyDescriptor(entry.getKey(), User.class).getReadMethod().invoke(user);
new PropertyDescriptor(entry.getValue(), Person.class).getWriteMethod().invoke(person, userVal);
}
System.out.println(user);
System.out.println(person);
}
}
class User {
private String name_first;
private String last_first;
private int age;
public User(String name_first, String last_first, int age) {
this.name_first = name_first;
this.last_first = last_first;
this.age = age;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
public String getName_first() {
return name_first;
}
public String getLast_first() {
return last_first;
}
public void setName_first(String name_first) {
this.name_first = name_first;
}
public void setLast_first(String last_first) {
this.last_first = last_first;
}
#Override
public String toString() {
return "User{" +
"name_first='" + name_first + '\'' +
", last_first='" + last_first + '\'' +
", age=" + age +
'}';
}
}
class Person {
private String first_name;
private String first_last;
private int personAge;
public void setFirst_name(String first_name) {
this.first_name = first_name;
}
public void setFirst_last(String first_last) {
this.first_last = first_last;
}
public String getFirst_name() {
return first_name;
}
public String getFirst_last() {
return first_last;
}
public int getPersonAge() {
return personAge;
}
public void setPersonAge(int personAge) {
this.personAge = personAge;
}
#Override
public String toString() {
return "Person{" +
"first_name='" + first_name + '\'' +
", first_last='" + first_last + '\'' +
", personAge=" + personAge +
'}';
}
}
You can tweak and try it out this example to make it more align with your requirement.
Note:
This solution uses reflection.
I have created some Json file that contains shop's objects and i want to store it on Google drive and read it with Retrofit.
Currently, I can't store it in local memory or in-app.
Also, there is no server side yet, so it needs to be stored somewhere that Retrofit can access.
If you have any other ideas, I'd be more than happy to hear.
I make the link public to anyone, and here is my .json file:
{
"shop": [
{
"shopName": "Renuar",
"shopID": "1000",
"isPaid": "false",
"branches": [
{
"branchName": "Branch 1",
"branchPhone": "039599559",
"openingTime": "09:00",
"closingTime": "21:00",
"branchLat": "32.000",
"branchLon": "35.000",
"branchAddressNote": "Grand Canyon"
}
]
},
{
"shopName": "Castro",
"shopID": "1000",
"isPaid": "false",
"branches": [
{
"branchName": "Branch 1",
"branchPhone": "039599559",
"openingTime": "09:00",
"closingTime": "21:00",
"branchLat": "32.000",
"branchLon": "35.000",
"branchAddressNote": "Grand Canyon"
}
]
}
]
}
I've tried the next steps but it's not work for me.
public interface ApiService {
#GET("file/d/1-lsBIzI7Y5uCg8bG_531o49Dcu6E2RdH/view?usp=sharing")
Call<ShopsResponse> getAllShops();
}
public static class RetrofitInstance{
public static Retrofit retrofit = null;
private static final String BASE_URL = "https://drive.google.com/";
public static ApiService getApiService(){
if (retrofit == null){
Gson gson = new GsonBuilder()
.setLenient()
.create();
retrofit = new Retrofit.Builder()
.baseUrl(BASE_URL)
.addConverterFactory(GsonConverterFactory.create(gson))
.build();
}
return retrofit.create(ApiService.class);
}
}
ApiService apiService = RetrofitInstance.getApiService();
apiService.getAllShops().enqueue(new Callback<ShopsResponse>() {
#Override
public void onResponse(Call<ShopsResponse> call, Response<ShopsResponse> response) {
ShopsResponse response1 = response.body();
Log.d(TAG, "onResponse: "+response1.getShop().size());
}
#Override
public void onFailure(Call<ShopsResponse> call, Throwable t) {
Log.d(TAG, "onResponse: "+t.getMessage());
}
});
That what i receive in logcat:
D/myDebug: onResponse: java.lang.IllegalStateException: Expected BEGIN_OBJECT but was STRING at line 2 column 1 path $
I think there is something wrong with your pojo objects. It should be like this according to your response
package com.example;
import com.google.gson.annotations.Expose;
import com.google.gson.annotations.SerializedName;
public class Branch {
#SerializedName("branchName")
#Expose
private String branchName;
#SerializedName("branchPhone")
#Expose
private String branchPhone;
#SerializedName("openingTime")
#Expose
private String openingTime;
#SerializedName("closingTime")
#Expose
private String closingTime;
#SerializedName("branchLat")
#Expose
private String branchLat;
#SerializedName("branchLon")
#Expose
private String branchLon;
#SerializedName("branchAddressNote")
#Expose
private String branchAddressNote;
public String getBranchName() {
return branchName;
}
public void setBranchName(String branchName) {
this.branchName = branchName;
}
public String getBranchPhone() {
return branchPhone;
}
public void setBranchPhone(String branchPhone) {
this.branchPhone = branchPhone;
}
public String getOpeningTime() {
return openingTime;
}
public void setOpeningTime(String openingTime) {
this.openingTime = openingTime;
}
public String getClosingTime() {
return closingTime;
}
public void setClosingTime(String closingTime) {
this.closingTime = closingTime;
}
public String getBranchLat() {
return branchLat;
}
public void setBranchLat(String branchLat) {
this.branchLat = branchLat;
}
public String getBranchLon() {
return branchLon;
}
public void setBranchLon(String branchLon) {
this.branchLon = branchLon;
}
public String getBranchAddressNote() {
return branchAddressNote;
}
public void setBranchAddressNote(String branchAddressNote) {
this.branchAddressNote = branchAddressNote;
}
}
package com.example;
import java.util.List;
import com.google.gson.annotations.Expose;
import com.google.gson.annotations.SerializedName;
public class Example {
#SerializedName("shop")
#Expose
private List<Shop> shop = null;
public List<Shop> getShop() {
return shop;
}
public void setShop(List<Shop> shop) {
this.shop = shop;
}
}
package com.example;
import java.util.List;
import com.google.gson.annotations.Expose;
import com.google.gson.annotations.SerializedName;
public class Shop {
#SerializedName("shopName")
#Expose
private String shopName;
#SerializedName("shopID")
#Expose
private String shopID;
#SerializedName("isPaid")
#Expose
private String isPaid;
#SerializedName("branches")
#Expose
private List<Branch> branches = null;
public String getShopName() {
return shopName;
}
public void setShopName(String shopName) {
this.shopName = shopName;
}
public String getShopID() {
return shopID;
}
public void setShopID(String shopID) {
this.shopID = shopID;
}
public String getIsPaid() {
return isPaid;
}
public void setIsPaid(String isPaid) {
this.isPaid = isPaid;
}
public List<Branch> getBranches() {
return branches;
}
public void setBranches(List<Branch> branches) {
this.branches = branches;
}
}
I am trying to deserialize following JSON:
{
"name": "myName",
"decoder": "myDecoder",
"id": 123,
"definition": {
"AND": [
"and-condition-1",
"and-condition-2",
{
"OR": [
"or-condition-1",
"or-condition-2"
]
}
]
}
}
I have deserialized the file:
ObjectMapper mapper = new ObjectMapper();
RuleDefinition ruleDefinition = mapper.readValue(new File(fileName), RuleDefinition.class);
in to following Object-Structure:
RuleDefinition.java
import com.fasterxml.jackson.annotation.JsonInclude;
import com.fasterxml.jackson.annotation.JsonProperty;
#JsonInclude(JsonInclude.Include.NON_NULL)
public class RuleDefinition {
#JsonProperty("name")
private String name;
#JsonProperty("decoder")
private String decoder;
#JsonProperty("id")
private int id;
#JsonProperty("definition")
private Definition definition;
#JsonProperty("name")
public String getName() {
return name;
}
#JsonProperty("name")
public void setName(String name) {
this.name = name;
}
#JsonProperty("decoder")
public String getDecoder() {
return decoder;
}
#JsonProperty("decoder")
public void setDecoder(String decoder) {
this.decoder = decoder;
}
#JsonProperty("id")
public int getId() {
return id;
}
#JsonProperty("id")
public void setId(int id) {
this.id = id;
}
#JsonProperty("definition")
public Definition getDefinition() {
return definition;
}
#JsonProperty("definition")
public void setDefinition(Definition definition) {
this.definition = definition;
}
#Override
public String toString() {
return "RuleDefinition{" +
"name='" + name + '\'' +
", decoder='" + decoder + '\'' +
", id=" + id +
", definition=" + definition +
'}';
}
}
Definition.Java
import com.fasterxml.jackson.annotation.JsonInclude;
import com.fasterxml.jackson.annotation.JsonProperty;
import java.util.List;
#JsonInclude(JsonInclude.Include.NON_NULL)
public class Definition {
#JsonProperty("AND")
private List<AND> AND;
public List<AND> getAND() {
return AND;
}
public void setAND(List<AND> AND) {
this.AND = AND;
}
#Override
public String toString() {
return "Definition{" +
"AND=" + AND +
'}';
}
}
AND.java
import com.fasterxml.jackson.annotation.JsonInclude;
import com.fasterxml.jackson.annotation.JsonProperty;
import java.util.List;
#JsonInclude(JsonInclude.Include.NON_NULL)
public class AND {
#JsonProperty("OR")
private List<String> Or;
#JsonProperty("OR")
public List<String> getOR() {
return Or;
}
#JsonProperty("OR")
public void setOR(List<String> Or) {
this.Or = Or;
}
#Override
public String toString() {
return "AND{" +
"Or=" + Or +
'}';
}
}
and i got the following error
com.fasterxml.jackson.databind.JsonMappingException: Can not construct instance of com.model.AND: no String-argument constructor/factory method to deserialize from String value ('and-condition-1')
I see that the issue is because of 'and-condition-1' which is just a value, how do I deserialize these, I wanted to know should I write a custom deserializer (or) Is there any work around?
I think the problem is that in your JSON the AND object is both a string and an object. You should create a JsonDeserializer for it.
enter link description here
enter link description here
I was following the start-up guide of at spring website https://spring.io/guides/gs/consuming-rest/.
I am not following the exact tutorial in the sense that I am using another endpoint: http://www.omdbapi.com?s=rush.
I am having an issue with JSON conversion to POJO. I am not getting any error or exceptions. Could someone point out where am I going wrong?
You can find the complete code here
Here are my POJOs:
package com.sample.restapi.model;
import java.util.List;
import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
#JsonIgnoreProperties(ignoreUnknown=true)
public class SearchResponse {
private List<Search> search;
private String totalResults;
private String response;
public SearchResponse() {
}
public List<Search> getSearch() {
return search;
}
public void setSearch(List<Search> search) {
this.search = search;
}
public String getTotalResults() {
return totalResults;
}
public void setTotalResults(String totalResults) {
this.totalResults = totalResults;
}
public String getResponse() {
return response;
}
public void setResponse(String response) {
this.response = response;
}
#Override
public String toString() {
return "SearchResponse [search=" + search + ", totalResults=" + totalResults + ", response=" + response + "]";
}
}
Here is the Search.java
package com.sample.restapi.model;
import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
#JsonIgnoreProperties(ignoreUnknown=true)
public class Search {
private String title;
private String year;
private String imdbID;
private String type;
private String poster;
public Search() {
}
public String getTitle() {
return title;
}
public void setTitle(String title) {
this.title = title;
}
public String getYear() {
return year;
}
public void setYear(String year) {
this.year = year;
}
public String getImdbID() {
return imdbID;
}
public void setImdbID(String imdbID) {
this.imdbID = imdbID;
}
public String getType() {
return type;
}
public void setType(String type) {
this.type = type;
}
public String getPoster() {
return poster;
}
public void setPoster(String poster) {
this.poster = poster;
}
#Override
public String toString() {
return "Search [title=" + title + ", year=" + year + ", imdbID=" + imdbID + ", type=" + type + ", poster="
+ poster + "]";
}
}
Here is the driver class.
package com.sample.restapi;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.web.client.RestTemplate;
import com.sample.restapi.model.SearchResponse;
#SpringBootApplication
public class ConsumerApplication {
private static final Logger log = LoggerFactory.getLogger(ConsumerApplication.class);
public static void main(String[] args) {
RestTemplate restTemplate = new RestTemplate();
SearchResponse searchResponse = restTemplate.getForObject("http://www.omdbapi.com?s=rush", SearchResponse.class);
log.info(searchResponse.toString());
}
}
The console output is :
14:34:12.941 [main] INFO com.sample.restapi.ConsumerApplication - SearchResponse [search=null, totalResults=344, response=null]
You are missing correct identifiers for the properties in the json, there are differences in the response and your classes in the Capital and lower case letters. Use #JsonProperty in your classes.
#JsonProperty("Search")
private List<Search> search = new ArrayList<Search>();
private String totalResults;
#JsonProperty("Response")
private String response;
you should also add #JsonProperty annotations in the Search class.