Dynamically add property:value in JSON through rest services - java

How do we create a json property:value dynamically by taking them as inputs from the user through a REST service, without having to have fields to hold the value.
Basically, the present output is :
{
"name": "X",
"price": "X",
"ticker": "X",
"status": "X",
"supplier": "X",
"attribute": [{
"key": "index",
"value": "Nasdaq"
},
{
"key": "priority",
"value": "high"
}
]
}
Required output is :
{
"name": "X",
"price": "X",
"ticker": "X",
"status": "X",
"supplier": "X",
"attribute": [{
"index": "Nasdaq"
},
{
"priority": "high"
}
]
}
Here, index and Nasdaq are the values given by the user, which is the key-value pair that is to be added to the attribute list.
The two POJO's used :
Stock.java
#XmlRootElement
public class Stock {
public Stock() {
}
public Stock(String name, double price, String ticker, String status, String supplier, List<KV> attribute) {
super();
this.name = name;
this.price = price;
this.ticker = ticker;
this.status = status;
this.supplier = supplier;
this.attribute = attribute;
}
private String name;
private double price;
private String ticker;
private String status;
private String supplier;
private List<KV> attribute;
public List<KV> getAttribute() {
return attribute;
}
public void setAttribute(List<KV> attribute) {
this.attribute = attribute;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public double getPrice() {
return price;
}
public void setPrice(double price) {
this.price = price;
}
public String getTicker() {
return ticker;
}
public void setTicker(String ticker) {
this.ticker = ticker;
}
public String getStatus() {
return status;
}
public void setStatus(String status) {
this.status = status;
}
public String getSupplier() {
return supplier;
}
public void setSupplier(String supplier) {
this.supplier = supplier;
}
}
And :
KV.java
public class KV {
private String key;
private String value;
public KV(String key, String value) {
super();
this.key = key;
this.value = value;
}
public String getKey() {
return key;
}
public void setKey(String key) {
this.key = key;
}
public String getValue() {
return value;
}
public void setValue(String value) {
this.value = value;
}
}
Would prefer answers relating to usage of annotations or changes in the rest service, and not text processing at the end.

Okay, once you get the response you are getting currently then instead of a class "public class KV {} ", you can create a Hashmap,
& key of the Hashmap can hold the index/priority etc & value can hold Nasdaq/high.
Also name the Hashmap variable as "attribute".
So that you can extract the data from API using your current structure & then can convert it to one as I said above & send the response.

Try using Attributes class in java
Instead of defining a list of object you can just define
Attribute attributes;
For more details about how Attribute class works visit https://docs.oracle.com/javase/8/docs/api/org/xml/sax/Attributes.html

Related

Matching a value in a Array list in java

I am trying to match a value in a list using variable and return the list if condition matches.
result =
{
"drives": [{
"id": "0AEz3mOyzyCb7Uk9PVA",
"name": "Dev-zz-SFJobs-2020-10"
}, {
"id": "0AMEHi1wsq-8FUk9PVA",
"name": "Dev-zz-SFJobs-2020-11"
},
],
"nextPageToken": "~!!~AI9FV7RVoBRduLEGDhuzy0aSZShRe4uSXy20zpCBTP2LFWCXS0c"
}
folderName = "Dev-zz-SFJobs-2020-10"
java code:
if(result.getDrives().contains(folderName))
{
return result;
} else {
}
I am trying above code, how can i achieve this?
This would work for you if you are using java 8+
Optional<Drives> value = result.getDrives().stream().filter(drive -> drive.getName().equals(folderName)).findAny();
if (value.isPresent()){
return result;
}else{
}
I am expecting your model class Drive contains two variables of type string namely "id" and "name"
public class Drives {
private String id;
private String name;
public Drives(String id, String name) {
this.id = id;
this.name = name;
}
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;
}
}

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;

UnrecognizedPropertyException: Unrecognized field "sections"

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
}

How to deserialize nested JSON using GSON

JSON
"entities": {
"nca_location": [
{
"confidence": 0.85126983589896,
"value": "struga",
"type": "value"
},
{
"confidence": 0.9188255680843,
"value": "Skopje",
"type": "value"
}
],
"intent": [
{
"confidence": 0.99990092463824,
"value": "nca_get_position_availability"
}
]
}
EntityDto
public class EntityDto {
private String name;
private List<EntityValueDto> values;
public EntityDto(String name, List<EntityValueDto> values) {
this.name = name;
this.values = values;
}
public List<EntityValueDto> getValues() {
return values;
}
public void setValues(List<EntityValueDto> values) {
this.values = values;
}
}
EntityValueDto
public class EntityValueDto {
private Float confidence;
private String value;
public EntityValueDto(Float confidence, String value) {
this.confidence = confidence;
this.value = value;
}
public Float getConfidence() {
return confidence;
}
public void setConfidence(Float confidence) {
this.confidence = confidence;
}
public String getValue() {
return value;
}
public void setValue(String value) {
this.value = value;
}
}
How can I use GSON/Jackson to make this sort of mapping automatic? I would like to only extract the entities values and make a list out of them.
EntityDto example: nca_location would be the name, and the list would be the parsed objects.
ResponseEntity response = restTemplate.exchange(requestUrl, HttpMethod.POST, entity, Object.class);
This is how I get the response object from the API and I have no idea how to proceed.

exception while convert string to jsonobject

I have a String in my servlet which is of the following format.
{
"name": "Jam",
"noOfBooksRequired": "2",
"type": "Type 1",
"bookName": [
"The Magic",
"The Power"
]
}
where the bookName is an array. I want to access the values in the array and populate in the bean. But, when I try to convert the string to jsonobject, I am getting the following exception because bookName is an array com.google.gson.JsonSyntaxException: java.lang.IllegalStateException: Expected a string but was BEGIN_ARRAY This is how I am trying to do it
JSONObject js= new JSONObject();
String inputData= request.getParameter("inputData");
HashMap<String, String> hmap= new HashMap<String, String>();
Type type = new TypeToken<HashMap<String, String>>(){}.getType();
hmap = gson.fromJson(inputData, type);
js.putAll(hmap);
What I am doing is, I convert the string to a map and then add it to the JSONObject.
Since there are many json serializers and not sure which is the best. Right now, I have net.sf.json.JSONObject and com.google.gson.JsonObject
Can someone help me to get this solved.
Thanks in advance
You can map your JSON to a POJO.
If the book will have more attributes besides the name, you'll need two POJOs, as you can see below.
A POJO for the book:
class Book {
private String name;
private String author;
public Book() {
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getAuthor() {
return author;
}
public void setAuthor(String author) {
this.author = author;
}
}
And a POJO for the shelf, which have a list of books:
class Shelf {
private String name;
private Integer noOfBooksRequired;
private String type;
private List<Book> books;
public Shelf() {
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public Integer getNoOfBooksRequired() {
return noOfBooksRequired;
}
public void setNoOfBooksRequired(Integer noOfBooksRequired) {
this.noOfBooksRequired = noOfBooksRequired;
}
public String getType() {
return type;
}
public void setType(String type) {
this.type = type;
}
public List<Book> getBooks() {
return books;
}
public void setBooks(List<Book> books) {
this.books = books;
}
}
Your JSON will look like this:
{
"name": "Jam",
"noOfBooksRequired": "2",
"type": "Type 1",
"books": [
{"name": "The Magic", "author": "John Doe"},
{"name": "The Power", "author": "Jane Doe"}
]
}
And then you can use Gson to parse your JSON:
Gson gson = new Gson();
Shelf shelf = gson.fromJson(inputData, Shelf.class);
Update
Considering your JSON looks like this (the book can be represented as a String):
{
"name": "Jam",
"noOfBooksRequired": "2",
"type": "Type 1",
"books": [
"The Magic",
"The Power"
]
}
Only one POJO with a list of String is enough:
class Shelf {
private String name;
private Integer noOfBooksRequired;
private String type;
private List<String> books;
public Shelf() {
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public Integer getNoOfBooksRequired() {
return noOfBooksRequired;
}
public void setNoOfBooksRequired(Integer noOfBooksRequired) {
this.noOfBooksRequired = noOfBooksRequired;
}
public String getType() {
return type;
}
public void setType(String type) {
this.type = type;
}
public List<String> getBooks() {
return books;
}
public void setBooks(List<String> books) {
this.books = books;
}
}

Categories

Resources