I am trying to convert a complex object into related Java beans. However, some sub class can be not generated correctly.
I am just using simulate MS Adaptive card to create a set of Java beans classes. When I call Gson package or Alibaba fastJson package to parse my json data. it always shows the super class type.
This is just an experiment to test Gson & fastJson whether it can convert complex objects. which is running on the Android studio.
My demo json is like following:
{
"type": "AdaptiveCard",
"version": "1.0",
"id": "workloadQCactivity 20",
"speak": "activity 20 <break time=\"300ms\"/> at<break time=\"300ms\"/> <break time=\"300ms\"/>building<break time=\"300ms\"/>A<break time=\"300ms\"/>floor<break time=\"300ms\"/>1<break time=\"300ms\"/>room<break time=\"300ms\"/>1<break time=\"300ms\"/> ",
"body": [{
"type": "Container",
"items": [{
"type": "ColumnSet",
"columns": [{
"type": "Column",
"width": "Stretch",
"items": [{
"type": "TextBlock",
"size": "large",
"weight": "bolder",
"text": "activity 20 at building A floor 1 room 1",
"wrap": true
}]
}]
}]
}],
"actions": [{
"type": "Action.ShowCard",
"card": {
"type": "AdaptiveCard",
"version": "1.0",
"body": [{
"type": "TextBlock",
"size": "medium",
"weight": "bolder",
"isSubtle": true,
"text": "have thing to check list1",
"wrap": true
}, {
"type": "TextBlock",
"weight": "bolder",
"isSubtle": true,
"text": "this is section 1",
"wrap": true
}, {
"type": "TextBlock",
"isSubtle": true,
"text": "q1 of s1",
"wrap": true
}, {
"type": "TextBlock",
"isSubtle": true,
"text": "q2 of s2",
"wrap": true
}, {
"type": "TextBlock",
"weight": "bolder",
"isSubtle": true,
"text": "this is section 2",
"wrap": true
}, {
"type": "TextBlock",
"isSubtle": true,
"text": "q1 of s22",
"wrap": true
}, {
"type": "TextBlock",
"size": "medium",
"weight": "bolder",
"isSubtle": true,
"text": "have checklist 2",
"wrap": true
}, {
"type": "TextBlock",
"weight": "bolder",
"isSubtle": true,
"text": "section of the second checklist",
"wrap": true
}, {
"type": "TextBlock",
"isSubtle": true,
"text": "qqqqqq",
"wrap": true
}]
},
"title": "Show Checklist"
}]
}
Therefore, I just follow MS adaptive card to create following java beans.
First class: AdaptiveTypedElement
public class AdaptiveTypedElement {
#JsonProperty("additionalPorperties")
public Map<String, Object> additionalPorperties = new HashMap<String, Object>();
//#JsonProperty("type")
//public String type;
#JsonProperty("id")
public String id;
}
Second class: AdaptiveTypedElement
public class AdaptiveElement extends AdaptiveTypedElement {
#JsonProperty("spacing")
public AdaptiveSpacing spacing ;
#JsonProperty("separator")
public boolean separator = false;
#JsonProperty("speak")
public String speak;
#JsonProperty("separation")
// public AdaptiveSeparationStyle separation;
public String separation;
}
Third class AdaptiveContainer:
public class AdaptiveContainer extends AdaptiveElement {
#JsonProperty("typeName")
public String typeName = "Container";
#JsonProperty("type")
public String type = "Container";
#JsonProperty("items")
public List<AdaptiveElement> items = new ArrayList<AdaptiveElement>();
#JsonProperty("selectAction")
public AdaptiveAction selectAction = null;
#JsonProperty("style")
public AdaptiveContainerStyle style = AdaptiveContainerStyle.Default;
}
public class AdaptiveColumnSet extends AdaptiveElement {
#JsonProperty("typeName")
public final String typeName = "ColumnSet";
#JsonProperty("type")
public final String type = "ColumnSet";
#JsonProperty("columns")
public List<AdaptiveColumn> columns = new ArrayList<AdaptiveColumn>();
#JsonProperty("selectionAction")
public AdaptiveAction selectionAction = null;
}
public class AdaptiveColumn extends AdaptiveContainer{
#JsonProperty("typeName")
public final String typeName = "Column";
#JsonProperty("type")
public final String type = "Column";
#JsonProperty("size")
public String size;
#JsonProperty("with")
public String with;
}
public class AdaptiveAction {
#JsonProperty("title")
public String title;
#JsonProperty("speak")
public String speak;
}
public class AdaptiveShowCardAction extends AdaptiveAction {
#JsonProperty("typeName")
public final String typeName = "Action.ShowCard";
#JsonProperty("type")
public final String Type = "Action.ShowCard";
#JsonProperty("card")
public AdaptiveCard card;
}
public class AdaptiveTextBlock extends AdaptiveElement{
#JsonProperty("typeName")
public String typeName = "TextBlock";
#JsonProperty("type")
public String type = "TextBlock";
#JsonProperty("text")
public String text = "";
#JsonProperty("size")
public AdaptiveTextSize size;
#JsonProperty("weight")
public AdaptiveTextWeight weight;
#JsonProperty("color")
public AdaptiveTextColor color;
#JsonProperty("horizontalAlignment")
public AdaptiveHorizontalAlignment horizontalAlignment = AdaptiveHorizontalAlignment.Left;
#JsonProperty("wrap")
public boolean wrap = false;
#JsonProperty("isSubtle")
public boolean isSubtle = false;
#JsonProperty("maxLines")
public int maxLines = 0;
#JsonProperty("maxWidth")
public int maxWidth = 0;
}
public class AdaptiveCard extends AdaptiveTypedElement {
#JsonProperty("contentType")
public final String contentType = "application/vnd.microsoft.card.adaptive";
#JsonProperty("typeName")
public final String typeName = "AdaptiveCard";
#JsonProperty("type")
public String type = "AdaptiveCard";
#JsonProperty("body")
public List<AdaptiveElement> body = new ArrayList<AdaptiveElement>();
#JsonProperty("actions")
public List<AdaptiveAction> actions = new ArrayList<AdaptiveAction>();
#JsonProperty("speak")
public String speak = null;
#JsonProperty("title")
public String title;
#JsonProperty("version")
//public AdaptiveSchemaVersion version = null;
public String version = null;
#JsonProperty("fallbackText")
public String fallbackText = null;
#JsonProperty("lang")
public String lang = null;
}
In the end, I finally got AdaptiveCard Object. See my code:
return JSON.parseObject(attachJson, AdaptiveCard.class). Note that I add "implementation 'com.alibaba:fastjson:1.2.54'" in my Android Studio
When I check this object, I found the Body data member should be class "AdaptiveContainer " not "AdaptiveElement". I was wondering why it did not following subclass mechanism of OOP & OOD. I am expecting "AdaptiveContainer", but actually output is "AdaptiveElement".
enter image description here
rib-pet, your question has a far to big example. Anyway I tried to create a java class mapping for your sample using GSON
Action.java
package com.example;
import com.google.gson.annotations.Expose;
import com.google.gson.annotations.SerializedName;
public class Action {
#SerializedName("type")
#Expose
private String type;
#SerializedName("card")
#Expose
private Card card;
#SerializedName("title")
#Expose
private String title;
public String getType() {
return type;
}
public void setType(String type) {
this.type = type;
}
public Card getCard() {
return card;
}
public void setCard(Card card) {
this.card = card;
}
public String getTitle() {
return title;
}
public void setTitle(String title) {
this.title = title;
}
}
Body.java
package com.example;
import java.util.List;
import com.google.gson.annotations.Expose;
import com.google.gson.annotations.SerializedName;
public class Body {
#SerializedName("type")
#Expose
private String type;
#SerializedName("items")
#Expose
private List<Item> items = null;
public String getType() {
return type;
}
public void setType(String type) {
this.type = type;
}
public List<Item> getItems() {
return items;
}
public void setItems(List<Item> items) {
this.items = items;
}
}
Body_.java (dependend on your wished model you should integrate this class better in some existing
package com.example;
import com.google.gson.annotations.Expose;
import com.google.gson.annotations.SerializedName;
public class Body_ {
#SerializedName("type")
#Expose
private String type;
#SerializedName("size")
#Expose
private String size;
#SerializedName("weight")
#Expose
private String weight;
#SerializedName("isSubtle")
#Expose
private Boolean isSubtle;
#SerializedName("text")
#Expose
private String text;
#SerializedName("wrap")
#Expose
private Boolean wrap;
public String getType() {
return type;
}
public void setType(String type) {
this.type = type;
}
public String getSize() {
return size;
}
public void setSize(String size) {
this.size = size;
}
public String getWeight() {
return weight;
}
public void setWeight(String weight) {
this.weight = weight;
}
public Boolean getIsSubtle() {
return isSubtle;
}
public void setIsSubtle(Boolean isSubtle) {
this.isSubtle = isSubtle;
}
public String getText() {
return text;
}
public void setText(String text) {
this.text = text;
}
public Boolean getWrap() {
return wrap;
}
public void setWrap(Boolean wrap) {
this.wrap = wrap;
}
}
Card.java
package com.example;
import java.util.List;
import com.google.gson.annotations.Expose;
import com.google.gson.annotations.SerializedName;
public class Card {
#SerializedName("type")
#Expose
private String type;
#SerializedName("version")
#Expose
private String version;
#SerializedName("body")
#Expose
private List<Body_> body = null;
public String getType() {
return type;
}
public void setType(String type) {
this.type = type;
}
public String getVersion() {
return version;
}
public void setVersion(String version) {
this.version = version;
}
public List<Body_> getBody() {
return body;
}
public void setBody(List<Body_> body) {
this.body = body;
}
}
Column.java
package com.example;
import java.util.List;
import com.google.gson.annotations.Expose;
import com.google.gson.annotations.SerializedName;
public class Column {
#SerializedName("type")
#Expose
private String type;
#SerializedName("width")
#Expose
private String width;
#SerializedName("items")
#Expose
private List<Item_> items = null;
public String getType() {
return type;
}
public void setType(String type) {
this.type = type;
}
public String getWidth() {
return width;
}
public void setWidth(String width) {
this.width = width;
}
public List<Item_> getItems() {
return items;
}
public void setItems(List<Item_> items) {
this.items = items;
}
}
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("type")
#Expose
private String type;
#SerializedName("version")
#Expose
private String version;
#SerializedName("id")
#Expose
private String id;
#SerializedName("speak")
#Expose
private String speak;
#SerializedName("body")
#Expose
private List<Body> body = null;
#SerializedName("actions")
#Expose
private List<Action> actions = null;
public String getType() {
return type;
}
public void setType(String type) {
this.type = type;
}
public String getVersion() {
return version;
}
public void setVersion(String version) {
this.version = version;
}
public String getId() {
return id;
}
public void setId(String id) {
this.id = id;
}
public String getSpeak() {
return speak;
}
public void setSpeak(String speak) {
this.speak = speak;
}
public List<Body> getBody() {
return body;
}
public void setBody(List<Body> body) {
this.body = body;
}
public List<Action> getActions() {
return actions;
}
public void setActions(List<Action> actions) {
this.actions = actions;
}
}
Item.java
package com.example;
import java.util.List;
import com.google.gson.annotations.Expose;
import com.google.gson.annotations.SerializedName;
public class Item {
#SerializedName("type")
#Expose
private String type;
#SerializedName("columns")
#Expose
private List<Column> columns = null;
public String getType() {
return type;
}
public void setType(String type) {
this.type = type;
}
public List<Column> getColumns() {
return columns;
}
public void setColumns(List<Column> columns) {
this.columns = columns;
}
}
Item_.java also here better integration needed
package com.example;
import com.google.gson.annotations.Expose;
import com.google.gson.annotations.SerializedName;
public class Item_ {
#SerializedName("type")
#Expose
private String type;
#SerializedName("size")
#Expose
private String size;
#SerializedName("weight")
#Expose
private String weight;
#SerializedName("text")
#Expose
private String text;
#SerializedName("wrap")
#Expose
private Boolean wrap;
public String getType() {
return type;
}
public void setType(String type) {
this.type = type;
}
public String getSize() {
return size;
}
public void setSize(String size) {
this.size = size;
}
public String getWeight() {
return weight;
}
public void setWeight(String weight) {
this.weight = weight;
}
public String getText() {
return text;
}
public void setText(String text) {
this.text = text;
}
public Boolean getWrap() {
return wrap;
}
public void setWrap(Boolean wrap) {
this.wrap = wrap;
}
}
hope it helps!
I've figured out this solution via the following solution:
JSONObject and JSONArray
JSONArray body = contentObj.getJSONArray("body");
JSONArray actions = contentObj.getJSONArray("actions");
title.setText(body.getJSONObject(0).getString("text"));
Related
I'm trying to parse a JSON like this
{
"meta": {
"limit": 20,
"next": null,
"offset": 0,
"previous": null,
"total_count": 1
},
"objects": [
{
"customer_id": "some-customer-id",
"id": 5,
"is_active": true,
"product_code": "some-product-code",
"resource_uri": "/api/v1/aws-marketplace/5/",
"support_subscription_id": "22"
}
]
}
generated for http://www.jsonschema2pojo.org I got his Java clases
package com.greenqloud.netappstats.collector.metrics.gqconsole.api;
import java.util.List;
import com.google.gson.annotations.Expose;
import com.google.gson.annotations.SerializedName;
public class AwsMarketplace {
#SerializedName("meta")
#Expose
private Meta meta;
#SerializedName("objects")
#Expose
private List<Object> objects = null;
public Meta getMeta() {
return meta;
}
public void setMeta(Meta meta) {
this.meta = meta;
}
public List<Object> getObjects() {
return objects;
}
public void setObjects(List<Object> objects) {
this.objects = objects;
}
}
Meta class
package com.greenqloud.netappstats.collector.metrics.gqconsole.api;
import com.google.gson.annotations.Expose;
import com.google.gson.annotations.SerializedName;
public class Meta {
#SerializedName("limit")
#Expose
private int limit;
#SerializedName("next")
#Expose
private String next;
#SerializedName("offset")
#Expose
private int offset;
#SerializedName("previous")
#Expose
private String previous;
#SerializedName("total_count")
#Expose
private int totalCount;
public int getLimit() {
return limit;
}
public void setLimit(int limit) {
this.limit = limit;
}
public String getNext() {
return next;
}
public void setNext(String next) {
this.next = next;
}
public int getOffset() {
return offset;
}
public void setOffset(int offset) {
this.offset = offset;
}
public String getPrevious() {
return previous;
}
public void setPrevious(String previous) {
this.previous = previous;
}
public int getTotalCount() {
return totalCount;
}
public void setTotalCount(int totalCount) {
this.totalCount = totalCount;
}
}
Object class
package com.greenqloud.netappstats.collector.metrics.gqconsole.api;
import com.google.gson.annotations.Expose;
import com.google.gson.annotations.SerializedName;
public class Object {
#SerializedName("customer_id")
#Expose
private String customerId;
#SerializedName("id")
#Expose
private int id;
#SerializedName("is_active")
#Expose
private boolean isActive;
#SerializedName("product_code")
#Expose
private String productCode;
#SerializedName("resource_uri")
#Expose
private String resourceUri;
#SerializedName("support_subscription_id")
#Expose
private String supportSubscriptionId;
public String getCustomerId() {
return customerId;
}
public void setCustomerId(String customerId) {
this.customerId = customerId;
}
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public boolean isIsActive() {
return isActive;
}
public void setIsActive(boolean isActive) {
this.isActive = isActive;
}
public String getProductCode() {
return productCode;
}
public void setProductCode(String productCode) {
this.productCode = productCode;
}
public String getResourceUri() {
return resourceUri;
}
public void setResourceUri(String resourceUri) {
this.resourceUri = resourceUri;
}
public String getSupportSubscriptionId() {
return supportSubscriptionId;
}
public void setSupportSubscriptionId(String supportSubscriptionId) {
this.supportSubscriptionId = supportSubscriptionId;
}
}
But when trying to deserialise with this func
Type localVarReturnType = new TypeToken<List<InstanceCreatorForAwsMarketplace>>(){}.getType();
ApiResponse<List<InstanceCreatorForAwsMarketplace>> responseFromApiCleint = apiClient.execute(newCall, localVarReturnType);
I get the following error:
com.google.gson.JsonSyntaxException: java.lang.IllegalStateException: Expected BEGIN_ARRAY but was BEGIN_OBJECT at line 1 column 2 path $
Any idea what might be the issue? This looks like a fairly simple json that the rest service returns, but I have not been able to get it work, any help would be greatly appreciated.
Right after I had written the question, I found out the answer, of course the top level class should not be a list, just the class it self. But I have a secondary question, can the three mapper classes be mounted into one class, just a cosmetic issue?
I have the following JSON string in a "special" format.
I want to convert it to an object in java but I don't know how to access single values for example the value of location or "resolved_at".
I tried with GSON and JSONPOBJECT but it doesn't work with this one.
{
"result": {
"upon_approval": "proceed",
"location": {
"link": "https://instance.service- now.com/api/now/table/cmn_location/108752c8c611227501d4ab0e392ba97f",
"value": "108752c8c611227501d4ab0e392ba97f"
},
"expected_start": "",
"reopen_count": "",
"sys_domain": {
"link": "https://instance.service- now.com/api/now/table/sys_user_group/global",
"value": "global"
},
"description": "",
"activity_due": "2016-01-22 16:12:37",
"sys_created_by": "glide.maint",
"resolved_at": "",
"assigned_to": {
"link": "https://instance.service- now.com/api/now/table/sys_user/681b365ec0a80164000fb0b05854a0cd",
"value": "681b365ec0a80164000fb0b05854a0cd"
},
"business_stc": "",
"wf_activity": "",
"sys_domain_path": "/",
"cmdb_ci": {
"link": "https://instance.service- now.com/api/now/table/cmdb_ci/281190e3c0a8000b003f593aa3f20ca6",
"value": "281190e3c0a8000b003f593aa3f20ca6"
},
"opened_by": {
"link": "https://instance.service- now.com/api/now/table/sys_user/glide.maint",
"value": "glide.maint"
},
"subcategory": "",
"comments": ""
}
}
Just create an object and use the objectmapper like:
Myclass myclass = objectMapper.readValue(json, Myclass.class);
But according to https://jsoneditoronline.org/ your json is not valid.
Used an online converter to create the classes, after removing the errors:
-----------------------------------com.example.AssignedTo.java-----------------------------------
package com.example;
import com.google.gson.annotations.Expose;
import com.google.gson.annotations.SerializedName;
public class AssignedTo {
#SerializedName("link")
#Expose
private String link;
#SerializedName("value")
#Expose
private String value;
public String getLink() {
return link;
}
public void setLink(String link) {
this.link = link;
}
public String getValue() {
return value;
}
public void setValue(String value) {
this.value = value;
}
}
-----------------------------------com.example.CmdbCi.java-----------------------------------
package com.example;
import com.google.gson.annotations.Expose;
import com.google.gson.annotations.SerializedName;
public class CmdbCi {
#SerializedName("link")
#Expose
private String link;
#SerializedName("value")
#Expose
private String value;
public String getLink() {
return link;
}
public void setLink(String link) {
this.link = link;
}
public String getValue() {
return value;
}
public void setValue(String value) {
this.value = value;
}
}
-----------------------------------com.example.Example.java-----------------------------------
package com.example;
import com.google.gson.annotations.Expose;
import com.google.gson.annotations.SerializedName;
public class Example {
#SerializedName("result")
#Expose
private Result result;
public Result getResult() {
return result;
}
public void setResult(Result result) {
this.result = result;
}
}
-----------------------------------com.example.Location.java-----------------------------------
package com.example;
import com.google.gson.annotations.Expose;
import com.google.gson.annotations.SerializedName;
public class Location {
#SerializedName("link")
#Expose
private String link;
#SerializedName("value")
#Expose
private String value;
public String getLink() {
return link;
}
public void setLink(String link) {
this.link = link;
}
public String getValue() {
return value;
}
public void setValue(String value) {
this.value = value;
}
}
-----------------------------------com.example.OpenedBy.java-----------------------------------
package com.example;
import com.google.gson.annotations.Expose;
import com.google.gson.annotations.SerializedName;
public class OpenedBy {
#SerializedName("link")
#Expose
private String link;
#SerializedName("value")
#Expose
private String value;
public String getLink() {
return link;
}
public void setLink(String link) {
this.link = link;
}
public String getValue() {
return value;
}
public void setValue(String value) {
this.value = value;
}
}
-----------------------------------com.example.Result.java-----------------------------------
package com.example;
import com.google.gson.annotations.Expose;
import com.google.gson.annotations.SerializedName;
public class Result {
#SerializedName("upon_approval")
#Expose
private String uponApproval;
#SerializedName("location")
#Expose
private Location location;
#SerializedName("expected_start")
#Expose
private String expectedStart;
#SerializedName("reopen_count")
#Expose
private String reopenCount;
#SerializedName("sys_domain")
#Expose
private SysDomain sysDomain;
#SerializedName("description")
#Expose
private String description;
#SerializedName("activity_due")
#Expose
private String activityDue;
#SerializedName("sys_created_by")
#Expose
private String sysCreatedBy;
#SerializedName("resolved_at")
#Expose
private String resolvedAt;
#SerializedName("assigned_to")
#Expose
private AssignedTo assignedTo;
#SerializedName("business_stc")
#Expose
private String businessStc;
#SerializedName("wf_activity")
#Expose
private String wfActivity;
#SerializedName("sys_domain_path")
#Expose
private String sysDomainPath;
#SerializedName("cmdb_ci")
#Expose
private CmdbCi cmdbCi;
#SerializedName("opened_by")
#Expose
private OpenedBy openedBy;
#SerializedName("subcategory")
#Expose
private String subcategory;
#SerializedName("comments")
#Expose
private String comments;
public String getUponApproval() {
return uponApproval;
}
public void setUponApproval(String uponApproval) {
this.uponApproval = uponApproval;
}
public Location getLocation() {
return location;
}
public void setLocation(Location location) {
this.location = location;
}
public String getExpectedStart() {
return expectedStart;
}
public void setExpectedStart(String expectedStart) {
this.expectedStart = expectedStart;
}
public String getReopenCount() {
return reopenCount;
}
public void setReopenCount(String reopenCount) {
this.reopenCount = reopenCount;
}
public SysDomain getSysDomain() {
return sysDomain;
}
public void setSysDomain(SysDomain sysDomain) {
this.sysDomain = sysDomain;
}
public String getDescription() {
return description;
}
public void setDescription(String description) {
this.description = description;
}
public String getActivityDue() {
return activityDue;
}
public void setActivityDue(String activityDue) {
this.activityDue = activityDue;
}
public String getSysCreatedBy() {
return sysCreatedBy;
}
public void setSysCreatedBy(String sysCreatedBy) {
this.sysCreatedBy = sysCreatedBy;
}
public String getResolvedAt() {
return resolvedAt;
}
public void setResolvedAt(String resolvedAt) {
this.resolvedAt = resolvedAt;
}
public AssignedTo getAssignedTo() {
return assignedTo;
}
public void setAssignedTo(AssignedTo assignedTo) {
this.assignedTo = assignedTo;
}
public String getBusinessStc() {
return businessStc;
}
public void setBusinessStc(String businessStc) {
this.businessStc = businessStc;
}
public String getWfActivity() {
return wfActivity;
}
public void setWfActivity(String wfActivity) {
this.wfActivity = wfActivity;
}
public String getSysDomainPath() {
return sysDomainPath;
}
public void setSysDomainPath(String sysDomainPath) {
this.sysDomainPath = sysDomainPath;
}
public CmdbCi getCmdbCi() {
return cmdbCi;
}
public void setCmdbCi(CmdbCi cmdbCi) {
this.cmdbCi = cmdbCi;
}
public OpenedBy getOpenedBy() {
return openedBy;
}
public void setOpenedBy(OpenedBy openedBy) {
this.openedBy = openedBy;
}
public String getSubcategory() {
return subcategory;
}
public void setSubcategory(String subcategory) {
this.subcategory = subcategory;
}
public String getComments() {
return comments;
}
public void setComments(String comments) {
this.comments = comments;
}
}
-----------------------------------com.example.SysDomain.java-----------------------------------
package com.example;
import com.google.gson.annotations.Expose;
import com.google.gson.annotations.SerializedName;
public class SysDomain {
#SerializedName("link")
#Expose
private String link;
#SerializedName("value")
#Expose
private String value;
public String getLink() {
return link;
}
public void setLink(String link) {
this.link = link;
}
public String getValue() {
return value;
}
public void setValue(String value) {
this.value = value;
}
}
Edit: As i see, the code above will not work OOTB. I've got it working doeing the following steps:
Replace #SerializedName with #JsonProperty
then:
ObjectMapper mapper = new ObjectMapper();
Example example = mapper.readValue(json, Example.class);
I'm having difficulty trying to parse this JSON response into a list of "properties" elements. My JSON looks like this:
{
"type": "FeatureCollection",
"features": [
{
"type": "Feature",
"properties": {
"mag": 6.6,
"place": "192km ESE of Tadine, New Caledonia"
}
},
{
"type": "Feature",
"properties": {
"mag": 7.5,
"place": "168km ESE of Tadine, New Caledonia"
}
},
{
"type": "Feature",
"properties": {
"mag": 6,
"place": "155km ESE of Tadine, New Caledonia"
}
}
]
}
This is response contains Earthquake details so basically each "properties" within "features" is the POJO I want, but all of them just in a List. Here is my Earthquake class:
public class Earthquake {
#SerializedName("mag")
private double magnitude;
#SerializedName("place")
private String location;
public Earthquake(double magnitude, String location) {
this.magnitude = magnitude;
this.location = location;
}
// getters
}
I've tried doing custom deserialization suggested here. It gives me the error
Expected BEGIN_ARRAY but was BEGIN_OBJECT at line 1 column 2 path $
suggesting that I'm trying to parse a JsonObject instead of a JsonArray. Here is the deserializer I used.
public class EarthquakeDeserializer implements JsonDeserializer<ArrayList<Earthquake>> {
#Override
public ArrayList<Earthquake> deserialize(JsonElement json, Type typeOfT, JsonDeserializationContext context) throws JsonParseException {
// get list of "features"
JsonElement features = json.getAsJsonObject().get("features");
JsonArray earthquakeElements = new JsonArray();
for (JsonElement feature : features.getAsJsonArray()){
JsonElement properties = feature.getAsJsonObject().get("properties");
earthquakeElements.add(properties);
}
Type listType = new TypeToken<ArrayList<Earthquake>>(){}.getType();
return new Gson().fromJson(earthquakeElements, listType);
}
}
Any ideas as to what's going on here?
you can create this kind of a POJO class for your Json, No matter if you want just single part of your response body, you need to create POJO for whole response and from that POJO you need to get appropriate attributes. ->
This is your main json object ->
public class Example {
#SerializedName("type")
#Expose
private String type;
#SerializedName("features")
#Expose
private List<Feature> features = null;
public String getType() {
return type;
}
public void setType(String type) {
this.type = type;
}
public List<Feature> getFeatures() {
return features;
}
public void setFeatures(List<Feature> features) {
this.features = features;
}
}
this is your feature class ->
package com.example;
import com.google.gson.annotations.Expose;
import com.google.gson.annotations.SerializedName;
public class Feature {
#SerializedName("type")
#Expose
private String type;
#SerializedName("properties")
#Expose
private Properties properties;
public String getType() {
return type;
}
public void setType(String type) {
this.type = type;
}
public Properties getProperties() {
return properties;
}
public void setProperties(Properties properties) {
this.properties = properties;
}
}
this is your properties class ->
package com.example;
import com.google.gson.annotations.Expose;
import com.google.gson.annotations.SerializedName;
public class Properties {
#SerializedName("mag")
#Expose
private Integer mag;
#SerializedName("place")
#Expose
private String place;
public Integer getMag() {
return mag;
}
public void setMag(Integer mag) {
this.mag = mag;
}
public String getPlace() {
return place;
}
public void setPlace(String place) {
this.place = place;
}
}
After creating this classes, you can serialize the JSON to POJO via GSON library, you can refer to HussainAbbas's answer for how to do it.
Now you can get anything via creating object of response class, and via that object you can access any property you want. Thanks.
check this out
package com.example;
import java.util.List;
import com.google.gson.annotations.Expose;
import com.google.gson.annotations.SerializedName;
public class Example {
#SerializedName("type")
#Expose
private String type;
#SerializedName("features")
#Expose
private List<Feature> features = null;
public String getType() {
return type;
}
public void setType(String type) {
this.type = type;
}
public List<Feature> getFeatures() {
return features;
}
public void setFeatures(List<Feature> features) {
this.features = features;
}
}
-----------------------------------com.example.Feature.java-----------------------------------
package com.example;
import com.google.gson.annotations.Expose;
import com.google.gson.annotations.SerializedName;
public class Feature {
#SerializedName("type")
#Expose
private String type;
#SerializedName("properties")
#Expose
private Properties properties;
public String getType() {
return type;
}
public void setType(String type) {
this.type = type;
}
public Properties getProperties() {
return properties;
}
public void setProperties(Properties properties) {
this.properties = properties;
}
}
-----------------------------------com.example.Properties.java-----------------------------------
package com.example;
import com.google.gson.annotations.Expose;
import com.google.gson.annotations.SerializedName;
public class Properties {
#SerializedName("mag")
#Expose
private Integer mag;
#SerializedName("place")
#Expose
private String place;
public Integer getMag() {
return mag;
}
public void setMag(Integer mag) {
this.mag = mag;
}
public String getPlace() {
return place;
}
public void setPlace(String place) {
this.place = place;
}
}
After this add this... in your retrofit response
Gson gson = new Gson()
String data = gson.toJson(response.body());
LoginResponse loginResponse = gson.fromJson(dataString,LoginResponse.class);
Example example = gson.fromJson(dataString,Example.class);
String feature_proprerties_mag = example.getFeatures().getProperties().getMag
I have a below JSON response that I am getting back from a rest service. Now I need to deserialize below JSON response into a POJO. I am working with Jackson.
{
"pagination": {
"number": 1,
"entriesPerPage": 200,
"total": 3
},
"postings": [{
"categories": [{
"taskid": "79720",
"name": "Sunglasses",
"parentCategory": {
"taskid": "394",
"name": "Sunglasses & Fashion Eyewear",
"parentCategory": {
"taskid": "2340",
"name": "Men's Accessories",
"parentCategory": {
"taskid": "10987",
"name": "Clothing, Shoes & Accessories"
}
}
}
}]
},
{
"categories": [{
"taskid": "12980",
"name": "Toys",
"parentCategory": {
"taskid": "123",
"name": "Fashion",
"parentCategory": {
"taskid": "78765",
"name": "Men's Accessories"
}
}
}]
}],
"total": 2
}
In above json, postings is a JSON array which can have multiple posting json object. Now categories is also JSON array. Now tricky part is I can have multiple levels of parentCategory inside each category object and I don't know how many levels of parentCategory I will have. Give above JSON, I need to extract taskid of each category and taskId of last parentCategory. So it should be like this:
79720=10987
12980=78765
Where 79720 is taskId of category and 10987 is the taskId of last parentCategory. Similarly for other one.
Below is my code where I am deserializing JSON into my POJO by making an http call:
ResponseEntity<Stuff> responseEntity = HttpClient.getInstance().getClient()
.exchange(URI.create(endpoint), HttpMethod.POST, requestEntity, Stuff.class);
Stuff response = responseEntity.getBody();
List<Posting> postings = response.getPostings();
for(Posting postings : postings) {
//....
}
Confusion I have is - How to make POJO for above JSON? I tried using jsonschema2pojo but it's not making right classes for parentCategory. Since I can have nested levels of parentCategory which I don't know before hand.
Is this possible to do using Jackson?
This is the POJO class generated for Category and ParentCategory. I am not sure whether I need to make any changes here so that I can parse recursive parentCategory object.
#JsonInclude(JsonInclude.Include.NON_NULL)
#JsonPropertyOrder({"taskid", "name", "parentCategory"})
public class Category {
#JsonProperty("taskid")
private String taskid;
#JsonProperty("name")
private String name;
#JsonProperty("parentCategory")
private ParentCategory parentCategory;
#JsonIgnore
private Map<String, Object> additionalProperties = new HashMap<String, Object>();
...
}
#JsonInclude(JsonInclude.Include.NON_NULL)
#JsonPropertyOrder({"taskid", "name", "parentCategory"})
public class ParentCategory {
#JsonProperty("taskid")
private String taskid;
#JsonProperty("name")
private String name;
#JsonProperty("parentCategory")
private ParentCategory parentCategory;
#JsonIgnore
private Map<String, Object> additionalProperties = new HashMap<String, Object>();
...
}
This time I would approach with GSon
Which manages recursion with less effort.
Pojos can be made from json2pojo website, simply choosing GSon as JSon library.
These are the Pojos:
import java.io.Serializable;
import com.google.gson.annotations.Expose;
import com.google.gson.annotations.SerializedName;
public class Pagination implements Serializable
{
public Pagination() {
super();
// TODO Auto-generated constructor stub
}
#SerializedName("number")
#Expose
private Integer number;
#SerializedName("entriesPerPage")
#Expose
private Integer entriesPerPage;
#SerializedName("total")
#Expose
private Integer total;
private final static long serialVersionUID = 5114620434202813556L;
public Integer getNumber() {
return number;
}
public void setNumber(Integer number) {
this.number = number;
}
public Integer getEntriesPerPage() {
return entriesPerPage;
}
public void setEntriesPerPage(Integer entriesPerPage) {
this.entriesPerPage = entriesPerPage;
}
public Integer getTotal() {
return total;
}
public void setTotal(Integer total) {
this.total = total;
}
}
import java.io.Serializable;
import java.util.List;
import com.google.gson.annotations.Expose;
import com.google.gson.annotations.SerializedName;
public class Categories implements Serializable
{
public Categories() {
super();
// TODO Auto-generated constructor stub
}
#SerializedName("pagination")
#Expose
private Pagination pagination;
#SerializedName("postings")
#Expose
private List<Posting> postings = null;
#SerializedName("total")
#Expose
private Integer total;
private final static long serialVersionUID = 4589512697836725240L;
public Pagination getPagination() {
return pagination;
}
public void setPagination(Pagination pagination) {
this.pagination = pagination;
}
public List<Posting> getPostings() {
return postings;
}
public void setPostings(List<Posting> postings) {
this.postings = postings;
}
public Integer getTotal() {
return total;
}
public void setTotal(Integer total) {
this.total = total;
}
}
import java.io.Serializable;
import com.google.gson.annotations.Expose;
import com.google.gson.annotations.SerializedName;
public class Category implements Serializable
{
public Category() {
super();
// TODO Auto-generated constructor stub
}
#SerializedName("taskid")
#Expose
private String taskid;
#SerializedName("name")
#Expose
private String name;
#SerializedName("parentCategory")
#Expose
private ParentCategory parentCategory;
private final static long serialVersionUID = -2127963072268572959L;
public String getTaskid() {
return taskid;
}
public void setTaskid(String taskid) {
this.taskid = taskid;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public ParentCategory getParentCategory() {
return parentCategory;
}
public void setParentCategory(ParentCategory parentCategory) {
this.parentCategory = parentCategory;
}
}
import java.io.Serializable;
import java.util.List;
import com.google.gson.annotations.Expose;
import com.google.gson.annotations.SerializedName;
public class Posting implements Serializable
{
#SerializedName("categories")
#Expose
private List<Category> categories = null;
private final static long serialVersionUID = 8135185675909461065L;
public List<Category> getCategories() {
return categories;
}
public Posting() {
super();
// TODO Auto-generated constructor stub
}
public void setCategories(List<Category> categories) {
this.categories = categories;
}
}
import java.io.Serializable;
import java.util.List;
import com.google.gson.annotations.Expose;
import com.google.gson.annotations.SerializedName;
public class ParentCategory implements Serializable
{
#SerializedName("taskid")
#Expose
private String taskid;
#SerializedName("name")
#Expose
private String name;
#SerializedName("parentCategory")
#Expose
private List<ParentCategory> parentCategory;
public ParentCategory() {
super();
// TODO Auto-generated constructor stub
}
private final static long serialVersionUID = -5989749742502713615L;
public String getTaskid() {
return taskid;
}
public void setTaskid(String taskid) {
this.taskid = taskid;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public List<ParentCategory> getParentCategory() {
return parentCategory;
}
public void setParentCategory(List<ParentCategory> parentCategory) {
this.parentCategory = parentCategory;
}
}
So this is a test implementation:
Pagination pagination = new Pagination();
pagination.setNumber(1);
pagination.setEntriesPerPage(200);
pagination.setTotal(3);
Categories categories = new Categories();
categories.setPagination(pagination);
Category category = new Category();
category.setName("Sunglasses");
category.setTaskid("79720");
List<Category> categoryList = new ArrayList<Category>();
Posting posting = new Posting();
posting.setCategories(categoryList);
List<ParentCategory> parentCategoryList = new ArrayList<ParentCategory>();
List<ParentCategory> parentCategoryList2 = new ArrayList<ParentCategory>();
ParentCategory parentCategory1 = new ParentCategory();
parentCategory1.setName("Sunglasses & Fashion Eyewear");
parentCategory1.setTaskid("394");
ParentCategory parentCategory2 = new ParentCategory();
parentCategory2.setName("Men's Accessories");
parentCategory2.setTaskid("2340");
ParentCategory parentCategory3 = new ParentCategory();
parentCategory3.setName("Clothing, Shoes & Accessories");
parentCategory3.setTaskid("10987");
parentCategoryList.add(parentCategory2);
parentCategoryList2.add(parentCategory3);
parentCategory2.setParentCategory(parentCategoryList2);
parentCategory1.setParentCategory(parentCategoryList);
category.setParentCategory(parentCategory1);
Gson gson = new Gson();
System.out.println(gson.toJson(category));
...and this is the resulting Json:
{
"taskid": "79720",
"name": "Sunglasses",
"parentCategory": {
"taskid": "394",
"name": "Sunglasses \u0026 Fashion Eyewear",
"parentCategory": [{
"taskid": "2340",
"name": "Men\u0027s Accessories",
"parentCategory": [{
"taskid": "10987",
"name": "Clothing, Shoes \u0026 Accessories"
}]
}]
}
}
Maybe still need a bit of tweaking but you got the idea.
Hope it helps!
EDIT: as the op requests I add the Jackson Version.
Pojos:
import java.io.Serializable;
import com.fasterxml.jackson.annotation.JsonInclude;
import com.fasterxml.jackson.annotation.JsonProperty;
import com.fasterxml.jackson.annotation.JsonPropertyOrder;
#JsonInclude(JsonInclude.Include.NON_NULL)
#JsonPropertyOrder({"taskid", "name", "parentCategory"})
public class ParentCategory implements Serializable{
/**
*
*/
private static final long serialVersionUID = 1L;
#JsonProperty("taskid")
private String taskid;
#JsonProperty("name")
private String name;
#JsonProperty("parentCategory")
private ParentCategory parentCategory;
public String getTaskid() {
return taskid;
}
public void setTaskid(String taskid) {
this.taskid = taskid;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public ParentCategory getParentCategory() {
return parentCategory;
}
public void setParentCategory(ParentCategory parentCategory) {
this.parentCategory = parentCategory;
}
}
import com.fasterxml.jackson.annotation.JsonInclude;
import com.fasterxml.jackson.annotation.JsonProperty;
import com.fasterxml.jackson.annotation.JsonPropertyOrder;
#JsonInclude(JsonInclude.Include.NON_NULL)
#JsonPropertyOrder({"taskid", "name", "parentCategory"})
public class Category implements Serializable{
/**
*
*/
private static final long serialVersionUID = 1L;
#JsonProperty("taskid")
private String taskid;
#JsonProperty("name")
private String name;
#JsonProperty("parentCategory")
private ParentCategory parentCategory;
public String getTaskid() {
return taskid;
}
public void setTaskid(String taskid) {
this.taskid = taskid;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public ParentCategory getParentCategory() {
return parentCategory;
}
public void setParentCategory(ParentCategory parentCategory) {
this.parentCategory = parentCategory;
}
}
public class Test {
public static void main(String[] args) throws JsonProcessingException {
Category category = new Category();
category.setName("Sunglasses");
category.setTaskid("79720");
List<Category> categoryList = new ArrayList<Category>();
List<ParentCategory> parentCategoryList = new ArrayList<ParentCategory>();
List<ParentCategory> parentCategoryList2 = new ArrayList<ParentCategory>();
ParentCategory parentCategory1 = new ParentCategory();
parentCategory1.setName("Sunglasses & Fashion Eyewear");
parentCategory1.setTaskid("394");
ParentCategory parentCategory2 = new ParentCategory();
parentCategory2.setName("Men's Accessories");
parentCategory2.setTaskid("2340");
ParentCategory parentCategory3 = new ParentCategory();
parentCategory3.setName("Clothing, Shoes & Accessories");
parentCategory3.setTaskid("10987");
parentCategory1.setParentCategory(parentCategory2);
parentCategory2.setParentCategory(parentCategory3);
category.setParentCategory(parentCategory1);
ObjectMapper objectMapper = new ObjectMapper();
String testJson = objectMapper.writeValueAsString(category);
System.out.println(testJson);
}
}
And here again a test result:
{
"taskid": "79720",
"name": "Sunglasses",
"parentCategory": {
"taskid": "394",
"name": "Sunglasses & Fashion Eyewear",
"parentCategory": {
"taskid": "2340",
"name": "Men's Accessories",
"parentCategory": {
"taskid": "10987",
"name": "Clothing, Shoes & Accessories"
}
}
}
}
I have following JSON structure:
{
"result": {
"category": [{
"id": "3",
"name": "category name",
"slug": "sllug",
"image": "imageurl",
"sub-categories": [{
"id": "3",
"name": "category name",
"slug": "sllug",
"image": "imageurl",
"sub-categories": [{
"id": "3",
"name": "category name",
"slug": "sllug",
"image": "imageurl",
"sub-categories": []
}]
}]
},
{
"id": "3",
"name": "category name",
"slug": "sllug",
"image": "imageurl",
"sub-categories": []
}
]
}
}
I need to create class with the above JSON.
I have created two classes as HomeCategoryModel and HomeSubCategoryModel.
There may be multiple sub-categories in each level.
How to map this type of json into classes.
HomeCategoryModel class:
public class HomeCategoryModel {
public int Id;
public String Name;
public String Slug;
public String ImageUrl;
public ArrayList<HomeSubCategoryModel> SubCategories;
//...
//getter, setter
}
HomeSubCategory class:
public class HomeSubCategoryModel {
public int Id;
public String Name;
public String Slug;
public String ImageUrl;
public ArrayList<HomeSubCategoryModel> SubCategories;
//getter setter
}
I have tried to parse using recursive function like this but doesn't seem to work:
JSONObject allLists = jsonObject.getJSONObject("result");
JSONArray catArray = allLists.getJSONArray("category");
ArrayList<HomeCategoryModel> categoryList = new ArrayList<HomeCategoryModel>();
for (int i = 0; i < catArray.length(); i++) {
JSONObject jObj = catArray.getJSONObject(i);
HomeCategoryModel categoryModel = new HomeCategoryModel();
categoryModel.setId(Integer.parseInt(jObj.getString("id")));
categoryModel.setName(jObj.getString("name"));
categoryModel.setSlug(jObj.getString("slug"));
categoryModel.setImageUrl(jObj.getString("image"));
JSONArray productsArray = jObj.getJSONArray("sub-categories");
if (productsArray.length() > 0) {
parseSubCategories(productsArray);
}
categoryList.add(categoryModel);
}
And:
public static ArrayList<HomeSubCategoryModel> parseSubCategories(JSONArray arr) {
ArrayList<HomeSubCategoryModel> subLists = new ArrayList<HomeSubCategoryModel>();
for (int i = 0; i < arr.length(); i++) {
try {
JSONObject childObj = arr.getJSONObject(i);
HomeSubCategoryModel categoryModel = new HomeSubCategoryModel();
categoryModel.setId(Integer.parseInt(childObj.getString("id")));
categoryModel.setName(childObj.getString("name"));
categoryModel.setSlug(childObj.getString("slug"));
categoryModel.setImageUrl(childObj.getString("image"));
JSONArray subArray = childObj.getJSONArray("sub-categories");
if (subArray.length() > 0) {
parseSubCategories(subArray);
}
subLists.add(categoryModel);
} catch (JSONException e) {
e.printStackTrace();
}
}
return subLists;
}
Please suggest me. Thank you.
if you would like to use Gson then i can suggest something like below.
Generate your POJO like this
package com.example;
import com.google.gson.annotations.Expose;
import com.google.gson.annotations.SerializedName;
public class Example {
#SerializedName("result")
#Expose
private Result result;
public Result getResult() {
return result;
}
public void setResult(Result result) {
this.result = result;
}
public class Result {
#SerializedName("category")
#Expose
private List < Category > category = null;
public List < Category > getCategory() {
return category;
}
public void setCategory(List < Category > category) {
this.category = category;
}
}
public class Category {
#SerializedName("id")
#Expose
private String id;
#SerializedName("name")
#Expose
private String name;
#SerializedName("slug")
#Expose
private String slug;
#SerializedName("image")
#Expose
private String image;
#SerializedName("sub-categories")
#Expose
private List < SubCategory > subCategories = null;
public String getId() {
return id;
}
public void setId(String id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getSlug() {
return slug;
}
public void setSlug(String slug) {
this.slug = slug;
}
public String getImage() {
return image;
}
public void setImage(String image) {
this.image = image;
}
public List < SubCategory > getSubCategories() {
return subCategories;
}
public void setSubCategories(List < SubCategory > subCategories) {
this.subCategories = subCategories;
}
}
public class SubCategory_ {
#SerializedName("id")
#Expose
private String id;
#SerializedName("name")
#Expose
private String name;
#SerializedName("slug")
#Expose
private String slug;
#SerializedName("image")
#Expose
private String image;
#SerializedName("sub-categories")
#Expose
private List < Object > subCategories = null;
public String getId() {
return id;
}
public void setId(String id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getSlug() {
return slug;
}
public void setSlug(String slug) {
this.slug = slug;
}
public String getImage() {
return image;
}
public void setImage(String image) {
this.image = image;
}
public List < Object > getSubCategories() {
return subCategories;
}
public void setSubCategories(List < Object > subCategories) {
this.subCategories = subCategories;
}
}
}
and then
Gson gson = new Gson();
Example exp = gson.fromJson("your json string",Example.class);
And you are done.