JSON Arraylist HashMap Extraction Android - java

Please bear with me with this.Follow through the whole code.I will be putting everything just to be clear:
And this is my json : you can format here
https://jsonformatter.curiousconcept.com/
[{"productLineItemId":5,"restaurantId":2,"productId":5,"catalogName":"Cold Drink","categoryName":"sprite","subCategoryName":"SPRITE ","productName":"SPRITE","price":20.0,"optionName":"no","optionValues":"200ML","veg":true,"spicy":false},{"productLineItemId":8,"restaurantId":2,"productId":5,"catalogName":"veg","categoryName":"south indian","subCategoryName":"rice","productName":"jeera Rice","price":888.0,"optionName":"notning","optionValues":"ooo","veg":true,"spicy":true},{"productLineItemId":100,"restaurantId":2,"productId":5,"catalogName":"non veg","categoryName":"south indian","subCategoryName":"hot briyani","productName":"briyani","price":9.0,"optionName":"plate","optionValues":"half","veg":true,"spicy":true}]
Now Here ,you can see inside that json we have 3 objects right now,which in future will be dynamic,means could be many number.So, my goal is to retrieve all those Json Objects and show them in a custom adaptor list.
Below these are my codes:
MainActivity.java
try {
httpClient2=new DefaultHttpClient();
StringBuilder stringBuilder2=new StringBuilder("xxxxxxxx");
httpPost2=new HttpPost(stringBuilder2.toString());
httpResponse2=httpClient2.execute(httpPost2);
code=httpResponse2.getStatusLine().getStatusCode();
httpPost2.setHeader(HTTP.CONTENT_TYPE,"application/json");
HttpEntity httpEntity2=httpResponse2.getEntity();
if(code<200 && code>=300){
Log.d("msg","Here <200 and >300");
}
else{
if(httpEntity2!=null){
cena= EntityUtils.toString(httpEntity2);
JSONArray jsonArray=new JSONArray(cena);
hashMapArrayList=new ArrayList<HashMap<String,String>>();
for(int i=0;i<jsonArray.length();i++) {
jsonObject = jsonArray.getJSONObject(i);
HashMap<String, String> hashMap = new HashMap<String, String>();
hashMap.put("Price", jsonObject.getString("price"));
hashMap.put("CategoryName", jsonObject.getString("categoryName"));
hashMap.put("ProductName", jsonObject.getString("productName"));
hashMap.put("CatalogName", jsonObject.getString("catalogName"));
hashMapArrayList.add(hashMap);
}
Intent intent = new Intent(MainActivity.this, Checkout.class);
intent.putExtra("arrayhash",hashMapArrayList);
startActivity(intent);
Log.d("cena","got something here"+cena.toString());
}
//Checkout.java
listView=(ListView)findViewById(R.id.listView);
hashMapArrayList2=(ArrayList<HashMap<String,String>>) getIntent().getSerializableExtra("arrayhash");
price_a = new String[hashMapArrayList2.size()];
categoryName_b = new String[hashMapArrayList2.size()];
productName_c = new String[hashMapArrayList2.size()];
catalogName_d = new String[hashMapArrayList2.size()];
int i=0;
for(Map<String,String> item:hashMapArrayList2){
price_a[i]=item.get("Price");
categoryName_b[i]=item.get("CategoryName");
productName_c[i]=item.get("ProductName");
catalogName_d[i]=item.get("CatalogName");
i++;
}
customAdapter=new CustomAdapter(Checkout.this,price_a,categoryName_b,productName_c,catalogName_d);
listView.setAdapter(customAdapter);
//This is my Custom Adaptor
public CustomAdapter(Context context,String price[],String categoryName[],String productName[],String catalogName[]){
this.context=context;
this.price=price;
this.categoryName=categoryName;
this.productName=productName;
this.catalogName=catalogName;
}
#Override
public int getCount() {
return price.length;
}
#Override
public Object getItem(int position) {
return position;
}
#Override
public long getItemId(int position) {
return position;
}
#Override
public View getView(int position, View convertView, ViewGroup parent) {
layoutInflater=(LayoutInflater)context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
View v=layoutInflater.inflate(R.layout.custom_row,null);
tv2=(TextView)v.findViewById(R.id.textView2);
tv3=(TextView)v.findViewById(R.id.textView3);
tv4=(TextView)v.findViewById(R.id.textView4);
tv5=(TextView)v.findViewById(R.id.textView5);
return v;
}
//So i Am getting output like this :
//Now You could see the problem,I have 3 json objects but I am getting only one which I am able to show.Could you show me where modificatiuons needs to be so that I could show all json objects(dynamic) in custom adapter.I hope you got the full understanding.And I am new to development and If I have done any mistakes then sorry,deeply appreciated.
After some modification suggested from comment section,I got these :
Duplicate

Just modify your logic as below
hashMapArrayList=new ArrayList<HashMap<String,String>>();
JSONArray jsonArray=new JSONArray(cena);
for(int i=0;i<jsonArray.length();i++) {
jsonObject = jsonArray.getJSONObject(i);
HashMap<String, String> hashMap = new HashMap<String, String>();
hashMap.put("Price", jsonObject.getString("price"));
hashMap.put("CategoryName", jsonObject.getString("categoryName"));
hashMap.put("ProductName", jsonObject.getString("productName"));
hashMap.put("CatalogName", jsonObject.getString("catalogName"));
hashMapArrayList.add(hashMap);
}
Just move HashMap<String, String> hashMap inside loop and add this one by one in hashMapArrayList

Modified code .
Initialize ArrayList out of the for loop and inside the for loop add the HashMap into the ArrayList
hashMapArrayList=new ArrayList<HashMap<String,String>>();
JSONArray jsonArray=new JSONArray(cena);
for(int i=0;i<jsonArray.length();i++) {
jsonObject = jsonArray.getJSONObject(i);
HashMap<String, String> hashMap = new HashMap<String, String>();
hashMap.put("Price", jsonObject.getString("price"));
hashMap.put("CategoryName", jsonObject.getString("categoryName"));
hashMap.put("ProductName", jsonObject.getString("productName"));
hashMap.put("CatalogName", jsonObject.getString("catalogName"));
hashMapArrayList.add(hashMap);
}

Use Gson for the Parsing
#Generated("org.jsonschema2pojo")
public class Example {
#SerializedName("productLineItemId")
#Expose
private Integer productLineItemId;
#SerializedName("restaurantId")
#Expose
private Integer restaurantId;
#SerializedName("productId")
#Expose
private Integer productId;
#SerializedName("catalogName")
#Expose
private String catalogName;
#SerializedName("categoryName")
#Expose
private String categoryName;
#SerializedName("subCategoryName")
#Expose
private String subCategoryName;
#SerializedName("productName")
#Expose
private String productName;
#SerializedName("price")
#Expose
private Double price;
#SerializedName("optionName")
#Expose
private String optionName;
#SerializedName("optionValues")
#Expose
private String optionValues;
#SerializedName("veg")
#Expose
private Boolean veg;
#SerializedName("spicy")
#Expose
private Boolean spicy;
/**
* #return The productLineItemId
*/
public Integer getProductLineItemId() {
return productLineItemId;
}
/**
* #param productLineItemId The productLineItemId
*/
public void setProductLineItemId(Integer productLineItemId) {
this.productLineItemId = productLineItemId;
}
/**
* #return The restaurantId
*/
public Integer getRestaurantId() {
return restaurantId;
}
/**
* #param restaurantId The restaurantId
*/
public void setRestaurantId(Integer restaurantId) {
this.restaurantId = restaurantId;
}
/**
* #return The productId
*/
public Integer getProductId() {
return productId;
}
/**
* #param productId The productId
*/
public void setProductId(Integer productId) {
this.productId = productId;
}
/**
* #return The catalogName
*/
public String getCatalogName() {
return catalogName;
}
/**
* #param catalogName The catalogName
*/
public void setCatalogName(String catalogName) {
this.catalogName = catalogName;
}
/**
* #return The categoryName
*/
public String getCategoryName() {
return categoryName;
}
/**
* #param categoryName The categoryName
*/
public void setCategoryName(String categoryName) {
this.categoryName = categoryName;
}
/**
* #return The subCategoryName
*/
public String getSubCategoryName() {
return subCategoryName;
}
/**
* #param subCategoryName The subCategoryName
*/
public void setSubCategoryName(String subCategoryName) {
this.subCategoryName = subCategoryName;
}
/**
* #return The productName
*/
public String getProductName() {
return productName;
}
/**
* #param productName The productName
*/
public void setProductName(String productName) {
this.productName = productName;
}
/**
* #return The price
*/
public Double getPrice() {
return price;
}
/**
* #param price The price
*/
public void setPrice(Double price) {
this.price = price;
}
/**
* #return The optionName
*/
public String getOptionName() {
return optionName;
}
/**
* #param optionName The optionName
*/
public void setOptionName(String optionName) {
this.optionName = optionName;
}
/**
* #return The optionValues
*/
public String getOptionValues() {
return optionValues;
}
/**
* #param optionValues The optionValues
*/
public void setOptionValues(String optionValues) {
this.optionValues = optionValues;
}
/**
* #return The veg
*/
public Boolean getVeg() {
return veg;
}
/**
* #param veg The veg
*/
public void setVeg(Boolean veg) {
this.veg = veg;
}
/**
* #return The spicy
*/
public Boolean getSpicy() {
return spicy;
}
/**
* #param spicy The spicy
*/
public void setSpicy(Boolean spicy) {
this.spicy = spicy;
}
}
Example exampleObj = new Example();
Gson gson = new Gson();
JsonArray jsonArray = new JsonArray(response.string);
exampleObj=gson.fromJson(response.string,Example.class);

Related

How do I deserialize my immutable subclass?

I'm currently trying to deserialize a json-response. My object uses the builder pattern and the consumer interface.
I'm doing a http-request to an external source and get my response as json. All the responses are strings and look like:
{
"a": "198",
"b": "F",
"c": "30",
"d": "2019-02-01",
"e": "2019-12-31"
}
I've changed the name of my model and my key to Model and Key so there might be typos, sorry for that.
#JsonDeserialize(builder = Model.Builder.class)
public class Model {
private final Data data;
private Model() {
this.data = new Data();
}
/**
* #return key
*/
public Key getKey() {
return data.key;
}
/**
* #return Tax Form
*/
public String getTaxForm() {
return data.taxForm;
}
/**
* #return tax table
*/
public int getTaxTable() {
return data.taxTable;
}
/**
* #return tax percent
*/
public BigDecimal getTaxPercent() {
return data.taxPercent;
}
/**
* #return Valid from
*/
public LocalDate getValidFrom() {
return data.validFrom;
}
/**
* #return Valid to
*/
public LocalDate getValidTo() {
return data.validTo;
}
/**
* #param key key
* #return builder
*/
public static Builder getBuilder(Key key) {
return new Builder(key);
}
/**
* #param model the response
* #return builder
*/
public static Builder getBuilder(Model model) {
return new Builder(model);
}
/**
* builder
*/
public static class Builder {
#JsonDeserialize(as = Model.Data.class)
private final Data data;
#JsonCreator
private Builder(Key key) {
this.data = new Data();
this.data.key = key;
}
private Builder(Model model) {
this(model.data.key);
data.taxForm = model.data.taxForm;
data.taxTable = model.data.taxTable;
data.taxPercent = model.data.taxPercent;
data.validFrom = model.data.validFrom;
data.validTo = model.data.validTo;
}
public Builder with(Consumer<Data> consumer) {
consumer.accept(this.data);
return this;
}
public Model build() {
Model internalModel = new Model();
internalModel.data.key = data.key;
internalModel.data.taxForm = data.taxForm;
internalModel.data.taxTable = data.taxTable;
internalModel.data.taxPercent = data.taxPercent;
internalModel.data.validFrom = data.validFrom;
internalModel.data.validTo = data.validTo;
return internalModel;
}
}
/**
* Data
*/
public static final class Data implements Serializable {
private Key key;
#JsonProperty("b")
public String taxForm;
public int taxTable;
public BigDecimal taxPercent;
public LocalDate validFrom;
public LocalDate validTo;
}
}
public class Key {
private final String personalNumber;
public Key(#JsonProperty("a") String personalNumber) {
this.personalNumber = personalNumber;
}
public String getPersonalNumber() {
return personalNumber;
}
}
Currently I am able to deserialize a, but all the other fields are missed. I tried using #JsonProperty in the Data class but that doesn't work. Any ideas?

How can i set this JSON with dynamic keys in POJO and get data from it in Android JAVA?

I am developing an e-commerce app and I am getting this JSON data from API.
{"status": 0, "data": {"stores": {"test-5": {"name": "Test 5", "locality": {"name": "Some place B", "id": 2}, "cover": "IMAGE-URL-HERE"}, "test-2": {"name": "Test 2", "locality": {"name": "Some place A", "id": 2}, "cover": "IMAGE-URL-HERE"}}}, "action": [["DATA", "stores"]]}
I have created some POJO for this data too
public class PartnerStoreMainPOJO {
#SerializedName("partnerstore")
#Expose
private PartnerStoresPOJO partnerstore;
/**
*
* #return
* The data
*/
public PartnerStoresPOJO getPartnerStore() {
return partnerstore;
}
/**
*
* #param partnerstore
* The data
*/
public void setPartnerStore(PartnerStoresPOJO partnerstore) {
this.partnerstore = partnerstore;
}
}
//-------------
public class PartnerStoresPOJO {
#SerializedName("partnerstoredetail")
#Expose
private Map<String, PartnerStoreDetailPOJO> partnerstoredetail;
/**
*
* #return
* The feeds
*/
public Map<String, PartnerStoreDetailPOJO> getpartnerstoredetail() {
return partnerstoredetail;
}
/**
*
* #param partnerstoredetail
* The feeds
*/
public void setpartnerstoredetail(Map<String, PartnerStoreDetailPOJO> partnerstoredetail) {
this.partnerstoredetail = partnerstoredetail;
}
}
//----------------
public class PartnerStoreDetailPOJO {
#SerializedName("partnerstorelocality")
#Expose
private Map<String, PartnerStoreLocalityPOJO> partnerstorelocality;
#SerializedName("cover")
#Expose
private String cover;
#SerializedName("name")
#Expose
private String name;
/**
* #return The name
*/
public String getName() {
return name;
}
/**
* #param name The name
*/
public void setName(String name) {
this.name = name;
}
/**
* #return The cover
*/
public String getCover() {
return cover;
}
/**
* #param cover The address
*/
public void setCover(String cover) {
this.cover = cover;
}
public Map<String, PartnerStoreLocalityPOJO> getpartnerstorelocality() {
return partnerstorelocality;
}
public void setpartnerstorelocality(Map<String, PartnerStoreLocalityPOJO> partnerstorelocality) {
this.partnerstorelocality = partnerstorelocality;
}
}
//----------------
public class PartnerStoreLocalityPOJO {
#SerializedName("name")
#Expose
private String name;
#SerializedName("id")
#Expose
private String id;
/**
*
* #return
* The name
*/
public String getName() {
return name;
}
/**
*
* #param name
* The name
*/
public void setName(String name) {
this.name = name;
}
/**
*
* #return
* The id
*/
public String getId() {
return id;
}
/**
*
* #param id
* The id
*/
public void setId(String id) {
this.id = id;
}
}
//---------------
Amd i am using volley library. This is my java code-
public void onResultReceived(String response, String tag_json_obj) {
if (tag_json_obj.equals(LOCALITY_SET)){
try {
JSONObject jsonObject=new JSONObject(response);
String data=jsonObject.getString("data");
} catch (JSONException e) {
Log.d("EXCEPTN",e.toString());
e.printStackTrace();
}
}
}
I am using that data string.
Try it once: Do changes accordingly, It can give you a direction for your query.
public void convertJSON(JSONObject jsonObject) {
try {
JSONObject object = jsonObject.getJSONObject("data");
Iterator<String> iter = object.keys();
while (iter.hasNext()) {
String key = iter.next();
Object value = object.get(key);
JSONObject obj2 = object.getJSONObject(key);
//set key to POJO
Iterator<String> iter2 = obj2.keys();
while (iter2.hasNext()) {
String key2 = iter2.next();
//....so on
}
}
} catch (JSONException e) {
e.printStackTrace();
}
}

Deserialize Array Of Objects with the first item being the counter of the elements

Hello i was trying to deserialize the following JSON response from a Web Api:
{
"response": [
370968,
{
"aid": 65843156,
"owner_id": 17519165,
"artist": "Bass Test",
"title": "дурной басс!",
"duration": 238,
"url": "http://cs6-10v4.vk-cdn.net/p22/c412a04df93035.mp3?extra=9YguhLftfZDDwo4JKBVwvlx_V1vwlu5pNU4-WremEqM9bL8eN2vh3_qu7bAg9EgNCj0ztEcMurarC499x8X2MpUaipykG2LDueWe0QQMrIPplkxKdV1xcQp35baDwA84l-luVxai9maX",
"lyrics_id": "6214304"
},
{
"aid": 207425918,
"owner_id": 96085484,
"artist": "► DJ Pleased",
"title": "Bass Test № 04 (New 2013)",
"duration": 328,
"url": "http://cs6-7v4.vk-cdn.net/p23/6d7071221fb912.mp3?extra=O5ih5W5YkaEkXhHQSOKeDzvtr0V8xyS1WhIgjYLROFOMcW__FpU3mSf5udwdEAq6kkcz7QSy5jB57rTgSxnRJXCySZy2b0J_a2DvzFUBqVX6lcKqlarTryP_loQyk-SYPbFLh-9mSzm_iA",
"lyrics_id": "86651563",
"genre": 10
}
]
}
My intention is to build a class to get the items in the response and use them in my Java Android application. The problem is that the first item of the response array is a number and not an object like the next items. So when I parse it with Gson it gives me the error:
com.google.gson.JsonSyntaxException: java.lang.IllegalStateException: Expected BEGIN_OBJECT but was NUMBER at line 1 column 20 path $.response[0]
I used the retrofit android library with the following POJO class (witch works if i don't have the counter in the response):
import java.util.HashMap;
import java.util.Map;
public class Response {
private Integer aid;
private Integer ownerId;
private String artist;
private String title;
private Integer duration;
private String url;
private String lyricsId;
private Integer genre;
private String album;
private Map<String, Object> additionalProperties = new HashMap<String, Object>();
/**
*
* #return
* The aid
*/
public Integer getAid() {
return aid;
}
/**
*
* #param aid
* The aid
*/
public void setAid(Integer aid) {
this.aid = aid;
}
/**
*
* #return
* The ownerId
*/
public Integer getOwnerId() {
return ownerId;
}
/**
*
* #param ownerId
* The owner_id
*/
public void setOwnerId(Integer ownerId) {
this.ownerId = ownerId;
}
/**
*
* #return
* The artist
*/
public String getArtist() {
return artist;
}
/**
*
* #param artist
* The artist
*/
public void setArtist(String artist) {
this.artist = artist;
}
/**
*
* #return
* The title
*/
public String getTitle() {
return title;
}
/**
*
* #param title
* The title
*/
public void setTitle(String title) {
this.title = title;
}
/**
*
* #return
* The duration
*/
public Integer getDuration() {
return duration;
}
/**
*
* #param duration
* The duration
*/
public void setDuration(Integer duration) {
this.duration = duration;
}
/**
*
* #return
* The url
*/
public String getUrl() {
return url;
}
/**
*
* #param url
* The url
*/
public void setUrl(String url) {
this.url = url;
}
/**
*
* #return
* The lyricsId
*/
public String getLyricsId() {
return lyricsId;
}
/**
*
* #param lyricsId
* The lyrics_id
*/
public void setLyricsId(String lyricsId) {
this.lyricsId = lyricsId;
}
/**
*
* #return
* The genre
*/
public Integer getGenre() {
return genre;
}
/**
*
* #param genre
* The genre
*/
public void setGenre(Integer genre) {
this.genre = genre;
}
/**
*
* #return
* The album
*/
public String getAlbum() {
return album;
}
/**
*
* #param album
* The album
*/
public void setAlbum(String album) {
this.album = album;
}
public Map<String, Object> getAdditionalProperties() {
return this.additionalProperties;
}
public void setAdditionalProperty(String name, Object value) {
this.additionalProperties.put(name, value);
}
Is there any way to make it work? I don't have access to the API server so i cant change how the result is displayed. To generate the class i used http://www.jsonschema2pojo.org/ but i was able to generate it only by removing the counter from the response.
The wrapper class VKSongApi:
public class VKSongApi {
private List<Response> response = new ArrayList<Response>();
private Map<String, Object> additionalProperties = new HashMap<String, Object>();
/**
*
* #return
* The response
*/
public List<Response> getResponse() {
return response;
}
/**
*
* #param response
* The response
*/
public void setResponse(List<Response> response) {
this.response = response;
}
public Map<String, Object> getAdditionalProperties() {
return this.additionalProperties;
}
public void setAdditionalProperty(String name, Object value) {
this.additionalProperties.put(name, value);
}
}
The retrofit interface class is:
public interface VKApi {
#GET("/method/audio.search")
Call<VKSongApi> search(#Query("q") String query, #Query("access_token") String token);
}
Then in the MainActivity i do:
public static final String BASE_URL = "https://api.vk.com/method/";
Retrofit retrofit = new Retrofit.Builder()
.baseUrl(BASE_URL)
.addConverterFactory(GsonConverterFactory.create())
.build();
VKApi apiService =
retrofit.create(VKApi.class);
And call the method from the MainActivity with:
Call<VKSongApi> call = apiService.search("test","fff9ef502df4bb10d9bf50dcd62170a24c69e98e4d847d9798d63dacf474b674f9a512b2b3f7e8ebf1d69");
call.enqueue(new Callback<VKSongApi>() {
#Override
public void onResponse(Call<VKSongApi> call, Response<VKSongApi> response) {
int statusCode = response.code();
VKSongApi song = response.body();
Log.d(TAG,response.message());
}
#Override
public void onFailure(Call<VKSongApi> call, Throwable t) {
//Here the error occurs com.google.gson.JsonSyntaxException: java.lang.IllegalStateException: Expected BEGIN_OBJECT but was NUMBER at line 1 column 20 path $.response[0]
Log.d(TAG,"Failure");
}
});
I solved by parsing manually the response using a custom deserializer class

Java Bean Return Value is Null

I'm getting a problem with the return value after the post request, the response string contains the requested JSON text but the dataBean is null ??
#Override
public wDataBean doInBackground(Void... params) {
wDataBean dataBean = new wDataBean();
try {
Response response = client.newCall(request).execute();
String responseString = response.body().string();
JSONObject jsonObject = new JSONObject(responseString);
Gson gson = new Gson();
dataBean = gson.fromJson(jsonObject.toString(), wDataBean.class);
}
catch (final IOException e)
{
runOnUiThread(new Runnable() {
#Override
public void run() {
Toast.makeText(MainActivity.this,e.getMessage(),Toast.LENGTH_SHORT).show();
}
});
} catch (JSONException e) {
e.printStackTrace();
Toast.makeText(MainActivity.this,e.getMessage(),Toast.LENGTH_SHORT).show();
}
return dataBean;
}
This is a sample of the response:
{ "IsOK":true,
"Response":"Logged in successfully",
"MyArray":{ "user":"35",
"email":"email#domain.com",
"img":"https:\/\/www.mywebsite.com\/uploads\/136_image.png",
"fname":"First Name",
"lname":"Last Name",
"myToken":
{
"auth":"xyzxyzyxyzxyzxyzxyzxyzxyzxyzxyzxyzxyz",
"expiry":"1980-01-01 00:00:00"
}
},
"myToken":{}
}
wDataBean.java
public class wDataBean {
private Main1 main;
public Main1 getMain() {return main;}
public void setMain(Main1 main) {this.main = main;}
class Main1 {
boolean IsOK;
String Response;
JSONArray MyArray;
int user;
String email;
String img;
String fname;
String lname;
JSONArray myToken;
String auth;
Date expiry;
public boolean isOK() {return isOK();}
public int getUser() {return user;}
public JSONArray getMyArray() {return MyArray;}
public String getEmail() {return email;}
public String getImg() {return img;}
public String getResponse() {return Response;}
public Date getExpiry() {return expiry;}
public JSONArray getMyToken() {return myToken;}
public String getAuth() {return auth;}
public String getFname() {return fname;}
public String getLname() {return lname;}
public void setAuth(String auth) {this.auth = auth;}
public void setEmail(String email) {this.email = email;}
public void setExpiry(Date expiry) {this.expiry = expiry;}
public void setFname(String fname) {this.fname = fname;}
public void setImg(String img) {this.img = img;}
public void setLname(String lname) {this.lname = lname;}
public void setMyArray(JSONArray myArray) {MyArray = myArray;}
public void setMyToken(JSONArray myToken) {this.myToken = myToken;}
public void setOK(boolean OK) {IsOK = OK;}
public void setResponse(String response) { Response = response;}
public void setUser(int user) { this.user = user;}
}
}
The goal is to get "auth" and "expiry" from myToken
This should be your bean class -
public class WDataBean {
#SerializedName("IsOK")
#Expose
private Boolean isOK;
#SerializedName("Response")
#Expose
private String response;
#SerializedName("MyArray")
#Expose
private MyArray myArray;
#SerializedName("myToken")
#Expose
private MyToken_ myToken;
/**
*
* #return
* The isOK
*/
public Boolean getIsOK() {
return isOK;
}
/**
*
* #param isOK
* The IsOK
*/
public void setIsOK(Boolean isOK) {
this.isOK = isOK;
}
/**
*
* #return
* The response
*/
public String getResponse() {
return response;
}
/**
*
* #param response
* The Response
*/
public void setResponse(String response) {
this.response = response;
}
/**
*
* #return
* The myArray
*/
public MyArray getMyArray() {
return myArray;
}
/**
*
* #param myArray
* The MyArray
*/
public void setMyArray(MyArray myArray) {
this.myArray = myArray;
}
/**
*
* #return
* The myToken
*/
public MyToken_ getMyToken() {
return myToken;
}
/**
*
* #param myToken
* The myToken
*/
public void setMyToken(MyToken_ myToken) {
this.myToken = myToken;
}
public class MyToken_ {
}
public class MyToken {
#SerializedName("auth")
#Expose
private String auth;
#SerializedName("expiry")
#Expose
private String expiry;
/**
*
* #return
* The auth
*/
public String getAuth() {
return auth;
}
/**
*
* #param auth
* The auth
*/
public void setAuth(String auth) {
this.auth = auth;
}
/**
*
* #return
* The expiry
*/
public String getExpiry() {
return expiry;
}
/**
*
* #param expiry
* The expiry
*/
public void setExpiry(String expiry) {
this.expiry = expiry;
}
}
public class MyArray {
#SerializedName("user")
#Expose
private String user;
#SerializedName("email")
#Expose
private String email;
#SerializedName("img")
#Expose
private String img;
#SerializedName("fname")
#Expose
private String fname;
#SerializedName("lname")
#Expose
private String lname;
#SerializedName("myToken")
#Expose
private MyToken myToken;
/**
*
* #return
* The user
*/
public String getUser() {
return user;
}
/**
*
* #param user
* The user
*/
public void setUser(String user) {
this.user = user;
}
/**
*
* #return
* The email
*/
public String getEmail() {
return email;
}
/**
*
* #param email
* The email
*/
public void setEmail(String email) {
this.email = email;
}
/**
*
* #return
* The img
*/
public String getImg() {
return img;
}
/**
*
* #param img
* The img
*/
public void setImg(String img) {
this.img = img;
}
/**
*
* #return
* The fname
*/
public String getFname() {
return fname;
}
/**
*
* #param fname
* The fname
*/
public void setFname(String fname) {
this.fname = fname;
}
/**
*
* #return
* The lname
*/
public String getLname() {
return lname;
}
/**
*
* #param lname
* The lname
*/
public void setLname(String lname) {
this.lname = lname;
}
/**
*
* #return
* The myToken
*/
public MyToken getMyToken() {
return myToken;
}
/**
*
* #param myToken
* The myToken
*/
public void setMyToken(MyToken myToken) {
this.myToken = myToken;
}
}
}
Can you show me the class wDataBean?
But I venture to say that this can solve
Gson gson = new GsonBuilder().setDateFormat("yyyy-mm-dd HH:mm:ss").create();

Android GSON POJO optional field parsing

Ok so heres the thing I am working with an api that for one JSON parameter can return two different types. So I can receive from the server either a JSON Object or a String. I'm pretty new to Android development so if someone could explain to me with maybe a code example how I can handle that problem.
Example json responses {video:"ID OF VIDEO"} or {video:{id:"ID OF VIDEO",...extra data}}. I had a look at custom deserialisers but can't find an example that is easy to follow. There must be a simple way of solving my problem. Currently I receive error "Expected string but found BEGIN OBJECT"
import com.google.gson.annotations.Expose;
import com.google.gson.annotations.SerializedName;
public class MyNotification {
#SerializedName("_id")
#Expose
private String Id;
#SerializedName("comment")
#Expose
private String comment;
#SerializedName("createdAt")
#Expose
private String createdAt;
#SerializedName("message")
#Expose
private String message;
#SerializedName("read")
#Expose
private Boolean read;
#SerializedName("recipient")
#Expose
private String recipient;
#SerializedName("sender")
#Expose
private User sender;
#SerializedName("type")
#Expose
private String type;
// #SerializedName("video")
// #Expose
// private String video;
/**
*
* #return
* The Id
*/
public String getId() {
return Id;
}
/**
*
* #param Id
* The _id
*/
public void setId(String Id) {
this.Id = Id;
}
/**
*
* #return
* The comment
*/
public String getComment() {
return comment;
}
/**
*
* #param comment
* The comment
*/
public void setComment(String comment) {
this.comment = comment;
}
/**
*
* #return
* The createdAt
*/
public String getCreatedAt() {
return createdAt;
}
/**
*
* #param createdAt
* The createdAt
*/
public void setCreatedAt(String createdAt) {
this.createdAt = createdAt;
}
/**
*
* #return
* The message
*/
public String getMessage() {
return message;
}
/**
*
* #param message
* The message
*/
public void setMessage(String message) {
this.message = message;
}
/**
*
* #return
* The read
*/
public Boolean getRead() {
return read;
}
/**
*
* #param read
* The read
*/
public void setRead(Boolean read) {
this.read = read;
}
/**
*
* #return
* The recipient
*/
public String getRecipient() {
return recipient;
}
/**
*
* #param recipient
* The recipient
*/
public void setRecipient(String recipient) {
this.recipient = recipient;
}
/**
*
* #return
* The sender
*/
public User getSender() {
return sender;
}
/**
*
* #param sender
* The sender
*/
public void setSender(User sender) {
this.sender = sender;
}
/**
*
* #return
* The type
*/
public String getType() {
return type;
}
/**
*
* #param type
* The type
*/
public void setType(String type) {
this.type = type;
}
// /**
// *
// * #return
// * The video
// */
// public String getVideo() {
// return video;
// }
//
// /**
// *
// * #param video
// * The video
// */
// public void setVideo(String video) {
// this.video = video;
// }
}
and the part that craps out
Gson gson = new Gson();
String jsonString = String.valueOf(dataset);
Type listType = new TypeToken<List<MyNotification>>(){}.getType();
notficationsList = (List<MyNotification>) gson.fromJson(jsonString, listType);
Sorry it took so long:
Your best bet is to repair the JSON, if you must map it to an Object.
Try cleaning the JSON with this code:
public static String cleanJson(String json) {
int videoPos = json.indexOf("video");
if(videoPos == -1) {
return json; //return, no video here
}
boolean isObject = false;
int objectBegin = -1;
String cleanedJson = json.replaceAll("\\\"", "\\\\");
for(int i = videoPos; i < cleanedJson.length(); i++) {
if(cleanedJson.charAt(i) == '"') {
System.out.println("string");
return json; // its a string anyway
}
if(cleanedJson.charAt(i) == '{') {
//its an object
// i now is the position beginning the object
objectBegin = i;
}
} //replace " with space
if(objectBegin == -1) {// we did not find any { or " it is a string
return json;
}
boolean inString = false;
int objectEnd = -1;
for(int i = objectBegin; i < cleanedJson.length(); i++) {
//looking for the end of the object;
if(cleanedJson.charAt(i) == '"') inString = !inString;
if(cleanedJson.charAt(i) == '}') {
objectEnd = i;
break;
}
}
if(objectEnd != -1) {
String start = json.substring(0,objectBegin);
String videoPart = json.substring(objectBegin, objectEnd+1);
String end = json.substring(objectEnd+1);
// now we want to get the id
String newVideoPart = "";
int idStart = videoPart.indexOf("id");
int idStringStart = -1;
int idStringEnd = -1;
for(int i = idStart; i < videoPart.length(); i++) {
if(videoPart.charAt(i) == '"') {
if(idStringStart == -1) {
idStringStart = i;
} else {
idStringEnd = i;
break;
}
}
}
if(idStringStart != -1 && idStringEnd != -1) {
newVideoPart = videoPart.substring(idStringStart, idStringEnd+1);
}
return start+newVideoPart+end;
}
return json;
}
Works with these two test jsons:
System.out.println(cleanJson("{video:\"1234\"}"));
System.out.println(cleanJson("{video:{id:\"2345\", name=\"test\"}}"));
Try it like this:
notficationsList = (List<MyNotification>) gson.fromJson(cleanJson(jsonString), listType);
Ok so the solution I went with I wrote my own type adapter that gson allow you to use
public class Helper_StringAdapter extends TypeAdapter<String>{
#Override
public String read(com.google.gson.stream.JsonReader in) throws IOException {
if(in.peek() == JsonToken.NULL){
in.nextNull();
return null;
}else if(in.peek() == JsonToken.BEGIN_OBJECT && in.getPath().contains(".video")){
L.e("VIDEO IS AN OBJECT!");
String userId = readAndReturnVideoId(in);
return userId;
}else{
return in.nextString();
}
}
private String readAndReturnVideoId(com.google.gson.stream.JsonReader reader) throws IOException{
String id = "";
reader.beginObject();
while(reader.hasNext()){
String name = reader.nextName();
if(name.equals("_id")){
id = reader.nextString();
}else{
reader.skipValue();
}
}
reader.endObject();
L.e("READ ID RETURNED"+id);
return id;
}
#Override
public void write(com.google.gson.stream.JsonWriter out, String value) throws IOException {
L.e("TEST "+out);
}
}
Then in my activity data manager (Recyclerview Adapter)
public void updateData (JSONArray dataset) {
GsonBuilder gsonb = new GsonBuilder();
gsonb.registerTypeAdapter(String.class,new Helper_StringAdapter());
Gson gson = gsonb.create();
String jsonString = String.valueOf(dataset);
Type listType = new TypeToken<List<FrameNotification>>(){}.getType();
notficationsList = (List<FrameNotification>) gson.fromJson(jsonString, listType);
}
Seems to do the job

Categories

Resources