How to map Json to Java object using jackson - java

I am using jackson to map json which I get from my post rest api to map to a java object.
the json is represent by
{
"baseName": "xyz",
"salary": [
{
"id": 1,
"info": {
"ename": "john",
"eid": 143
}
},
{
"id": 2,
"info": {
"ename": "bg",
"eid": 123
}
}
]
}
The java class are represent by
BaseInfo.java
class BaseInfo {
String baseName;
ArrayList<salary> salaries = new ArrayList<salary>();
}
Salary.java
class Salary {
int id;
EmplInfo emp;
}
EmplInfo.java
class EmplInfo{
String ename;
int eid;
}
But in the when call the api with this json I get the arraylist initialized but contains nothings. What I am doing wrong ? I get other information like baseName,etc

You can use the JsonProperty annotation to rename properties
class BaseInfo {
String baseName;
#JsonProperty("salary")
ArrayList<salary> salaries = new ArrayList<salary>();
}
class Salary {
int id;
#JsonProperty("info")
EmplInfo emp;
}

Following are the solutions:
Either add JsonProperty annotations as specified by Michael or update json keys i.e 'salary' to 'salaries' and 'info' to 'emp'

Related

Pass one attribute three times in a json array in a json serializable object in java

I am trying to duplicate the following JSON Payload using a Java serializable object.
{
"startDate": "2022-09-11",
"endDate": "9999-12-31",
"columns": [
{
"attribute": "FTOS"
},
{
"attribute": "StartDate"
},
{
"attribute": "EndDate"
}
],
"ids": [
{
"id": "EAY9",
"idType": "InvestmentId"
}
]
}
Below is the POJO and code I am trying.
public class Column{
public String attribute;
}
public class Id{
public String id;
public String idType;
}
public class Root{
public String startDate;
public String endDate;
public ArrayList<Column> columns;
public ArrayList<Id> ids;
}
The issue is while setting the attribute. If you see in the payload, we have it repeated three times whereas I am trying to set that in the following manner to replicate the same but I am getting only a single attribute in my payload. Below is the code.
Column col=new Column();
List<Column> colList=new ArrayList<>();
col.setAttribute("FTOS");
col.setAttribute("StartDate");
col.setAttribute("EndDate");
colList.add(col);
But I am getting the following payload in the actual output.
{
"startDate": "2022-09-11",
"endDate": "9999-12-31",
"columns": [
{
"attribute": "EndDate"
}
],
"ids": [
{
"id": "EAY9",
"idType": "InvestmentId"
}
]
}
The attribute you see is displayed only once. How to generate it three times as in the expected payload?
As #Anon indicated in the comments: "you need 3 objects of columns you only have one –
Anon"
Create a new Column object for each attribute you need to add to the list:
List<Column> colList=new ArrayList<>();
Column col1=new Column();
col1.setAttribute("FTOS");
colList.add(col1);
Column col2=new Column();
col2.setAttribute("StartDate");
colList.add(col2);
Column col3=new Column();
col3.setAttribute("EndDate");
colList.add(col3);

How to load json data in java?

I'm quite new to API testing, I am wondering how to best and simple load some body?
I created simple pojo classes, but i am having problems with nested json.
ex:
{
"listOfItems": [
{
"name": "name1",
"value": "Jack"
},
{
"name": "nameDate",
"value": "20-08-2021-08-00-00"
},
{
"name": "address",
"value": "address here",
}
{
"name": "name2",
"value": "Smith"
}
],
"something": [],
"size": 1
}
Then, in classes I used:
ClassName {
private List<ListOfItems> listOfItems;
private List<something> something;
private int size;
//setters and getters
}
and
Class ListOfItems{
private String name;
private String value;
//getters and setters
}
then in test class I am trying to use it, but have no idea how.
public Class Test {
ClassName className = new ClassName();
ListOfItems list = new ListOfItems();
//how to get list with 3x name and 3x value like in json?
className.setsize(150);
given().when().body(???).post("\endpoint").then()...
}
But I have no idea how to declare those 4 properties (name, value)
You are actually on a pretty good track, you can use Gson library to help you out, Here is the video example for your explanation which I used to learn Gson back when I needed it

How to loop trough nested JSON and get value using Java, SpringBoot

I have a nested JSON that I want to loop through and get value based on key.
Data.json
{
"car": [
{
"date": 1324599600000,
"values": [
{
"name": "Audi",
"price": "11212.12"
},
{
"name": "Bmw",
"price": "22321.3"
},
{
"name": "Cittroen",
"price": "23432.2"
},
{
"name": "Tuareg",
"price": "556456.3"
}
]
}
I created 3 object models based on JSON data.
CarResponse.java
public class CarResponse {
#JsonProperty(value = "car")
List<Car> cars;
//getters,setters
Car.java
public class Car{
#JsonProperty("values")
private List<CarValue> carValue;
//getters, setters
CarValue.java
public class CarValue {
private String name;
private BigDecimal price;
//getters, setters
DataParse.java
public class DataParse{
CarResponse response;
public CarValue parse(){
CarValue carValue = new CarValue();
//NEED HELP WITH THIS PART
for(Car cars : response.getQuote()){
for(CarValue qv : cars.getCarValue()){
String type = qv.get("name").asText();
Decimal value = qv.get("price").decimalValue();
carValue.setName(qv.getName());
carValue.setPrice(qv.getPrice());
}
}
return quoteValue;
}
}
In JSON I need to check if car name is Audi and if car name is Tuareg then save it and display it.
Nested for loop part of code is not working
for(Car cars : response.getQuote()){
for(CarValue qv : cars.getCarValue()){
String type = qv.get("name").asText();
Decimal value = qv.get("price").decimalValue();
carValue.setName(qv.getName());
carValue.setPrice(qv.getPrice());
}
}
Just put it as an example of what I need to do in this step which is check for key in JSON and if it is that key with for example name = Audi then
carValue.setName(qv.getName());
With my code above I am getting this in the console.
carValue=[carValue{name=null, price=null}
Assuming that your deserialization is working correctly, you should change the part that "is not working" to:
String type = qv.getName();
BigDecimal value = qv.getPrice();
If for some reason you want to use this qv.get(key) method, you should post its implementation.
When getName and getPrice are still returning null, it means you have a problem with the deserialization, for example a wrong setter method name. Still, without the implementation is impossible to understand.
Here is the official documentation of Jackson, the library used by default with spring-boot for JSON serialization / deserialization.
And here is Spring blog post about it.

Json Deserialize for hetero-type json Java

Apologies in advance, I'm a little new to JSON parsing and I m facing a problem in parsing JSON in Object in java.
{ result: {
"City": {
"Delhi": {
"A-Hospital": {
"pincode": 400001
},
"B-Hospital": {
"pincode": 400002
},
"C-Hospital": {
"pincode": 400003
},
.
.
.
},
"Mumbai": {
"A-Hospital": {
"pincode": 500001
},
"B-Hospital": {
"pincode": 500002
},
"C-Hospital": {
"pincode": 500003
},
.
.
.
},
"Bangalore": {
"A-Hospital": {
"pincode": 600001
},
"B-Hospital": {
"pincode": 600002
},
"C-Hospital": {
"pincode": 600003
},
"D-Hospital": {
"pincode": 600004
},
.
.
.
}
}
}
}
Receiving Json is received from 3rd person hence can't the format.
How to create the class structure for such dynamic json and parse into Object ?
class City{
private Map<String, Map<String,Hospital>> hours;
//Getter and Setter
}
class Hospital {
private String pincode;
//Getter and Setter
}
I want to form a Map of the City with Hospital(A-Hospital,B-Hospital,etc) as Object. Example: Map<String,Hospital> cityHospitalMapping. class Hospital { String HospitalName; Integer pincode; }
But How to write the Deserializer ?
Tried
JsonObject allcities = (JsonObject) json.get("result");
City cities = new Gson().fromJson(allcities,City.class);
But cities is not containing any data.
Result:
cities{pincode=null}
Edited because you added the result in your JSON. Your problem here - after edit - is that City you declared does not contain but it itself IS a Map<String, Map<String,Hospital>>.
First of all you need a "wrapper" class, say Data. That is because your JSON example has an object that contains Response that contains City.
For City, there are no fixed field names so you need to deserialize it as a Map.
The same applies to values held in the map City. Values in City are also type of Map let us call these values inner map. Because there is this one fixed field name pincode you can declare before mentioned values in this inner map as of type Hospital, leading to a class like:
#Getter #Setter
public class Data {
#Getter #Setter
public class Result {
private Map<String, Map<String, Hospital>> City;
#Getter #Setter
public class Hospital {
private String pincode;
}
}
private Result result;
}
Now if you deserialize with Gson using this above class you can use it like:
Data data = gson.fromJson(JSON, Data.class);
Map<String, Map<String, Hospital>> city = data.getResult().getCity();
and obtain 400002.
You could implement some more or less complex custom deserializer but maybe it is more easy to deserialize JSON as it is and after tath do some mappings to other types of classes if needed.

How to Parse Nested / Multiple Json Objects using Retrofit

The JSON I'm parsing looks like this:
{ "version": 1
"data": {
"1001": {
"id": 1001,
"name": "herp",
"into": [
"3111": "we"
]
},
"1032": {
"id": 1002,
"name": "derp",
"into": [
"36": "w",
"12341: "c"
],
"tags": [
"hi there"
],
"cost" {
"even": 15
}
},
"1603": {
"id": 1003,
"name": "her",
"into": [
"37": "dll",
"58": "eow",
"32145": "3a"
],
"cost" {
"highest": 325
"lowest": 100
}
},
.... Even more data
}
The Json that is within "data" goes on for a while and does not have a set endpoint. I have no control over the Json, I'm just trying to read it. Unfortunately, with my class code I'm unable to get it to work. When I make a retrofit call the information inside "data" is empty.
I've tried many iterations of implementing this, including using a deserializer and restructuring my POJO code. This is the current state of my Data class:
public class Data {
private Map<String, Item> itemData;
// Relevant Getters, Setters and Constructors //
}
For my Item Class, the main issue is that the JSON Content isn't set, it can vary at times. As you can see above the values inside "into" vary and sometimes the amount of things within item changes as well such as "tags" or "cost":
public class Item {
private int id;
private String name;
private String group;
private String description;
private Map<String, String> into;
private List<String> tags;
private Map<String, Integer> cost;
// Relevant Getters, Setters and Constructors //
When I use this code my data class is empty, I don't see any errors in the log so I can't seem to figure out why the GSON isn't working with this.
In case you wanted to see how I construct my RestClient, here it is:
RestAdapter.Builder builder = new RestAdapter.Builder()
.setEndpoint(ROOT)
.setClient(new OkClient(new OkHttpClient()))
.setLogLevel(RestAdapter.LogLevel.FULL);
RestAdapter restAdapter = builder.build();
REST_CLIENT = restAdapter.create(DataApi.class);
I know that my Rest Query works because I can get the content within "version" but everything inside data is null.
I am officially a dumb scrub and completely looked over the easiest possible fix and should have my account and developer title revoked.
This is all I should have done:
public class ItemGroup {
private String version;
private Map<String,Item> data;
//...Man i'm so dumb...
}
AS REFERENCE FOR THE FUTURE. The reason why this works is because the JSON is in this format { { } { } { } }. Which means you have 3 objects of objects, as opposed to { [ ] [ ] [ ] } which is 3 objects of a list. What I had done was treat { { } { } { } } as { { { } { } { } } }. Which is not correct. By using a map which is basically a collection of pairs, we are able to imitate the { { } { } { } } with a Map.
Map Object { {Key-Pair Object} {Key-Pair Object} {Key-Pair Object} }
Just a quick idea for your Pojos:
Not sure if this will work. Maybe write a custom deserializer.
public class YourResponse {
int version;
Data data;
class Data {
Subdata subData;
}
class Subdata {
private int id;
private String name;
private ArrayList<Into> into;
private ArrayList<String> tags;
//...
}
class Into {
// "3111": "we"
private String into;
}
}

Categories

Resources