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