Android GSON POJO optional field parsing - java

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

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();
}
}

Spring Mongodb pagination of nested collection field

I have a collection of document inside another document. Would like to implement pagination on nested element while fetching the data. Could you please let me know how to do that? In the structure I would like to fetch messages using pagination.
public abstract class CommonDomainAttributes implements Serializable, Cloneable {
private static final long serialVersionUID = 1L;
#Id
protected String id;
#JsonIgnore
#CreatedDate
protected Date createDate;
//#JsonIgnore
#LastModifiedDate
//#JsonSerialize(using=JsonDateSerializer.class)
protected Date lastModifiedDate;
#JsonIgnore
#CreatedBy
protected String createdBy;
#JsonIgnore
#LastModifiedBy
protected String lastModifiedBy;
/**
* #return the id
*/
public String getId() {
return id;
}
/**
* #param id the id to set
*/
public void setId(String id) {
this.id = id;
}
/**
* #return the createDate
*/
public Date getCreateDate() {
return createDate;
}
/**
* #param createDate the createDate to set
*/
public void setCreateDate(Date createDate) {
this.createDate = createDate;
}
/**
* #return the lastModifiedDate
*/
public Date getLastModifiedDate() {
return lastModifiedDate;
}
/**
* #param lastModifiedDate the lastModifiedDate to set
*/
public void setLastModifiedDate(Date lastModifiedDate) {
this.lastModifiedDate = lastModifiedDate;
}
/**
* #return the createdBy
*/
public String getCreatedBy() {
return createdBy;
}
/**
* #param createdBy the createdBy to set
*/
public void setCreatedBy(String createdBy) {
this.createdBy = createdBy;
}
/**
* #return the lastModifiedBy
*/
public String getLastModifiedBy() {
return lastModifiedBy;
}
/**
* #param lastModifiedBy the lastModifiedBy to set
*/
public void setLastModifiedBy(String lastModifiedBy) {
this.lastModifiedBy = lastModifiedBy;
}
/* (non-Javadoc)
* #see java.lang.Object#hashCode()
*/
#Override
public int hashCode() {
final int prime = 31;
int result = 1;
result = prime * result + (id == null ? 0 : id.hashCode());
return result;
}
/* (non-Javadoc)
* #see java.lang.Object#equals(java.lang.Object)
*/
#Override
public boolean equals(Object obj) {
if (this == obj) {
return true;
}
if (obj == null) {
return false;
}
if (getClass() != obj.getClass()) {
return false;
}
CommonDomainAttributes other = (CommonDomainAttributes) obj;
if (id == null) {
if (other.id != null) {
return false;
}
} else if (!id.equals(other.id)) {
return false;
}
return true;
}
/* (non-Javadoc)
* #see java.lang.Object#toString()
*/
#Override
public String toString() {
StringBuilder builder = new StringBuilder();
builder.append("CommonDomainAttributes [id=").append(id)
.append(", createDate=").append(createDate)
.append(", lastModifiedDate=").append(lastModifiedDate)
.append(", createdBy=").append(createdBy)
.append(", lastModifiedBy=").append(lastModifiedBy)
.append(", toString()=").append(super.toString()).append("]");
return builder.toString();
}
}
public class Message extends CommonDomainAttributes implements Serializable{
private String fromuserId;
private String fromuserName;
private String toUserId;
private String touserName;
private String message;
/**
* #return the fromuserId
*/
public String getFromuserId() {
return fromuserId;
}
/**
* #param fromuserId the fromuserId to set
*/
public void setFromuserId(String fromuserId) {
this.fromuserId = fromuserId;
}
/**
* #return the fromuserName
*/
public String getFromuserName() {
return fromuserName;
}
/**
* #param fromuserName the fromuserName to set
*/
public void setFromuserName(String fromuserName) {
this.fromuserName = fromuserName;
}
/**
* #return the toUserId
*/
public String getToUserId() {
return toUserId;
}
/**
* #param toUserId the toUserId to set
*/
public void setToUserId(String toUserId) {
this.toUserId = toUserId;
}
/**
* #return the touserName
*/
public String getTouserName() {
return touserName;
}
/**
* #param touserName the touserName to set
*/
public void setTouserName(String touserName) {
this.touserName = touserName;
}
/**
* #return the message
*/
public String getMessage() {
return message;
}
/**
* #param message the message to set
*/
public void setMessage(String message) {
this.message = message;
}
/* (non-Javadoc)
* #see java.lang.Object#toString()
*/
#Override
public String toString() {
StringBuilder builder = new StringBuilder();
builder.append("Message [fromuserId=");
builder.append(fromuserId);
builder.append(", fromuserName=");
builder.append(fromuserName);
builder.append(", toUserId=");
builder.append(toUserId);
builder.append(", touserName=");
builder.append(touserName);
builder.append(", message=");
builder.append(message);
builder.append(", toString()=");
builder.append(super.toString());
builder.append("]");
return builder.toString();
}
}
#Document(collection="discussion")
#TypeAlias("discussion")
public class Discussion extends CommonDomainAttributes implements Serializable{
private String discussionTopic;
private List<Message> messages;
/**
* #return the discussionTopic
*/
public String getDiscussionTopic() {
return discussionTopic;
}
/**
* #param discussionTopic the discussionTopic to set
*/
public void setDiscussionTopic(String discussionTopic) {
this.discussionTopic = discussionTopic;
}
/**
* #return the messages
*/
public List<Message> getMessages() {
return messages;
}
/**
* #param messages the messages to set
*/
public void setMessages(List<Message> messages) {
this.messages = messages;
}
/**
* #param messages the messages to set
*/
public void addMessages(Message message) {
if(null == messages){
messages = new LinkedList<>();
}
messages.add(message);
}
/* (non-Javadoc)
* #see java.lang.Object#toString()
*/
#Override
public String toString() {
StringBuilder builder = new StringBuilder();
builder.append("Discussion [discussionTopic=");
builder.append(discussionTopic);
builder.append(", messages=");
builder.append(messages);
builder.append(", toString()=");
builder.append(super.toString());
builder.append("]");
return builder.toString();
}
}
A bit on Mongo Query Language
In MongoDB, the $slice operator controls the number of items of an array that a query returns. The $slice operator can accept values with following syntax:
[toSkip, toLimit]
Where the first value indicates the number of items in the array to skip and the second value indicates the number of items to return. For example, you can use the following query:
db.discussions.find({}, {messages: {$slice: [20, 10]}})
To return 10 messages, after skipping the first 20 messages of that array.
Bring it to Spring Data World
In order to use $slice operator with Spring Data MongoDB, you should use #Query annotation and its fields attribute. For example, if you have a DiscussionRepository, you could write something like:
public interface DiscussionRepository extends MongoRepository<Discussion, String> {
#Query(value = "{}", fields = "{messages: {$slice: [?0, ?1]}}")
List<Discussion> findDiscussions(int skip, int limit);
}
With this arrangement, following method call:
discussionRepository.findDiscussions(20, 10)
Would generate the same result as:
db.discussions.find({}, {messages: {$slice: [20, 10]}})
With a little bit of work, you can turn the Skip/Limit combination to a pagination functionality.

JSON Arraylist HashMap Extraction Android

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);

How to fix Out of START_ARRAY token Error

Can anybody say where I am doing wrong. I have json like that
[{"name":"foo","slug":"foo2","locales":["foo3"],"hostname":"foo4","region_tag":"foo5"},{"name":"foo","slug":"foo2","locales":["foo3"],"hostname":"foo4","region_tag":"foo5"},{"name":"foo","slug":"foo2","locales":["foo3"],"hostname":"foo4","region_tag":"foo5"},{"name":"foo","slug":"foo2","locales":["foo3"],"hostname":"foo4","region_tag":"foo5"}]
And I parse to this class.
#JsonSerialize(include = JsonSerialize.Inclusion.NON_NULL)
#JsonPropertyOrder({
"shards"
})
public class ShardsResponse extends Response{
#JsonProperty("shards")
private List<Shards> shards = new ArrayList<Shards>();
/**
*
* #return
* The shards
*/
#JsonProperty("shards")
public List<Shards> getShards() {
return shards;
}
/**
*
* #param shards
* The shards
*/
#JsonProperty("shards")
public void setShards(List<Shards> shards) {
this.shards = shards;
}
}
And Shards class is :
/**
*
* #return
* The locales
*/
#JsonProperty("locales")
public List<String> getLocales() {
return locales;
}
/**
*
* #param locales
* The locales
*/
#JsonProperty("locales")
public void setLocales(List<String> locales) {
this.locales = locales;
}
/**
*
* #return
* The name
*/
#JsonProperty("name")
public String getName() {
return name;
}
/**
*
* #param name
* The name
*/
#JsonProperty("name")
public void setName(String name) {
this.name = name;
}
/**
*
* #return
* The hostname
*/
#JsonProperty("hostname")
public String getHostname() {
return hostname;
}
/**
*
* #param hostname
* The hostname
*/
#JsonProperty("hostname")
public void setHostname(String hostname) {
this.hostname = hostname;
}
/**
*
* #return
* The slug
*/
#JsonProperty("slug")
public String getSlug() {
return slug;
}
/**
*
* #param slug
* The slug
*/
#JsonProperty("slug")
public void setSlug(String slug) {
this.slug = slug;
}
}
So I'm using ObjectMapper.readValue(jsontext, responseclass)
JSONObject object = new JSONObject(JsonString);
JsonString = "";
Iterator<String> keys= object.keys();
while (keys.hasNext()){
String keyValue = (String)keys.next();
JsonString= JsonString+ object.getString(keyValue);
}
JsonString= JsonString.substring(1, JsonString.length()-1);
Object response = ObjectMapper.readValue(JsonString, ShardsResponse.class);
At the last I am getting out of START_ARRAY token. Please anybody tell me what's wrong.
Cause I'm trying so much things, but I never find the solution.
How can I fix it.
Your json string is correct, but not for the object you expect, as someone mentioned already, you need to use a List
import java.io.IOException;
import java.util.List;
import org.codehaus.jackson.map.ObjectMapper;
import org.codehaus.jackson.type.TypeReference;
public class ParseJson {
private static final String jsonString = "[{\"name\":\"foo\",\"slug\":\"foo2\",\"locales\":[\"foo3\"],\"hostname\":\"foo4\",\"region_tag\":\"foo5\"},{\"name\":\"foo\",\"slug\":\"foo2\",\"locales\":[\"foo3\"],\"hostname\":\"foo4\",\"region_tag\":\"foo5\"},{\"name\":\"foo\",\"slug\":\"foo2\",\"locales\":[\"foo3\"],\"hostname\":\"foo4\",\"region_tag\":\"foo5\"},{\"name\":\"foo\",\"slug\":\"foo2\",\"locales\":[\"foo3\"],\"hostname\":\"foo4\",\"region_tag\":\"foo5\"}]";
public static void parse() {
try {
TypeReference<List<Shards>> typeRef = new TypeReference<List<Shards>>() { };
ObjectMapper mapper = new ObjectMapper();
List<Shards> list = mapper.readValue(jsonString, typeRef);
for ( Shards s : list )
{
s.printDebug();
}
ShardsResponse sr = new ShardsResponse(list);
String srString = mapper.writeValueAsString(sr);
System.out.println("srString: " + srString );
TypeReference<ShardsResponse> typeRef2 = new TypeReference<ShardsResponse>() { };
ShardsResponse sr2 = mapper.readValue(srString, typeRef2);
sr2.printDebug();
} catch ( IOException e) {
e.printStackTrace();
}
}
public static void main(String[] args) {
ParseJson.parse();
}
}
Edit:
If you expect a ShardsResponse back, your json string should look like this:
{"shards":[{"locales":["foo3"],"name":"foo","hostname":"foo4","slug":"foo2","region_tag":"foo5"},{"locales":["foo3"],"name":"foo","hostname":"foo4","slug":"foo2","region_tag":"foo5"},{"locales":["foo3"],"name":"foo","hostname":"foo4","slug":"foo2","region_tag":"foo5"},{"locales":["foo3"],"name":"foo","hostname":"foo4","slug":"foo2","region_tag":"foo5"}]}
Easiest way to figure out what the json will look like is to dump it out:
ShardsResponse sr = new ShardsResponse(list);
String srString = mapper.writeValueAsString(sr);
System.out.println("srString: " + srString );
Edit:
Adding additional Classes for clarity:
ShardsResponses.java
import java.util.ArrayList;
import java.util.List;
public class ShardsResponse {
private List<Shards> shards = new ArrayList<Shards>();
public ShardsResponse() { }
public ShardsResponse( List<Shards> shards)
{
this.shards = shards;
}
public List<Shards> getShards() {
return shards;
}
public void setShards(List<Shards> shards) {
this.shards = shards;
}
public void printDebug()
{
for ( Shards s : shards)
{
s.printDebug();
System.out.println("");
}
}
}
Shards.java:
import java.util.List;
public class Shards {
private List<String> locales;
private String name;
private String hostname;
private String slug;
private String region_tag;
public List<String> getLocales() {
return locales;
}
public void setLocales(List<String> locales) {
this.locales = locales;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getHostname() {
return hostname;
}
public void setHostname(String hostname) {
this.hostname = hostname;
}
public String getSlug() {
return slug;
}
public void setSlug(String slug) {
this.slug = slug;
}
public void printDebug()
{
System.out.println("name: " + name);
System.out.println("hostname: " + hostname);
System.out.println("slug: " + slug);
System.out.println("region_tag: " + region_tag);
for ( String s : locales )
{
System.out.println("Locals: " + locales);
}
}
public String getRegion_tag() {
return region_tag;
}
public void setRegion_tag(String region_tag) {
this.region_tag = region_tag;
}
}
you have an jsonArray but you are trying to parse a jsonObject. change your method to return a list of objects instead of one object.

Categories

Resources