I have an Android application that gets a json from a http call and looks like this:
{
"string_1":{
"prop_1":"value",
"prop_2":"value"
},
"string_2":{
"prop_1":"value",
"prop_2":"value"
},
...
"string_n":{
"prop_1":"value",
"prop_2":"value"
}
}
Here's the java class I wrote to use the data in my code:
public class FooClass implements Serializable {
private LinkedHashMap<String, FooObject> objectsMap;
public LinkedHashMap<String, FooObject> getObjectsMap() {
return objectsMap;
}
}
where FooObject is:
public class FooObject implements Serializable {
#SerializedName("prop_1")
private String property1;
#SerializedName("prop_2")
private String property2;
public String getProperty1() {
return property1;
}
public String getProperty1() {
return property1;
}
}
But since my json doesn't have an element called "objectsMap" my linked hash map from FooClass is always null.
What class structure should I use for this json structure?
Thank you.
UPDATE:
I have managed to solve my problem. I use retrofit 1.9, and make the method return a result of type LinkedHashMap and it solved my problem.
Better and more feasible is to change your response structure and have an Array rather than string_1, string_2... string_n. If you can't do that you will have to iterate through all the possible keys and save the response something like this
jObject = new JSONObject(response);
Iterator<?> keys = jObject.keys();
while( keys.hasNext() ) {
String key = (String)keys.next();
if ( jObject.get(key) instanceof JSONObject ) {
// do your stuff here
}
}
-----------------------------------com.example.Example.java-----------------------------------
package com.example;
import com.google.gson.annotations.Expose;
import com.google.gson.annotations.SerializedName;
public class Example {
#SerializedName("string_1")
#Expose
private String1 string1;
#SerializedName("string_2")
#Expose
private String2 string2;
#SerializedName("string_n")
#Expose
private StringN stringN;
public String1 getString1() {
return string1;
}
public void setString1(String1 string1) {
this.string1 = string1;
}
public String2 getString2() {
return string2;
}
public void setString2(String2 string2) {
this.string2 = string2;
}
public StringN getStringN() {
return stringN;
}
public void setStringN(StringN stringN) {
this.stringN = stringN;
}
}
-----------------------------------com.example.String1.java-----------------------------------
package com.example;
import com.google.gson.annotations.Expose;
import com.google.gson.annotations.SerializedName;
public class String1 {
#SerializedName("prop_1")
#Expose
private String prop1;
#SerializedName("prop_2")
#Expose
private String prop2;
public String getProp1() {
return prop1;
}
public void setProp1(String prop1) {
this.prop1 = prop1;
}
public String getProp2() {
return prop2;
}
public void setProp2(String prop2) {
this.prop2 = prop2;
}
}
-----------------------------------com.example.String2.java-----------------------------------
package com.example;
import com.google.gson.annotations.Expose;
import com.google.gson.annotations.SerializedName;
public class String2 {
#SerializedName("prop_1")
#Expose
private String prop1;
#SerializedName("prop_2")
#Expose
private String prop2;
public String getProp1() {
return prop1;
}
public void setProp1(String prop1) {
this.prop1 = prop1;
}
public String getProp2() {
return prop2;
}
public void setProp2(String prop2) {
this.prop2 = prop2;
}
}
-----------------------------------com.example.StringN.java-----------------------------------
package com.example;
import com.google.gson.annotations.Expose;
import com.google.gson.annotations.SerializedName;
public class StringN {
#SerializedName("prop_1")
#Expose
private String prop1;
#SerializedName("prop_2")
#Expose
private String prop2;
public String getProp1() {
return prop1;
}
public void setProp1(String prop1) {
this.prop1 = prop1;
}
public String getProp2() {
return prop2;
}
public void setProp2(String prop2) {
this.prop2 = prop2;
}
}
Hope it helps and you can use http://www.jsonschema2pojo.org/
If you're using a SerializedName annotation in your Response class which you're trying to map, just delete it and map your Json Response to
public class FooClass implements Serializable {
private Map<String, FooObject> objectsMap;
public Map<String, FooObject> getObjectsMap() {
return objectsMap;
}
}
Related
Hi everybody and thanks for helping me,
I'm trying to fetch data from an api url "https://api.stackexchange.com/2.2/search?order=desc&sort=creation&site=stackoverflow&tagged=android" and I don't know what I am missing.
I keep on getting an error saying that I am pointing to a null object, but it is not supposed to be null.
That is the error message
`
E/AndroidRuntime: FATAL EXCEPTION: main
Process: com.example.finalhomework, PID: 5005
java.lang.NullPointerException: Attempt to invoke interface method 'java.util.Iterator java.util.List.iterator()' on a null object reference
at com.example.finalhomework.view.SearchActivity$1.onResponse(SearchActivity.java:46)
at retrofit2.DefaultCallAdapterFactory$ExecutorCallbackCall$1.lambda$onResponse$0$DefaultCallAdapterFactory$ExecutorCallbackCall$1(DefaultCallAdapterFactory.java:89)
at retrofit2.-$$Lambda$DefaultCallAdapterFactory$ExecutorCallbackCall$1$3wC8FyV4pyjrzrYL5U0mlYiviZw.run(lambda)
at android.os.Handler.handleCallback(Handler.java:751)
at android.os.Handler.dispatchMessage(Handler.java:95)
at android.os.Looper.loop(Looper.java:154)
at android.app.ActivityThread.main(ActivityThread.java:6077)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:866)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:756)`
That is the results page which is supposed to get all the item
`
package com.example.finalhomework.model;
import java.io.Serializable;
import java.util.List;
import com.google.gson.annotations.Expose;
import com.google.gson.annotations.SerializedName;
public class StackOverflowPageResult implements Serializable
{
#SerializedName("StackOverflowItem")
#Expose
private List<StackOverflowItem> items = null;
#SerializedName("has_more")
#Expose
private Boolean hasMore;
#SerializedName("quota_max")
#Expose
private Integer quotaMax;
#SerializedName("quota_remaining")
#Expose
private Integer quotaRemaining;
private final static long serialVersionUID = -263378404000205617L;
public List<StackOverflowItem> getStackOverflowItem() {
return items;
}
public void setItems(List<StackOverflowItem> items) {
this.items = items;
}
public Boolean getHasMore() {
return hasMore;
}
public void setHasMore(Boolean hasMore) {
this.hasMore = hasMore;
}
public Integer getQuotaMax() {
return quotaMax;
}
public void setQuotaMax(Integer quotaMax) {
this.quotaMax = quotaMax;
}
public Integer getQuotaRemaining() {
return quotaRemaining;
}
public void setQuotaRemaining(Integer quotaRemaining) {
this.quotaRemaining = quotaRemaining;
}
}`
That is the Item itself:
`
package com.example.finalhomework.model;
import java.io.Serializable;
import java.util.List;
import com.google.gson.annotations.Expose;
import com.google.gson.annotations.SerializedName;
public class StackOverflowItem implements Serializable
{
#SerializedName("tags")
#Expose
private List<String> tags = null;
#SerializedName("owner")
#Expose
private Owner owner;
#SerializedName("is_answered")
#Expose
private Boolean isAnswered;
#SerializedName("view_count")
#Expose
private Integer viewCount;
#SerializedName("answer_count")
#Expose
private Integer answerCount;
#SerializedName("score")
#Expose
private Integer score;
#SerializedName("last_activity_date")
#Expose
private Integer lastActivityDate;
#SerializedName("creation_date")
#Expose
private Integer creationDate;
#SerializedName("question_id")
#Expose
private Integer questionId;
#SerializedName("content_license")
#Expose
private String contentLicense;
#SerializedName("link")
#Expose
private String link;
#SerializedName("title")
#Expose
private String title;
#SerializedName("last_edit_date")
#Expose
private Integer lastEditDate;
#SerializedName("accepted_answer_id")
#Expose
private Integer acceptedAnswerId;
#SerializedName("closed_date")
#Expose
private Integer closedDate;
#SerializedName("closed_reason")
#Expose
private String closedReason;
private final static long serialVersionUID = 2088551364601451752L;
public List<String> getTags() {
return tags;
}
public void setTags(List<String> tags) {
this.tags = tags;
}
public Owner getOwner() {
return owner;
}
public void setOwner(Owner owner) {
this.owner = owner;
}
public Boolean getIsAnswered() {
return isAnswered;
}
public void setIsAnswered(Boolean isAnswered) {
this.isAnswered = isAnswered;
}
public Integer getViewCount() {
return viewCount;
}
public void setViewCount(Integer viewCount) {
this.viewCount = viewCount;
}
public Integer getAnswerCount() {
return answerCount;
}
public void setAnswerCount(Integer answerCount) {
this.answerCount = answerCount;
}
public Integer getScore() {
return score;
}
public void setScore(Integer score) {
this.score = score;
}
public Integer getLastActivityDate() {
return lastActivityDate;
}
public void setLastActivityDate(Integer lastActivityDate) {
this.lastActivityDate = lastActivityDate;
}
public Integer getCreationDate() {
return creationDate;
}
public void setCreationDate(Integer creationDate) {
this.creationDate = creationDate;
}
public Integer getQuestionId() {
return questionId;
}
public void setQuestionId(Integer questionId) {
this.questionId = questionId;
}
public String getContentLicense() {
return contentLicense;
}
public void setContentLicense(String contentLicense) {
this.contentLicense = contentLicense;
}
public String getLink() {
return link;
}
public void setLink(String link) {
this.link = link;
}
public String getTitle() {
return title;
}
public void setTitle(String title) {
this.title = title;
}
public Integer getLastEditDate() {
return lastEditDate;
}
public void setLastEditDate(Integer lastEditDate) {
this.lastEditDate = lastEditDate;
}
public Integer getAcceptedAnswerId() {
return acceptedAnswerId;
}
public void setAcceptedAnswerId(Integer acceptedAnswerId) {
this.acceptedAnswerId = acceptedAnswerId;
}
public Integer getClosedDate() {
return closedDate;
}
public void setClosedDate(Integer closedDate) {
this.closedDate = closedDate;
}
public String getClosedReason() {
return closedReason;
}
public void setClosedReason(String closedReason) {
this.closedReason = closedReason;
}
}`
That is the Retrofit builder with the url:
`
package com.example.finalhomework.network;
import retrofit2.Retrofit;
import retrofit2.converter.gson.GsonConverterFactory;
public class RetrofitInstance {
private static Retrofit retrofit;
private static final String BASE_URL ="https://api.stackexchange.com/2.2/";
public static Retrofit getRetrofitInstance(){
if (retrofit == null){
retrofit = new retrofit2.Retrofit.Builder()
.baseUrl(BASE_URL)
.addConverterFactory(GsonConverterFactory.create())
.build();
}
return retrofit;
}
}`
That is the interface with the url's arguments:
`
package com.example.finalhomework.network;
import com.example.finalhomework.model.StackOverflowPageResult;
import retrofit2.Call;
import retrofit2.http.GET;
import retrofit2.http.Query;
public interface GetStackOverflowItemDataService {
#GET("search")
Call<StackOverflowPageResult> getStackOverflowItem(
#Query("tagged") String tagged,
#Query("site") String site,
#Query("sort") String sort,
#Query("order") String order
);
}`
And here we've got the class which is supposed to get the total result, and I put a Log.i in order to check if everything is in order and the stackOverflowItems is null:
`
package com.example.finalhomework.view;
import androidx.appcompat.app.ActionBar;
import androidx.appcompat.app.AppCompatActivity;
import androidx.appcompat.widget.Toolbar;
import android.os.Bundle;
import android.util.Log;
import com.example.finalhomework.R;
import com.example.finalhomework.model.StackOverflowItem;
import com.example.finalhomework.model.StackOverflowPageResult;
import com.example.finalhomework.network.GetStackOverflowItemDataService;
import com.example.finalhomework.network.RetrofitInstance;
import java.util.List;
import retrofit2.Call;
import retrofit2.Callback;
import retrofit2.Response;
public class SearchActivity extends AppCompatActivity {
Toolbar toolbar;
private GetStackOverflowItemDataService stackOverflowItemDataService;
List<StackOverflowItem> stackOverflowItems;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_search);
setToolbarBack();
stackOverflowItemDataService = RetrofitInstance.getRetrofitInstance().create(GetStackOverflowItemDataService.class);
stackOverflowItemDataService.getStackOverflowItem("android", "stackoverflow", "creation", "desc")
.enqueue(new Callback<StackOverflowPageResult>() {
#Override
public void onResponse(Call<StackOverflowPageResult> call, Response<StackOverflowPageResult> response) {
StackOverflowPageResult stackOverflowPageResult = response.body();
stackOverflowItems = stackOverflowPageResult.getStackOverflowItem();
for (StackOverflowItem s : stackOverflowItems) {
Log.i("Item StackOverflow :", s.getTitle());
}
}
#Override
public void onFailure(Call<StackOverflowPageResult> call, Throwable t) {
}
});
}`
Again thanks for the help
There is mismatch between JSON data variable and your #SerializedName("StackOverflowItem")
So make the changes to match the SerializedName, code as follows -
public class StackOverflowPageResult implements Serializable {
#SerializedName("items")
private List<StackOverflowItem> items;
#SerializedName("has_more")
private Boolean hasMore;
#SerializedName("quota_max")
private Integer quotaMax;
#SerializedName("quota_remaining")
private Integer quotaRemaining;
// your further code here
//.............
}
SerializedName is only required when you are going to take variable name different from JSON object, otherwise you can skip #SerializedName tag as well.
One more thing I suggest, I you are not going to call excludeFieldsWithoutExposeAnnotation() in your GsonBuilder class, then there is no need for #Expose tag.
The Gson #Expose annotation can be used to mark a field to be exposed or not (included or not) for serialized or deserialized. The #Expose annotation can take two parameters and each parameter is a boolean which can take either the value true or false. In order to get GSON to react to the #Expose annotations we must create a Gson instance using the GsonBuilder class and need to call the excludeFieldsWithoutExposeAnnotation() method, it configures Gson to exclude all fields from consideration for serialization or deserialization that do not have the Expose annotation.
Happy Coding !
Here's an example of my JSON:
{
"status": "ok",
"rowCount": 60,
"pageCount": 6,
"value": [{
"CustomerID": 1911,
"CustomerTypeID": 3,
...
}
]
}
My POJO:
#SerializedName("CustomerID")
public Integer CustomerID;
#SerializedName("CustomerTypeID")
public Integer CustomerTypeID;
I want to pull everything under value.
How do I do this using Google's GSON?
I've tried doing it as I would normally, but for, obvious reasons, it didn't work:
Type collectionType = new TypeToken<ArrayList<Customer>>() {}.getType();
return gson.fromJson(json, collectionType);
You can not skip root JSON object. The simplest solution in this case is - create root POJO:
class Response {
#SerializedName("value")
private List<Customer> customers;
// getters, setters
}
And you can use it as below:
return gson.fromJson(json, Response.class).getCustomers();
You don't need to worry writing your own POJO.
just visit http://www.jsonschema2pojo.org/
and paste here your JSON data, it'll automatically return you converted classes as below
-----------------------------------com.example.Example.java-----------------------------------
package com.example;
import java.util.List;
import com.google.gson.annotations.Expose;
import com.google.gson.annotations.SerializedName;
public class Example {
#SerializedName("status")
#Expose
private String status;
#SerializedName("rowCount")
#Expose
private Integer rowCount;
#SerializedName("pageCount")
#Expose
private Integer pageCount;
#SerializedName("value")
#Expose
private List<Value> value = null;
public String getStatus() {
return status;
}
public void setStatus(String status) {
this.status = status;
}
public Integer getRowCount() {
return rowCount;
}
public void setRowCount(Integer rowCount) {
this.rowCount = rowCount;
}
public Integer getPageCount() {
return pageCount;
}
public void setPageCount(Integer pageCount) {
this.pageCount = pageCount;
}
public List<Value> getValue() {
return value;
}
public void setValue(List<Value> value) {
this.value = value;
}
}
-----------------------------------com.example.Value.java-----------------------------------
package com.example;
import com.google.gson.annotations.Expose;
import com.google.gson.annotations.SerializedName;
public class Value {
#SerializedName("CustomerID")
#Expose
private Integer customerID;
#SerializedName("CustomerTypeID")
#Expose
private Integer customerTypeID;
public Integer getCustomerID() {
return customerID;
}
public void setCustomerID(Integer customerID) {
this.customerID = customerID;
}
public Integer getCustomerTypeID() {
return customerTypeID;
}
public void setCustomerTypeID(Integer customerTypeID) {
this.customerTypeID = customerTypeID;
}
}
The above two classes are auto generated by website.
import java.util.List;
import com.google.gson.annotations.Expose;
import com.google.gson.annotations.SerializedName;
public class ExampleClass {
#SerializedName("status")
#Expose
private String status;
#SerializedName("rowCount")
#Expose
private int rowCount;
#SerializedName("pageCount")
#Expose
private int pageCount;
#SerializedName("value")
#Expose
private List<Value> value = null;
public String getStatus() {
return status;
}
public void setStatus(String status) {
this.status = status;
}
public int getRowCount() {
return rowCount;
}
public void setRowCount(int rowCount) {
this.rowCount = rowCount;
}
public int getPageCount() {
return pageCount;
}
public void setPageCount(int pageCount) {
this.pageCount = pageCount;
}
public List<Value> getValue() {
return value;
}
public void setValue(List<Value> value) {
this.value = value;
}
}
-----------------------------------Value.java-----------------------------------
import com.google.gson.annotations.Expose;
import com.google.gson.annotations.SerializedName;
public class Value {
#SerializedName("CustomerID")
#Expose
private int customerID;
#SerializedName("CustomerTypeID")
#Expose
private int customerTypeID;
public int getCustomerID() {
return customerID;
}
public void setCustomerID(int customerID) {
this.customerID = customerID;
}
public int getCustomerTypeID() {
return customerTypeID;
}
public void setCustomerTypeID(int customerTypeID) {
this.customerTypeID = customerTypeID;
}
}
/********* parsing with Gson ******/
GsonBuilder gsonBuilder = new GsonBuilder();
gson = gsonBuilder.create();
ExampleClass resultObj = gson.fromJson(jsonObject.toString(), ExampleClass.class);
List<Value> yourListOfCustomerValues = resultObj.getValue();
You can refer to this amazing post on mapping of arrays and lists of objects with Gson by Norman Peitek
Basics of Gson, model annotations and mapping of nested objects
I am having trouble parsing the below JSON structure. Basically I have to read the values object as list but the server returns as a JsonObject and the value changes based on the totalPageCount. Is there any way I can read the values as List? Should I use reflections ? Currently I am using Retrofit with returns the model class.
Any help is really appreciated.
Thank you
{
"page" : 0,
"pageSize" : 10,
"totalPageCount" : 1,
"values" : {
"key1" : "value1",
"key2" : "value2",
"key3" : "value3",
"key4" : "value4",
}
}
Model class :
import com.google.gson.annotations.Expose;
import com.google.gson.annotations.SerializedName;
public class Example {
#SerializedName("page")
#Expose
private Integer page;
#SerializedName("pageSize")
#Expose
private Integer pageSize;
#SerializedName("totalPageCount")
#Expose
private Integer totalPageCount;
#SerializedName("values")
#Expose
private Values values;
public Integer getPage() {
return page;
}
public void setPage(Integer page) {
this.page = page;
}
public Integer getPageSize() {
return pageSize;
}
public void setPageSize(Integer pageSize) {
this.pageSize = pageSize;
}
public Integer getTotalPageCount() {
return totalPageCount;
}
public void setTotalPageCount(Integer totalPageCount) {
this.totalPageCount = totalPageCount;
}
public Values getValues() {
return values;
}
public void setValues(Values values) {
this.values = values;
}
}
-----------------------------------com.example.Values.java-----------------------------------
package com.example;
import com.google.gson.annotations.Expose;
import com.google.gson.annotations.SerializedName;
public class Values {
#SerializedName("key1")
#Expose
private String key1;
#SerializedName("key2")
#Expose
private String key2;
#SerializedName("key3")
#Expose
private String key3;
#SerializedName("key4")
#Expose
private String key4;
public String getKey1() {
return key1;
}
public void setKey1(String key1) {
this.key1 = key1;
}
public String getKey2() {
return key2;
}
public void setKey2(String key2) {
this.key2 = key2;
}
public String getKey3() {
return key3;
}
public void setKey3(String key3) {
this.key3 = key3;
}
public String getKey4() {
return key4;
}
public void setKey4(String key4) {
this.key4 = key4;
}
}
This will work
private Map<String,String> values;
I have a JSON object like the following:
...
{
"url": "checkout.bodenusa.com/en-US"
},
{
"url": [
".bonton.com/checkout/",
".bonton.com/CheckoutView"
]
}
...
How should my Java class look like for Response server.
I try this snippet, but it is incorrect:
#SerializedName("url")
#Expose
private List<String> urlList = null;
#SerializedName("url")
#Expose
private String url;
Create a model like
import com.google.gson.annotations.Expose;
import com.google.gson.annotations.SerializedName;
import java.util.List;
public class Model {
#SerializedName("url")
#Expose
private List<String> url = null;
#SerializedName("apply")
#Expose
private Apply apply;
#SerializedName("controls")
#Expose
private Controls controls;
#SerializedName("remove")
#Expose
private Remove remove;
public List<String> getUrl() {
return url;
}
public void setUrl(List<String> url) {
this.url = url;
}
public Apply getApply() {
return apply;
}
public void setApply(Apply apply) {
this.apply = apply;
}
public Controls getControls() {
return controls;
}
public void setControls(Controls controls) {
this.controls = controls;
}
public Remove getRemove() {
return remove;
}
public void setRemove(Remove remove) {
this.remove = remove;
}
public class Controls {
#SerializedName("promo")
#Expose
private String promo;
#SerializedName("total")
#Expose
private String total;
#SerializedName("orderTotal")
#Expose
private String orderTotal;
#SerializedName("coupon")
#Expose
private String coupon;
public String getPromo() {
return promo;
}
public void setPromo(String promo) {
this.promo = promo;
}
public String getTotal() {
return total;
}
public void setTotal(String total) {
this.total = total;
}
public String getOrderTotal() {
return orderTotal;
}
public void setOrderTotal(String orderTotal) {
this.orderTotal = orderTotal;
}
public String getCoupon() {
return coupon;
}
public void setCoupon(String coupon) {
this.coupon = coupon;
}
}
public class Remove {
#SerializedName("type")
#Expose
private String type;
#SerializedName("submit")
#Expose
private String submit;
#SerializedName("timeout")
#Expose
private Integer timeout;
public String getType() {
return type;
}
public void setType(String type) {
this.type = type;
}
public String getSubmit() {
return submit;
}
public void setSubmit(String submit) {
this.submit = submit;
}
public Integer getTimeout() {
return timeout;
}
public void setTimeout(Integer timeout) {
this.timeout = timeout;
}
}
public class Apply {
#SerializedName("type")
#Expose
private String type;
#SerializedName("submit")
#Expose
private String submit;
#SerializedName("timeout")
#Expose
private Integer timeout;
public String getType() {
return type;
}
public void setType(String type) {
this.type = type;
}
public String getSubmit() {
return submit;
}
public void setSubmit(String submit) {
this.submit = submit;
}
public Integer getTimeout() {
return timeout;
}
public void setTimeout(Integer timeout) {
this.timeout = timeout;
}
}
}
Use this class along with a Custom TypeAdapter for Gson .Then it will work for both List and Object response .
ArrayAdapter class
import com.google.gson.Gson;
import com.google.gson.TypeAdapter;
import com.google.gson.TypeAdapterFactory;
import com.google.gson.reflect.TypeToken;
import java.lang.reflect.ParameterizedType;
import java.util.ArrayList;
import java.util.List;
public class ArrayAdapterFactory implements TypeAdapterFactory {
#Override
#SuppressWarnings({"unchecked", "rawtypes"})
public <T> TypeAdapter<T> create(final Gson gson, final TypeToken<T> type) {
TypeAdapter<T> typeAdapter = null;
try {
if (type.getRawType() == List.class || type.getRawType() == ArrayList.class) {
typeAdapter = new ArrayAdapter(gson,
(Class) ((ParameterizedType) type.getType())
.getActualTypeArguments()[0]);
}
} catch (Exception e) {
e.printStackTrace();
}
return typeAdapter;
}
}
ArrayAdapterFactory class
import com.google.gson.Gson;
import com.google.gson.TypeAdapter;
import com.google.gson.stream.JsonReader;
import com.google.gson.stream.JsonToken;
import com.google.gson.stream.JsonWriter;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
class ArrayAdapter<T> extends TypeAdapter<List<T>> {
private Class<T> adapterclass;
private Gson gson;
public ArrayAdapter(Gson gson, Class<T> adapterclass) {
this.adapterclass = adapterclass;
this.gson = gson;
}
#Override
public List<T> read(JsonReader reader) throws IOException {
List<T> list = new ArrayList<T>();
final JsonToken token = reader.peek();
System.out.println(token);
// Handling of Scenario 2( Check JavaDoc for the class) :
if (token == JsonToken.STRING || token == JsonToken.NUMBER ||
token == JsonToken.BOOLEAN) {
T inning = (T) gson.fromJson(reader, adapterclass);
list.add(inning);
} else if (token == JsonToken.BEGIN_OBJECT) {
// Handling of Scenario 1(Check JavaDoc for the class) :
T inning = (T) gson.fromJson(reader, adapterclass);
list.add(inning);
} else if (token == JsonToken.BEGIN_ARRAY) {
reader.beginArray();
while (reader.hasNext()) {
#SuppressWarnings("unchecked")
T inning = (T) gson.fromJson(reader, adapterclass);
list.add(inning);
}
reader.endArray();
}
return list;
}
#Override
public void write(JsonWriter writer, List<T> value) throws IOException {
}
}
And register the adapter factory like this,
Gson gson = new GsonBuilder().registerTypeAdapterFactory(new ArrayAdapterFactory()).create();
public class Example {
private String url;
public String getUrl() {
return url;
}
public void setUrl(String url) {
this.url = url;
}
}
Use this link to generate POJO's
I have following json data
{"id":10606,
"name":"ProgrammerTitle",
"objectMap":{"programme-title":"TestProgramme","working-title":"TestProgramme"}
}
I want to set this data to my pojo object
public class TestObject {
private Long id;
private String name;
#JsonProperty("programme-title")
private String programmeTitle;
#JsonProperty("working-title")
private String workingTitle;
}
Here i am able to set id and name in my test object but for object map i am not able to set data.
So i have made on more class for ObjectMap which contains programmeTitle & workingTitle this works fine but i can't set this fields directly to my pojo object
is this possible to set?
I am using Jackson Object Mapper to convert json data.
It is working fine if i create another java object inside my pojo like:
public class TestObject {
private Long id;
private String name;
#JsonProperty("objectMap")
private ObjectMap objectMap;
public Long getId() {
return id;
}
public void setId(Long id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public ObjectMap getObjectMap() {
return objectMap;
}
public void setObjectMap(ObjectMap objectMap) {
this.objectMap = objectMap;
}
}
public class ObjectMap {
#JsonProperty("programme-title")
private String programmeTitle;
#JsonProperty("working-title")
private String workingTitle;
public String getProgrammeTitle() {
return programmeTitle;
}
public void setProgrammeTitle(String programmeTitle) {
this.programmeTitle = programmeTitle;
}
public String getWorkingTitle() {
return workingTitle;
}
public void setWorkingTitle(String workingTitle) {
this.workingTitle = workingTitle;
}
}
If your JSON is like this
{"id":10606,
"name":"ProgrammerTitle",
"objectMap":{"programme-title":"TestProgramme","working-title":"TestProgramme"}
}
then you may write your object mapper class like this..
public class Program{
public static class ObjectMap{
private String programme_title, working_title;
public String getprogramme_title() { return programme_title; }
public String getworking_title() { return working_title; }
public void setprogramme_title(String s) { programme_title= s; }
public void setworking_title(String s) { working_title= s; }
}
private ObjectMap objMap;
private String name;
public ObjectMap getobjectMap () { return objMap; }
public void setObjectMap (ObjectMap n) { objMap= n; }
private Long id;
public Long getId() {return id;}
public void setId(Long id) {this.id = id;}
private String name;
public String getName() {return name;}
public void setName(String name) {this.name = name;}
}
please refer this check it
You can write your own deserializer for this class:
class EntityJsonDeserializer extends JsonDeserializer<Entity> {
#Override
public Entity deserialize(JsonParser jp, DeserializationContext ctxt) throws IOException, JsonProcessingException {
Root root = jp.readValueAs(Root.class);
Entity entity = new Entity();
entity.setId(root.id);
entity.setName(root.name);
if (root.objectMap != null) {
entity.setProgrammeTitle(root.objectMap.programmeTitle);
entity.setWorkingTitle(root.objectMap.workingTitle);
}
return entity;
}
private static class Root {
public Long id;
public String name;
public Title objectMap;
}
private static class Title {
#JsonProperty("programme-title")
public String programmeTitle;
#JsonProperty("working-title")
public String workingTitle;
}
}
Your entity:
#JsonDeserialize(using = EntityJsonDeserializer.class)
class Entity {
private Long id;
private String name;
private String programmeTitle;
private String workingTitle;
//getters, setters, toString
}
And usage example:
import com.fasterxml.jackson.annotation.JsonProperty;
import com.fasterxml.jackson.core.JsonParser;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.DeserializationContext;
import com.fasterxml.jackson.databind.JsonDeserializer;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.annotation.JsonDeserialize;
public class JacksonProgram {
public static void main(String[] args) throws IOException {
ObjectMapper mapper = new ObjectMapper();
Entity entity = mapper.readValue(jsonString, Entity.class);
System.out.println(entity);
}
}
Above program prints:
Entity [id=10606, name=ProgrammerTitle, programmeTitle=TestProgramme, workingTitle=TestProgramme]