Below is my JSON data. I want to convert this to POJOs to store the Name,id,profession in a header table and the respective Jsonarray field in a child table.
JSON:
{
"Name": "Bob",
"id": 453345,
"Profession": "Clerk",
"Orders": [
{
"Item": "Milk",
"Qty": 3
},
{
"Item": "Bread",
"Qty": 3
}
]
}
Entity classes:
public class User {
private String name;
private Integer id;
private String Profession;
private JsonArray Orders;
private UserCart userCart;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public Integer getId() {
return id;
}
public void setId(Integer id) {
this.id = id;
}
public String getProfession() {
return Profession;
}
public void setProfession(String profession) {
Profession = profession;
}
public JsonArray getOrders() {
return Orders;
}
public void setOrders(JsonArray orders) {
Orders = orders;
}
public UserCart getUserCart() {
return userCart;
}
public void setUserCart(UserCart userCart) {
this.userCart = userCart;
}
}
public class UserCart {
private String item;
private Integer qty;
public String getItem() {
return item;
}
public void setItem(String item) {
this.item = item;
}
public Integer getQty() {
return qty;
}
public void setQty(Integer qty) {
this.qty = qty;
}
}
But when I do below; I get error
Cannot deserialize instance of org.json.JSONArray out of START_ARRAY
token
User user = new User();
JsonNode data = new ObjectMapper().readTree(jsonString);
user = headerMap.readValue(data.toString(), User.class);
How do I go about assigning the entire JSON to both the Java objects ?
Use List<UserCart> for array data in json and use #JsonProperty for mapping different json node name to java object field. No need to use extra field (JsonArray Orders) anymore.
#JsonProperty("Orders")
private List<UserCart> userCart;
Related
I would like to iterate Products and get the list of name,code and price and set in my Model class. Any help would be really appreciated - how can I iterate this. When I use obj.get("Products") - it just printing as string - got stuck to iterate.
{
"id": "skd3303ll333",
"Products": [{
"name": "apple",
"code": "iphone-393",
"price": "1939"
},
{
"name": "ipad",
"code": "ipad-3939",
"price": "900"
}
]
}
#PostMapping(path="/create", consumes=MediaType.APPLICATION_JSON_VALUE)
public ResponseEntity<Object> create(#RequestBody Map<String, Object> obj ) {
System.out.println("Products :" + obj.get("Products"));
}
There are two ways to do this,
1) By type casting (personally i will not prefer this)
List<Map<Object,Object>> productslist = (List<Map<Object, Object>>) obj.get("products");
for(Map entry: productslist) {
for(Object s: entry.keySet()) {
System.out.println(s.toString());
System.out.println(entry.get(s).toString());
}
}
2) Mapping directly to Model class, for this approach you need Jackson library in buildpath
#JsonIgnoreProperties(unknown =true)
public class Customer {
#JsonProperty("id")
private String id;
#JsonProperty("products")
private List<Products> products;
public String getId() {
return id;
}
public void setId(String id) {
this.id = id;
}
public List<Products> getProducts() {
return products;
}
public void setProducts(List<Products> products) {
this.products = products;
}
}
#JsonIgnoreProperties(unknown =true)
class Products{
#JsonProperty("name")
private String name;
#JsonProperty("code")
private String code;
#JsonProperty("price")
private String price;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getCode() {
return code;
}
public void setCode(String code) {
this.code = code;
}
public String getPrice() {
return price;
}
public void setPrice(String price) {
this.price = price;
}
}
Controller
public ResponseEntity<Object> create(#RequestBody Customer obj ) {
You need POJO structure with two classes:
public class Product {
private String name;
private String code;
private int price;
}
public class ProductsGroup {
private long id;
private List<Product> products;
// getters/setters
}
And change your method signature to:
#PostMapping(path="/create", consumes=MediaType.APPLICATION_JSON_VALUE)
public ResponseEntity<ProductsGroup> create(#RequestBody ProductsGroup productGroup)
{
System.out.println("Products :" + productGroup.getProducts());
}
You are trying to process the json using a Map<String, Object> obj, which could be possible in some way, but mostly what you want to do is define a single or multiple POJO classes. These represent the json.
public class IdWrapper {
private String id;
#JsonProperty("Products")
private List<Product> products;
public String getId() {
return id;
}
public void setId(String id) {
this.id = id;
}
public List<Product> getProducts() {
return products;
}
}
public class Product {
private String name;
private String code;
private String price;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getCode() {
return code;
}
public void setCode(String code) {
this.code = code;
}
public String getPrice() {
return price;
}
public void setPrice(String price) {
this.price = price;
}
}
And in you controller like this:
#RestController
#RequestMapping("test")
public class DemoController {
#PostMapping()
public void test(#RequestBody IdWrapper productsWrapper) {
System.out.println();
}
}
I'm using Jackson as part of a spring boot app. I am turning JSON into Java, and I am getting this error. I did some research, but I still don't understand what is going wrong or how to fix it.
Here is the JSON fragment:
"dataBlock": {
"sections": [
{
"info": "",
"prompt": "",
"name": "First Section",
"sequence": 0,
"fields": [],
"gatingConditions": [],
"guid": "480d160c-c34f-4022-97b0-e8a1f28c49ae",
"id": -2
}
],
"prompt": "",
"id": -1,
"name": ""
}
So my Java object for this "dataBlock" element:
public class DataBlockObject {
private int id;
private String prompt;
private String name;
private List<SectionObject> sections;
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public String getPrompt() {
return prompt;
}
public void setPrompt(String prompt) {
this.prompt = prompt;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public List<SectionObject> getSections() {
return sections;
}
public void setSections(List<SectionObject> sections) {
this.sections = sections;
}
}
And the Section object is this:
public class SectionObject {
private int id;
private String name;
private String prompt;
private String info;
private int sequence;
private List<FieldObject> fields;
private List<GatingConditionObject> gatingConditions;
private String guid;
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getPrompt() {
return prompt;
}
public void setPrompt(String prompt) {
this.prompt = prompt;
}
public String getInfo() {
return info;
}
public void setInfo(String info) {
this.info = info;
}
public int getSequence() {
return sequence;
}
public void setSequence(int sequence) {
this.sequence = sequence;
}
public List<FieldObject> getFields() {
return fields;
}
public void setFields(List<FieldObject> fields) {
this.fields = fields;
}
public List<GatingConditionObject> getGatingConditions() {
return gatingConditions;
}
public void setGatingConditions(List<GatingConditionObject> gatingConditions) {
this.gatingConditions = gatingConditions;
}
public String getGuid() {
return guid;
}
public void setGuid(String guid) {
this.guid = guid;
}
}
So it seems to me that Jackson would make a DataBlockObject, map the obvious elemenets, and create an array that I have clearly marked as a List named sections. -- just like the JSON shows.
Now the error is:
Caused by: com.fasterxml.jackson.databind.exc.UnrecognizedPropertyException: Unrecognized field "sections" (class com.gridunity.workflow.bean.json.SectionObject), not marked as ignorable (8 known properties: "gatingConditions", "sequence", "prompt", "fields", "id", "info", "guid", "name"])
Now according to that error it would seem that one of my 8 elements should be named "sections" - But that's not one of my elements. It clearly has a problem with my List of Sections, but I cant figure out what it is.
Can someone explain WHY this is happening, especially sence it looks like I have my structure correct, and how to fix this. I have seen this on other posts:
objectMapper.disable(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES);
But that seems incredibly wrong as I know all of my properties.
It looks like the JSON itself has another sections field in one or more of the dataBlock.sections items. If you don't have control over the construction of the JSON object, you'll need to add a #JsonIgnoreProperties annotation on the SectionObject class so that when the JSON object has fields that aren't specified in the POJO, it won't throw an error during deserialization.
#JsonIgnoreProperties(ignoreUnknown = true)
public class SectionObject {
// class members and methods here
}
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.
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.
I am new to MongoDB and NoSQL databases at all and have some issues to working with MongoDB driver.
I don't properly understand how to get a sub-array/list from document and reinsert data in it.
This is my JSON/BSON object which i can easy save in MongoDB.
{
"_id": {
"$oid": "5757df25612c2445af329111"
},
"shop": {
"category": [
{
"MobilePhones": [
]
},
{
"TV-sets": [
]
},
{
"Motherboards": [
]
}
]
}
}
Now i need to get an Array of Categories from my Shop, get object as MobilePhones/TV-sets/Motherboards category from this array/list as i write in my java POJO class.
public class Category extends BasicDBObject implements Serializable {
private List<Goods> goodsList;
private BasicDBObject basicDBObject;
public BasicDBObject getBasicDBObject() {
return basicDBObject;
}
public void setBasicDBObject(BasicDBObject basicDBObject) {
this.basicDBObject = basicDBObject;
}
private String name;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public List<Goods> getGoodsList() {
return goodsList;
}
public void setGoodsList(List<Goods> goodsList) {
this.goodsList = goodsList;
}
public Category(String name){
this.name = name;
}
public Category(){}
}
And insert goods into this category as i write in
public class Goods extends BasicDBObject implements Serializable {
private String title;
private int price;
private String status;
private BasicDBObject basicDBObject;
public BasicDBObject getBasicDBObject() {
return basicDBObject;
}
public void setBasicDBObject(BasicDBObject basicDBObject) {
this.basicDBObject = basicDBObject;
}
public Goods(String title, int price, String status) {
this.title = title;
this.price = price;
this.status = status;
}
public String getTitle() {
return title;
}
public void setTitle(String title) {
this.title = title;
}
public int getPrice() {
return price;
}
public void setPrice(int price) {
this.price = price;
}
public String getStatus() {
return status;
}
public void setStatus(String status) {
this.status = status;
}
}
In this way i get/create collection at database
DBCollection collection = db.getCollection("shop");
BasicDBObject dbObject = new BasicDBObject();
dbObject.put("shop", shop.createCategoriesWithGoods());
collection.insert(dbObject);
But this way doesn't help me to get category as
DBCollection collection = db.getCollection("MobilePhones");
This is because a collection is a table (in SQL terms) so db.getCollection("MobilePhones"); is looking for a "table" called MobilePhones.
You have saved your data into a collection called "Shop". You need to call getCollection("Shop") then you can perform whatever operations you need to on the data.