How to make POJO and parse recursive objects using jackson? - java

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"
}
}
}
}

Related

Jira API Automation - REST Assured

Am trying to automate Jira Issue Creation via REST API with Java Rest Assured. The following are my code snippets.
I need to reframe the following JSON in Java and pass it to the Body.
{
"fields": {
"project": {
"id": "13204"
},
"summary": "welcome to testing1",
"issuetype": {
"id": "3"
},
"reporter": {
"name": "parthiban.selvaraj"
},
"priority": {
"id": "3"
},
"description": "description",
"customfield_10201": {
"id": "10608"
}
}
}
Below is my Java code with getter and setter:
package jira;
import com.google.gson.Gson;
import io.restassured.RestAssured;
import io.restassured.authentication.PreemptiveBasicAuthScheme;
import io.restassured.http.ContentType;
import io.restassured.http.Method;
import io.restassured.path.json.JsonPath;
import io.restassured.response.Response;
import io.restassured.specification.RequestSpecification;
import java.util.List;
public class home {
public static void main (String args[]){
System.out.println("Welcome");
RestAssured.baseURI = "http://##.###.##.##:####/jira/rest/api/2/issue/";
PreemptiveBasicAuthScheme authScheme = new PreemptiveBasicAuthScheme();
authScheme.setUserName("########");
authScheme.setPassword("#######");
RestAssured.authentication = authScheme;
getterSetter values=new getterSetter();
values.setProject(13204);
values.setSummary("Checking via REST Assured");
values.setIssueType(3);
values.setReporter("#######");
values.setPriority(3);
values.setDescription("Welcome to JAVA World");
//Updating sprint name custom field value
values.setCustomfield_10201(10608);
Gson gson=new Gson();
String json= gson.toJson(values);
System.out.println("JSON Values " + json);
RequestSpecification httpRequest = RestAssured.given().header("Content-Type",
"application/json").body(json);
System.out.println(httpRequest + " Request ");
Response response = httpRequest.request(Method.POST, "");
System.out.println(response.getStatusCode());
String responseBody = response.getBody().asString();
System.out.println("response " + responseBody);
JsonPath jsonPath = new JsonPath(responseBody);
}
}
Getter and Setter File:
package jira;
import javax.xml.bind.annotation.XmlRootElement;
//#XmlRootElement
public class getterSetter {
private int project;
private int issueType;
private String reporter;
private String summary;
private int priority;
private String description;
private int customfield_10201;
public String getSummary() {
return summary;
}
public void setSummary(String summary) {
this.summary = summary;
}
public void setProject(int project){
this.project=project;
}
public int getProject() {
return project;
}
public int getIssueType() {
return issueType;
}
public void setIssueType(int issueType) {
this.issueType = issueType;
}
public String getReporter() {
return reporter;
}
public void setReporter(String reporter) {
this.reporter = reporter;
}
public int getPriority() {
return priority;
}
public void setPriority(int priority) {
this.priority = priority;
}
public String getDescription() {
return description;
}
public void setDescription(String description) {
this.description = description;
}
public int getCustomfield_10201() {
return customfield_10201;
}
public void setCustomfield_10201(int customfield_10201) {
this.customfield_10201 = customfield_10201;
}
}
I understand JSON format which I am passing through request Body is wrong. Can anyone help me to pass correct JSON format in Request Body.
I tested in Postman with the above JSON format Issue created successfully in my Instance.
For the above code am hitting with
response code 500 and Internal Server Error.
According to the JSON string as the payload to create Jira issue, you can directly create several corresponding classes as follows:
class IssueInfo {
private Field fields;
//general getters and setters
}
class Field {
private Project project;
private String summary;
private IssueType issuetype;
private Reporter reporter;
private Priority priority;
private String description;
private Customfield10201 customfield_10201;
//general getters and setters
}
class Project {
private String id;
//general getters and setters
}
class IssueType {
private String id;
//general getters and setters
}
class Reporter {
private String name;
//general getters and setters
}
class Priority {
private String id;
//general getters and setters
}
class Customfield10201 {
private String id;
//general getters and setters
}
After assigning value of each required field, you can pass the instance of IssueInfo as request body.

GSON throwing error when trying to pares a simple rest api response: Expected BEGIN_ARRAY but was BEGIN_OBJECT at line 1 column 2 path $

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?

How to convert Json into a Java bean object?

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

Map multi-level json string into class object in java

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.

Trouble converting Json Array into Pojo with array of pojos

JSON String
{
"order":{
"address":{
"city":"seattle"
},
"orderItem":[
{
"itemId":"lkasj",
"count":2
},
{
"itemId":"ldka",
"count":3
}
]
}
}
Order Class
public class Order {
private OrderItem[] orderItems;
private CustomerAddress address;
Order(OrderItem[] orderItems, CustomerAddress address ) {
this.orderItems = orderItems;
this.address = address;
}
public OrderItem[] getOrderItems() {
return orderItems;
}
public void setOrderItems(OrderItem[] orderItems) {
this.orderItems = orderItems;
}
public CustomerAddress getAddress() {
return address;
}
public void setAddress(CustomerAddress address) {
this.address = address;
}
}
My OrderItem class
package com.cbd.backend.model;
import org.springframework.data.annotation.Id;
public class OrderItem {
#Id
private String id;
private String itemId;
private String count;
public String getId() {
return id;
}
public void setId(String id) {
this.id = id;
}
unit Test that blows up
public String getItemId() {
return itemId;
}
public void setItemId(String itemId) {
this.itemId = itemId;
}
public String getCount() {
return count;
}
public void setCount(String count) {
this.count = count;
}
}
Unit test to demonstrate issue
package com.cbd.backend.model;
import com.google.gson.Gson;
import org.junit.Test;
import static org.junit.Assert.*;
public class OrderTest {
Gson gson = new Gson();
#Test
public void gsonToOrder() {
Order order = gson.fromJson( a, Order.class );
assertNotNull(order);
assertNotNull(order.getOrderItems()[0]);
}
private final String a = "{ \"order\": { \"address\": { \"city\": \"seattle\" },\"orderItem\":[{ \"itemId\":\"lkasj\", \"count\":2 }, { \"itemId\":\"ldka\", \"count\":3 } ] } }";
}
Should I be using something other than gson or am i constructing this incorrectly
There are two problems in your code:
The root element of your JSON is "order", but the class does not have a property with this name. Try changing you model or just removing the element from the JSON.
There is a mismatch in the name of the "orderItem" property. It is plural in the class, but singular in the JSON.
To sum it up, the following JSON will work without any changes to the code.
{
"address":{
"city":"seattle"
},
"orderItems":[
{
"itemId":"lkasj",
"count":2
},
{
"itemId":"ldka",
"count":3
}
]
}
Also, "count" as it appears in the JSON seems to be numeric, so you might want to change the type of OrderItem.count to int or java.lang.Integer.

Categories

Resources