Json to Java Object with same key but different objects inisde - java

I have a question how to map JSON Objects with same key to different objects.
If I write 2 classes with the specific fields I get an error because the data element is contained twice.
How can I map the resource A to class A and the resource B to class B?
{
"ETag":"oiojojojojoj==",
"elements":[
{
"resource":"A",
"ETag":null,
"data":[
{
"anotherfield":"text",
"id":1,
"name":"GB"
}
]
},
{
"resource":"B",
"ETag":"dmVuZG9yOzIwMTctMDUtMDlUMTQ6MzE6NDNa",
"data":[
{
"field":"read",
"id":1
}
]
}
]
}
The classes could look like this:
public class Element {
#JsonProperty("resource")
public String resource = null;
#JsonProperty("ETag")
public Object eTag = null;
#JsonProperty("data")
public List<A> dataInA = null;
#JsonProperty("data")
public List<B> dataInB = null;
}
public class Example {
#JsonProperty("ETag")
public String eTag;
#JsonProperty("elements")
public List<Element> elements = null;
}
Class A
public class A {
#JsonProperty("anotherfield")
public String anotherfield;
#JsonProperty("id")
public Integer id;
#JsonProperty("name")
public String name;
}
Class B
public class B {
#JsonProperty("field")
public String field;
#JsonProperty("id")
public Integer id;
}
Thanks a lot!
EDIT:
When I switch the JSON elements to dataA and dataB It works.
{
"ETag":"oiojojojojoj==",
"elements":[
{
"resource":"A",
"ETag":null,
"dataA":[
{
"anotherfield":"text",
"id":1,
"name":"GB"
}
]
},
{
"resource":"B",
"ETag":"dmVuZG9yOzIwMTctMDUtMDlUMTQ6MzE6NDNa",
"dataB":[
{
"field":"read",
"id":1
}
]
}
]
}
Element class:
public class Element {
#JsonProperty("resource")
public String resource;
#JsonProperty("ETag")
public Object eTag;
#JsonProperty("dataA")
public List<A> dataInA;
#JsonProperty("dataB")
public List<B> dataInB;
}

Related

How to convert a POST API call with a JSON body to a java class in Springboot?

i'm passing a POST request with raw JSON body which holds the configuration details, i want to save it as a java class so i can distribute the data using getters to relevant classes that need the config details specified for them.This is the body of my request
{
"aisles" : 2,
"sections" : 2,
"shelves" : 1,
"packagingAreas": [ "a1.3", "a2.3" ],
"workers" : [
{
"name" : "rem",
"location" : "a1.1",
"capacity" : 20
}
],
"items" : [
{
"id" : "mars",
"name" : "Mars",
"supplier" : "Nestle",
"weight" : 1
},
{
"id" : "kitkat",
"name" : "Kit Kat",
"supplier" : "Nestle",
"weight" : 1
},
{
"id" : "dd",
"name" : "Double Decker",
"supplier" : "Nestle",
"weight" : 1
}
]
}
and i want to the details of that body into my config.java class, this is the config.java class
public class Config {
private static String aisles;
private static String sections;
private static String shelves;
private static String packagingAreas[];
private static ArrayList<Worker> workers;
private static ArrayList<Item> items;
public static String getAisles() {
return aisles;
}
public static String getSections() {
return sections;
}
public static String getShelves() {
return shelves;
}
public static String[] getPackagingAreas() {
return packagingAreas;
}
public static ArrayList<Worker> getWorkers() {
return workers;
}
public static ArrayList<Item> getItems() {
return items;
}
}
And i have modelled the worker and item classes with the same variables as in the json configuration file, is there a direct way to convert this JSON file to a class? if not what other methods can i try?
Thanks in advance!
edit- This is the endpoint i have created, using #Rest Controller
#RequestMapping(value ="/config", method = RequestMethod.POST)
public void configure() {
//i want to do the conversion here
}
Update the controller as follows
#RequestMapping(value ="/config", method = RequestMethod.POST)
public void configure(#RequestBody Config config) {
//your json is converted to config java object
}
Update your Config class
public class Config {
private String aisles;
private String sections;
private String shelves;
private String packagingAreas[];
private ArrayList<Worker> workers;
private ArrayList<Item> items;
public void setAisles(String aisles) {
this.aisles = aisles;
}
public void setSections(String sections) {
this.sections = sections;
}
public void setShelves(String shelves) {
this.shelves = shelves;
}
public void setPackagingAreas(String[] packagingAreas) {
this.packagingAreas = packagingAreas;
}
public void setWorkers(ArrayList<Worker> workers) {
this.workers = workers;
}
public void setItems(ArrayList<Item> items) {
this.items = items;
}
public String getAisles() {
return aisles;
}
public String getSections() {
return sections;
}
public String getShelves() {
return shelves;
}
public String[] getPackagingAreas() {
return packagingAreas;
}
public ArrayList<Worker> getWorkers() {
return workers;
}
public ArrayList<Item> getItems() {
return items;
}
}
Explanation
By default spring boot comes with several HttpMessageConverters enabled. One of them is MappingJacksonHttpMessageConverter which converts your json to java object.
See this http message converter

Cannot deserialize instance of `org.json.JSONObject`

I have a basic SpringBoot 2.1.5.RELEASE app. Using Spring Initializer, JPA, embedded Tomcat, Thymeleaf template engine, and package as an executable JAR file with some RestControllers.
In 1 of the controller this is the body I send:
{
"depositHotel": "xxx",
"destinationHotel": "aaa",
"depositHotelAmount": "0.2",
"destinationHotelAmount": "4",
"destinationAddress": [{
"address": "asdf",
"tag": ""
}],
"refundAddress": [{
"address": "pio",
"tag": ""
}]
}
so I create this class to use it as a RequestBody:
public class HotelswitchHotelOrderRequestBody {
public static class Builder {
private String depositHotel;
private String destinationHotel;
private Float depositHotelAmount;
private Float destinationHotelAmount;
private JSONObject destinationAddress;
private JSONObject refundAddress;
public Builder(String depositHotel, String destinationHotel) {
this.depositHotel = depositHotel;
this.destinationHotel = destinationHotel;
}
public Builder withDepositHotelAmount (Float depositHotelAmount) {
this.depositHotelAmount = depositHotelAmount;
return this;
}
public Builder withDestinationHotelAmount (Float destinationHotelAmount) {
this.destinationHotelAmount = destinationHotelAmount;
return this;
}
public Builder toDestinationAddress (JSONObject destinationAddress) {
this.destinationAddress = destinationAddress;
return this;
}
public Builder toRefundAddress (JSONObject refundAddress) {
this.refundAddress = refundAddress;
return this;
}
public HotelswitchHotelOrderRequestBody build(){
HotelswitchHotelOrderRequestBody order = new HotelswitchHotelOrderRequestBody();
order.depositHotel = this.depositHotel;
order.depositHotelAmount = this.depositHotelAmount;
order.destinationAddress = this.destinationAddress;
order.destinationHotel = this.destinationHotel;
order.destinationHotelAmount = this.destinationHotelAmount;
order.refundAddress = this.refundAddress;
return order;
}
}
private String depositHotel;
private String destinationHotel;
private Float depositHotelAmount;
private Float destinationHotelAmount;
private JSONObject destinationAddress;
private JSONObject refundAddress;
private HotelswitchHotelOrderRequestBody () {
//Constructor is now private.
}
public String getDepositHotel() {
return depositHotel;
}
public void setDepositHotel(String depositHotel) {
this.depositHotel = depositHotel;
}
public String getDestinationHotel() {
return destinationHotel;
}
public void setDestinationHotel(String destinationHotel) {
this.destinationHotel = destinationHotel;
}
public Float getDepositHotelAmount() {
return depositHotelAmount;
}
public void setDepositHotelAmount(Float depositHotelAmount) {
this.depositHotelAmount = depositHotelAmount;
}
public Float getDestinationHotelAmount() {
return destinationHotelAmount;
}
public void setDestinationHotelAmount(Float destinationHotelAmount) {
this.destinationHotelAmount = destinationHotelAmount;
}
public JSONObject getDestinationAddress() {
return destinationAddress;
}
public void setDestinationAddress(JSONObject destinationAddress) {
this.destinationAddress = destinationAddress;
}
public JSONObject getRefundAddress() {
return refundAddress;
}
public void setRefundAddress(JSONObject refundAddress) {
this.refundAddress = refundAddress;
}
}
But I have this error when receiving the object:
JSON parse error: out of START_ARRAY token; nested exception is com.fasterxml.jackson.databind.exc.MismatchedInputException: Cannot deserialize instance of `org.json.JSONObject` out of START_ARRAY token
JSONObject's representation in actual JSON is a hash i.e. {...}. In your json data you're providing an array of hashes [{...}] which is not the same. Judging from your domain I don't think it has to be multiple values, so you can just omit [] in your payload and if it does then the fields in your Java class can be defined as JSONArray.
However, I think you should go with defining an Address class and either using
private Address destinationAddress;
private Address refundAddress;
or if it indeed does have to be an object array
private List<Address> destinationAddresses;
private List<Address> refundAddresses;
I had a similar usecase , where I could not define the json to a POJO. Using com.fasterxml.jackson.databind.JsonNode instead of the JSONObject worked.

I have DTO for each json payload. I get the payload through http post request. I get two payloads but how to combine them to final payload

I have DTO for payload1, payload2 and payload3.
How to get the payload3?
using payload 1 and payload 2.
How to establish the mapping between the data models?
DTO 1
public class DataRequestModel {
private DataValue data; //some example
private long timestamp;
#Data
public static class DataValue {
private Value1 value1;
private Value2 value2;
}
#Data
public static class Value1 {
private long val;
}
#Data
public static class Value2 {
private long val;
}
}
Data Model 2
public class Guid{
private string guid;
}
Datamodel 3
public class payload{
private String guid;
private long longvalue;
private long timestamp;
}
## Controller
#RestController
#RequestMapping("/users")
public class DataTransferController {
List<Payload> payload;
#PostMapping("/list")
public void data(#RequestBody DataRequestModel dataRequestModel){
Not sure how to do from here...
for(Payload temp: payload){
temp.getLongValue()=dataRequestModel.getData().
}
}
}
These are the structure of the JSON
1.JSON payload1
{
"data":{
"value1":{
"val":30
}, "value2":{
"val":20
}
},
"timestamp":155501523
}
2.JSON payload2
{
"guid":[
"/value1",
"/value2"
]
}
3.JSON final payload (to be sent)
[
{
"guid":"/value1",
"longvalue":30,
"timestamp":155501523
},
{
"guid":"/value2",
"longvalue":20,
"timestamp":155501523
}
]
My code for generating payload 3 is
#RestController #RequestMapping("/users")
public class DataTransferController
{
List<Payload> payload; #PostMapping("/list")
public void data(#RequestBody DataRequestModel dataRequestModel)
{
Not sure how to do from here... for(TimeseriesPayload temp: timeseriesPayload)
{
temp.getLongValue()=dataRequestModel.getData().
}
}
}
You don't need for loop to do this, in the public void data create List<Payload>
public void data(#RequestBody DataRequestModel dataRequestModel) {
List<Payload> list = new ArrayList<>();
// first object
Payload payload1 = new Payload();
payload1.setGuid(//set value);
payload1.setLongValue(dataRequestModel.getData().getValue1().getVal());
payload1.setTimestamp(dataRequestModel.getTimestamp());
list.add(payload1);
// second object
Payload payload2 = new Payload();
payload12setGuid(//set value);
payload2.setLongValue(dataRequestModel.getData().getValue2().getVal());
payload1.setTimestamp(dataRequestModel.getTimestamp());
list.add(payload2);
And then finally return List

Realm can't create Nested Objects from Json

I've been trying to create a nested RealmObject using a json but it only creates the first Object and not the nested ones. I would appreciate a help on this.
my Realm classes:
Content.java
public class Content extends RealmObject {
private String uuid;
RealmList<ContentDetailModel> ContentDetail;
public Content() {
super();
this.uuid = UUID.randomUUID().toString();
}
public String getUuid() {
return uuid;
}
public RealmList<ContentDetailModel> getContentDetails() {
return ContentDetail;
}
public void setContentDetails(RealmList<ContentDetailModel> contentDetails) {
this.ContentDetail = contentDetails;
}
}
ContentDetailModel.java:
public class ContentDetailModel extends RealmObject {
String FileName;
String ContentTypeID;
RealmList<ContentDetailMetadataModel> ContentDetailMetadata;
RealmResults<Content> content = null;
public String getFileName() {
return FileName;
}
public void setFileName(String fileName) {
FileName = fileName;
}
public String getContentTypeID() {
return ContentTypeID;
}
public void setContentTypeID(String contentTypeID) {
ContentTypeID = contentTypeID;
}
public RealmList<ContentDetailMetadataModel> getContentDetailMetadata() {
return ContentDetailMetadata;
}
public void setContentDetailMetadata(RealmList<ContentDetailMetadataModel> contentDetailMetadataz) {
this.ContentDetailMetadata = contentDetailMetadataz;
}
}
and the rest of nested classes are like these. my Json string is as follows:
"
{
"Content":{
"ContentDetail":[
{
"FileName":"test.mp3",
"ContentTypeID":3,
"ContentDetailMetadata":{
"Metadata":[
{
"ID":2,
"Value":"2017-08-02 09:40:30"
},
{
"ID":1,
"Value":"35.73876557934912,51.50785446166992"
}
]
}
},
{
"FileName":"2.jpg",
"ContentTypeID":2,
"ContentDetailMetadata":[
{
"Metadata":{
"ID":2,
"Value":"2017-08-02 09:40:30"
}
},
{
"Metadata":{
"ID":1,
"Value":"35.73876557934912,51.50785446166992"
}
}
]
}
]
}
}
"
and the code I use to do it is :
realm.createObjectFromJson(json)
{
"Content":{
"ContentDetail":[
{
"FileName":"test.mp3",
"ContentTypeID":3,
"ContentDetailMetadata":[{
"Metadata":[
{
"ID":2,
"Value":"2017-08-02 09:40:30"
},
{
"ID":1,
"Value":"35.73876557934912,51.50785446166992"
}
]
}]
},
Translates to:
public class Root extends RealmObject {
private Content Content;
}
public class Content extends RealmObject {
private RealmList<ContentDetail> ContentDetail;
#LinkingObjects("Content")
private final RealmResults<Root> roots = null;
}
public class ContentDetail extends RealmObject {
private String FileName;
private long ContentTypeID;
//private ContentDetailMetadata ContentDetailMetadata;
private RealmList<ContentDetailMetadata> ContentDetailMetadata;
#LinkingObjects("ContentDetail")
private final RealmResults<Content> contents = null;
}
public class ContentDetailMetadata extends RealmObject {
private RealmList<Metadata> Metadata;
#LinkingObjects("ContentDetailMetadata")
private final RealmResults<ContentDetail> contentDetails = null;
}
public class Metadata extends RealmObject {
private long ID;
private String Value;
#LinkingObjects("Metadata")
private final RealmResults<ContentDetailMetadata> contentDetailMetadatas = null;
}
If your schema doesn't look like that, then createOrUpdateFromJson() won't work.
Personally I would advise against using this schema though, it's pretty bad as a Realm schema. It's advisable to parse the JSON and then map it into a schema that makes more sense!
It looks like your JSON has put all fields for the Content object under the Context JSON object instead of directly under the top-level object where it should be.
If you do this, it should work:
realm.createObjectFromJson(Content.class, json.getJSONObject("Content"));

Deserialize JSON to Java objects with inheritance?

I need to deserialize the following:
{
"name": "library",
"contains": [
{
"name: "office",
"contains": []
},
{
"name": "Home",
"contains":[{
"name": "Shelf",
"contains" : []
}]
}]
}
My class looks like this:
public class Container
{
String containerName;
}
Public class Contains extends Container {
#SerializedName("contains")
#Expose
private List<Container> contains;
}
How is it that when I run my code, I am hoping to get a contains object to run my methods it won't get me them. But I get a container object and can't run my methods from within my Contains class.
You don't need inheritance here. Just use Gson.fromJson().
Object class
public class Container {
#SerializedName("name")
#Expose
private String name;
#SerializedName("contains")
#Expose
private List<Container> contains;
public Container(String name) {
this.name = name;
contains = new ArrayList<Container>();
}
public void setName(String name) {
this.name = name;
}
public void add(Container c) {
this.contains.add(c);
}
public void setContainerList(List<Container> contains) {
this.contains = contains;
}
public String getName() {
return name;
}
public List<Container> getContainerList() {
return this.contains;
}
}
Code
public static void main(String[] args) {
Container lib = new Container("library");
Container office = new Container("office");
Container home = new Container("Home");
Container shelf = new Container("Shelf");
home.add(shelf);
lib.add(office);
lib.add(home);
Gson gson = new Gson();
// Serialize
String json = gson.toJson(lib);
// Deserialize
Container container = gson.fromJson(json, Container.class);
System.out.println(container.getName());
for (Container c : container.getContainerList()) {
System.out.println("-- " + c.getName());
}
}
Output
library
-- office
-- Home

Categories