UnrecognizedPropertyException: Unrecognized field "sections" - java

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
}

Related

JsonArray field in a JsonObject to Java Object

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;

JSON parse error: Cannot deserialize instance of.. out of START_ARRAY token

I know there are a few questions on stackoverflow regarding this problem. But I have have been spending hours trying to resolve this error without any success.
I am using the mysql database to store the values.
I keep on getting the error message from the
com.example.springboot.Recipe file.
This is springboot recipe file
package com.example.springboot;
import com.example.springboot.Recipe;
import javax.persistence.*;
import javax.validation.constraints.NotBlank;
import javax.validation.constraints.NotNull;
#Entity // This tells Hibernate to make a table out of this class
public class Recipe {
public Recipe(){
}
public Recipe(Integer id, String name, String description, String type, Integer preptime, Integer cooktime, String content, Integer difficulty){
this.id = id;
this.name = name;
this.description = description;
this.type = type;
this.preptime = preptimee;
this.cooktime = cooktime;
this.content = content;
this.difficulty = difficulty;
}
#Id
#GeneratedValue(strategy=GenerationType.AUTO)
private Integer id;
private String name;
private String description;
private String type;
private Integer preptime;
private Integer cooktime;
#Column(columnDefinition = "TEXT")
private String content;
private Integer difficulty;
public Integer getId() {
return id;
}
public void setId(Integer id) {
this.id = id;
}
public String getTitle() {
return name;
}
public void setTitle(String name) {
this.name = name;
}
public String getDescription() {
return description;
}
public void setDescription(String description) {
this.description = description;
}
public String getType() {
return type;
}
public void setType(String type) {
this.type = type;
}
public String getContent() {
return content;
}
public void setContent(String content) {
this.content = content;
}
public Integer getDifficulty() {
return difficulty;
}
public void setDifficulty(Integer difficulty) {
this.difficulty = difficulty;
}
public Integer getCookingtime() {
return cooktime;
}
public void setCookingtimeime(Integer cooktime) {
this.cooktime = cooktime;
}
public Integer getPreparationtime() {
return preptime;
}
public void setPreparationtime(Integer preptime) {
this.preptime = preptime;
}
}
Main Controller:
#PutMapping("/recipes/edit/{id}")
void updateRecipe2(#PathVariable int id, #RequestBody Recipe recipe ) {
Recipe recipe_ = recipeRepository.findById(id).get();
recipe_.setTitle(recipe.getTitle());
System.out.println("sss " + recipe.getname());
System.out.println("change");
recipeRepository.save(recipe_);
}
service.ts:
updateRecipe2 (id: number, recipe: any): Observable<any > {
const url = `${this.usersUrl}/edit/${id}`;
return this.http.put(url ,recipe);
}
where the updateRecipe2 gets called:
save(): void {
const id = +this.route.snapshot.paramMap.get('name');
this.recipeService.updateRecipe2(id, this.recipes)
.subscribe(() => this.gotoUserList());
}
as soon as the user clicks save this functions saves the changes made.
I hope the code snippets that I provided are enough to help solve the problem.
Thank you in advance.
I am building a rest api with spring boot and I am using angularjs as it's frontend. I am pretty new to web-development.
You are sending a list of recipes to an api endpoint that expects a single recipe object.
Your options are:
Send only one recipe object at a time, for example:
this.recipeService.updateRecipe2(id, this.recipes[0])
OR: create a new API endpoint to accept a list of recipes, to edit them in "batch"
#PutMapping("/recipes/edit")
void updateRecipes(#RequestBody List<Recipe> recipe ) {
my Example:
Use:
#PostMapping
Code:
public void setTransacciones(List<Transacciones> transacciones) {
this.transacciones = transacciones;
}
CodeBean:
public class Transacciones {
public String getText() {
return text;
}
public void setText(String text) {
this.text = text;
}
private String text;
}
Post(raw):
{
"transacciones" : [ {"text" : "1"}, {"text" : "2"} ]
}
Result:
{
"transacciones": [
{
"transaccionId": 2,
"text": "1"
},
{
"transaccionId": 3,
"text": "2"
}
]
}
BINGO!!

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.

Json Structure is So Different unable to change that to Java Objects

I am working on facebook application. When i queried for https://graph.facebook.com/me/video.watches?offset=0&limit=1000 I am getting a List of Watched Movies. For eg. I am pasting only one movie out of that list here.
{
"data": [
{
"id": "664878940211923",
"data": {
"tv_show": {
"id": "108611845829948",
"url": "https://www.facebook.com/pages/Popeye-the-Sailor/108611845829948",
"type": "video.tv_show",
"title": "Popeye the Sailor"
}
},
"type": "video.watches",
},
Here is the POJO Class I created to convert this to Java.
import java.util.List;
public class FBUserVideoWatches {
private List<Data> data;
public List<Data> getData() {
return data;
}
public void setData(List<Data> data) {
this.data = data;
}
public class Data{
private long id;
private TVData data;
private String type;
public long getId() {
return id;
}
public void setId(long id) {
this.id = id;
}
public TVData getData() {
return data;
}
public void setData(TVData data) {
this.data = data;
}
public String getType() {
return type;
}
public void setType(String type) {
this.type = type;
}
}
public class TVData{
private TV_Shows tv_shows;
public TV_Shows getTv_shows() {
return tv_shows;
}
public void setTv_shows(TV_Shows tv_shows) {
this.tv_shows = tv_shows;
}
}
public class TV_Shows{
private long id;
private String url;
private String type;
private String title;
public long getId() {
return id;
}
public void setId(long id) {
this.id = id;
}
public String getUrl() {
return url;
}
public void setUrl(String url) {
this.url = url;
}
public String getType() {
return type;
}
public void setType(String type) {
this.type = type;
}
public String getTitle() {
return title;
}
public void setTitle(String title) {
this.title = title;
}
}
}
Here is how i convert the json to java.
FBUserVideoWatches fbUserVideoWatches = gson.fromJson(response.getBody(), FBUserVideoWatches.class);
for (Data data : fbUserVideoWatches.getData()) {
System.out.println(data.getId());//This only works and I am getting values.
if(null != data.getData()){
if(null!=data.getData().getTv_shows()){
System.out.print(data.getData().getTv_shows().getTitle());
}
if(null!=data.getData().getTv_shows()){
System.out.print(data.getData().getTv_shows().getType());
}
}
}
When I use getter methods to get data from java class I am getting ID 664878940211923 & "type": "video.watches" as shown above. The members inside "tv_show" I am unable to access. I think some where I went wrong in creating POJO. I am unable to find that mistake. Please help me what corrections is necessary to make that work. Hope my question is clear. Thanks in Advance.
You were doing mistake in TVData Class your forgot serialized name on instance property coz its in diffferent in json and TV data class
#SerializedName(value="tv_show")
private TV_Shows tv_shows;
Assuming your json is like this
{
"data":[
{
"id":"664878940211923",
"data":{
"tv_show":{
"id":"108611845829948",
"url":"https://www.facebook.com/pages/Popeye-the-Sailor/108611845829948",
"type":"video.tv_show",
"title":"Popeye the Sailor"
}
},
"type":"video.watches"
},
{
"id":"664878940211923",
"data":{
"tv_show":{
"id":"108611845829948",
"url":"https://www.facebook.com/pages/Popeye-the-Sailor/108611845829948",
"type":"video.tv_show",
"title":"Popeye the Sailor"
}
},
"type":"video.watches"
}
]
}
Parsing model will like below according you to your json format
public class FBUserVideoWatches {
private List<Data> data;
public List<Data> getData() { return data; }
public void setData(List<Data> data) { this.data = data;}
}
public class Data {
private TVData data;
private String id;
private String type;
// setter/getter here
}
public class TVData {
#SerializedName(value="tv_show")
private Show show;
// setter/getter here
}
public class Show {
private String id;
private String url;
private String type;
private String title;
// setter/getter here
}
finally with Google Gson parse your object as like below
Gson gson = new Gson();
FBUserVideoWatches fbUserVideoWatches =gson.fromJson(json_string, FBUserVideoWatches.class);

Deserializing JSON using Jackson 2

I have a json
[
{
"host": {
"name": "anotherfullhost",
"id": 55602819,
"operatingsystem_id": 1073012828,
"hostgroup_id": null
}
},
{
"host": {
"name": "dhcp.mydomain.net",
"id": 219245707,
"operatingsystem_id": 1073012828,
"hostgroup_id": null
}
},
{
"host": {
"name": "my5name.mydomain.net",
"id": 980190962,
"operatingsystem_id": 1073012828,
"hostgroup_id": null
}
}
]
I would like to construct a Collection by deserializing the above json. What jackson annotations should I add to the below Host class
public class Host {
#JsonProperty("id")
private Long id;
#JsonProperty("name")
private String name;
#JsonProperty("operatingsystem_id")
private Long operatingSystemId;
#JsonProperty("hostgroup_id")
private Long hostGroupId;
public Long getId() {
return id;
}
public void setId(Long id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public Long getOperatingSystemId() {
return operatingSystemId;
}
public void setOperatingSystemId(Long operatingSystemId) {
this.operatingSystemId = operatingSystemId;
}
public Long getHostGroupId() {
return hostGroupId;
}
public void setHostGroupId(Long hostGroupId) {
this.hostGroupId = hostGroupId;
}
#Override
public String toString() {
return "Host{" +
"name='" + name + '\'' +
'}';
}
}
Any suggestions?
Note - I am using jackson 2.x API.
Thanks.
Update
Adding a wrapper object does the trick.
public class HostWrapper {
#JsonProperty("host")
private Host host;
public Host getHost() {
return host;
}
public void setHost(Host host) {
this.host = host;
}
#Override
public String toString() {
return host.toString();
}
}
and the below code to deserialize
ObjectMapper mapper = new ObjectMapper();
HostWrapper[] host = mapper.readValue(jsonString, HostWrapper[].class);
Please see this post - This should be the same issue than yours, even if a different API is used:
JsonMappingException: Current token not START_OBJECT (needed to unwrap root name 'Transaction[]'), but START_ARRAY

Categories

Resources