How to send nested JSON input to Restful web service (using Java)? - java

How to send nested JSON input to Restful web service (using Java)?
eg. JSON input
{
"item1": [
{
"name": "name1",
"value": "value1",
"subitems": [
{
"sname": "sname1",
"svalue": "svalue1"
},
{
"sname": "sname2",
"svalue": "svalue2"
}
],
"attributes": [
{
"length": 25,
"height": 25,
"width": 30
},
{
"length": 35,
"height": 35,
"width": 40
}
]
}
]
}

You can create a class to map you json like this :
public class item {
private String name;
private String value;
private List<SubItem> subitems;
private List<Attribute> attributes;
// add here getters, setters and constructor
}
public class SubItem{
private String name;
private String svalue;
//add here getters, setters and constructor
}
public class Attribute{
private Integer length;
private Integer height;
private Integer width;
//add here getters, setters and constructor
}

Related

Best Way to do Object Mapping with Nested Json

Currently I'm trying to write a site that interacts with a public API using Feign and Spring.
I'm having trouble deciding how to handle the object mapping for deeply nested JSON.
Ex:
[
{
"type": "console",
"category": "Console",
"result_count": 1,
"shown_count": 1,
"result": [
{
"name": "Nintendo Switch",
"id": "nintendo-switch",
"platform": {
"name": "Nintendo",
"category": "nintendo",
"type": "platform"
},
"image": {
"url": "https://encrypted-tbn1.gstatic.com/shopping?q=tbn:ANd9GcRqJYIheMDjTE9WAHjMSW4bjh7OplS7Bep9CdsBBLWMwGdXim7xOG4&usqp=CAc",
"height": 409,
"width": 631
},
"min_price": 205,
"variations": [
{
"items": [
{
"hex_code": "#696969",
"name": "Gray",
"id": "space-gray",
"type": "color"
},
{
"hex_code": "#C0C0C0",
"name": "Silver",
"id": "silver",
"type": "color"
}
],
"name": "Color",
"type": "color"
},
{
"items": [
{
"name": "Nintendo",
"id": "nintendo",
"type": "platform"
}
],
"name": "Platform",
"type": "platform"
}
]
}
]
}
]
As of now, I have a single Java file with a class for each object in the JSON, and I've considered having the Object mapper just put everything into a HashMap. Is there a more elegant way to do this?
public class SearchResults {
private List<SearchResult> products;
private int resultCount;
private String type;
}
class SearchResult {
private String name;
private String slug;
private Image image;
}
class Image {
private String URL;
private String height;
private String width;
}
Based on the json file provided i have designed the classes and also provided the code to parse the json file to java
public class Console{
String type;
String category;
int result_count;
int show_count;
Result [] result;
}
public class Result{
String name;
String id;
Platform platform;
Image image;
int mini_price;
Variation [] variations;
}
public class Platform{
String name;
String category;
String type;
}
public class Image{
String url;
int height;
int width;
}
public class Variation{
String name;
String type;
Item [] items;
}
public class Item{
String hex_code;
String name;
String id;
String type;
}
code to parse:
ObjectMapper objectMapper = new ObjectMapper();
objectMapper.enable(SerializationFeature.INDENT_OUTPUT);
Console[] consoles = objectMapper.readValue(ResourceUtils.getFile("path of json file"), Console[].class);
logger.info("Continents -> {}",(Object)continents);
for(Console console:consoles) {
//read the data accordingly
}

How map List to an Object with list in mapstructs

How can I use MapStruct to create a mapper that maps a list (my source) to a object with a list (destination)?
My source classes looks like this:
class SourceB {
private String name;
private String lastname;
}
class SourceA {
private Integer id;
private List<SourceB> bs;
}
so I need to transform it to this:
class DestinationA {
private Integer id;
private DestinationAB bs;
}
class DestinationAB {
private List<DestinationB> b;
}
class DestinationB {
private String name;
private String lastname;
}
Expected sample json:
source:
{
"id": 1,
"bs": [
{
"name": "name1",
"lastname": "last1"
},
{
"name": "name2",
"lastname": "last2"
}
]
}
destination:
{
"id": 1,
"bs": {
"b": [
{
"name": "name1",
"lastname": "last1"
},
{
"name": "name2",
"lastname": "last2"
}
]
}
}
It's quite simple. Just put #Mapping annotation with specified source and destination on top of the mapping method.
#Mapper
public interface SourceMapper {
#Mapping(source = "bs", target = "bs.b")
DestinationA sourceAToDestinationA(SourceA sourceA);
}

Remove Element in Nested List with Condition From another List - Java 8

I want to remove items from a list with a conditional value that comes from another List. Here are the objects
public class Student{
private String name;
private String age;
private List<Course> listCourses;
//Setters and getters
}
public Class Course{
private String courseName;
private List<CourseDetail> listCoursesDetail;
//Setters and getters
}
public Class CourseDetail{
private String id;
private String grade;
private String professor;
//Setters and getters
}
So as you can see the object Student has a list, inside that list there is another list from the object CourseDetail. What I want to achieve is to filter or remove elements from private List<CourseDetail> listCoursesDetail where ID is not equal to id from this other object.
public class Process{
private String name;
private List<ProcessDetail> listProcessDetail;
//Setters and getters
}
public class ProcessDetail{
private String id;
//Setters and getters
}
Assume the object Process is populated as follows
{
"name": "process1",
"listProcessDetail": [
{
"id": "456"
},
{
"id": "666"
},
{
"id": "555"
}
]
}
Student is populated as follows.
{
"name": "Kevin",
"age": "22",
"listCourses": [
{
"courseName": "Math",
"listCoursesDetail": [
{
"id": "666",
"grade": "88",
"professor": "Xavier"
},
{
"id": "144",
"grade": "90",
"professor": "Marcus"
},
{
"id": "555",
"grade": "100",
"professor": "Joe"
}
]
}
]
}
The expected result will be:
{
"name": "Kevin",
"age": "22",
"listCourses": [
{
"courseName": "456",
"listCoursesDetail": [
{
"id": "666",
"grade": "88",
"professor": "Xavier"
},
{
"id": "555",
"grade": "100",
"professor": "Joe"
}
]
}
]
}
The element from listCoursesDetail with ID 144 was removed since there is no such value in the object Process.
So far I have these:
Set<String> ids = Process.getListProcessDetail().stream().map(ProcessDetail::id).collect(Collectors.toSet());
In these I stored all the ID's on a Set.
Then my attempt to remove the items:
List<Course> courses = Student.getListCourses().stream().filter(c -> c.getListCoursesDetail().stream().anyMatch(d -> ids.contains(d.getId()))).collect(Collectors.toList());
With these lines of code I get the same Student object as nothing happened.
Assuming you want to modify the existing objects, not create a clone of them with shorter lists, you'd do it like this:
student.getListCourses().forEach(c ->
c.getListCoursesDetail().removeIf(d -> ! ids.contains(d.getId())));

Deserialize an object with children

I have a Json list using object with children
{
"id":"154",
"name":"peter",
"children": [
{
"id":"122",
"name": "mick",
"children":[]
},
{
"id":"123",
"name": "mick",
"children":[]
}
]
}
Here is the class of my object:
public class person{
private String id;
private String name;
private List<person> children;
//getters and setters
}
When I try to deserialize this object, I have the following error
Can not deserialize instance of person out of START_ARRAY token
What should I do ?
The JSON contains an array of persons.
Your class a List of person.
Either change the JSON like #Naveed Yadav suggested or change the class to
public class Person{
private String id;
private String name;
private Person[] children;
//getters and setters
}
(BTW the class name should be upper case in Java)
Fix syntax errors in your JSON body and you'll be in a good shape:
{
"id":"154",
"name":"peter",
"children": [
{
"id":"122",
"name": "mick",
"children":[], <== Excess comma
} <== Missing comma
{
"id":"123",
"name": "mick",
"children":[], <== Excess comma
}
]
}
Valid one:
{
"id": "154",
"name": "peter",
"children": [{
"id": "122",
"name": "mick",
"children": []
},
{
"id": "123",
"name": "mick",
"children": []
}
]
}
You need to change your POJO declaration like below:-
public class person{
private String id;
private String name;
private List<Children> children;
//getters and setters
private class Children{
private String id;
private String name;
private String[] children;
}
{
"id":"154",
"name":"peter",
"children":
{
"id":"122",
"name": "mick",
"children":[],
}
{
"id":"123",
"name": "mick",
"children":[],
}
}

JSON parser not returning numbers

I have the following JSON structure:
{
"status": "Completed",
"notes": null,
"members": {
"0": {
"year": "2",
"details": {
"id": "14899975",
"anotherId": "11013306"
},
"aName": "Fred",
"amounts": {
"First": 589.48,
"Second": 1000,
"Third": 339.48
}
},
"1": {
"year": "2",
"details": {
"id": "14899976",
"anotherId": "11013306"
},
"aName": "George",
"amounts": {
"First": 222.22,
"Second": 2000,
"Third": 22.22
}
},
"2": {
"year": 1,
"details": {
"id": "14899976",
"anotherId": "11013306"
},
"aName": "Albert",
"amounts": {
"First": 333.33,
"Second": 3000,
"Third": 33.33
},
}
}
}
I am using Spring RESTTemplate and JacksonMapping2HttpMessageConverter, and the following structures to receive the result of parsing the above JSON structure:
#JsonIgnoreProperties(ignoreUnknown = true)
public class Response {
private String status;
private String notes;
private Map<String,Struct1> quotes;
}
#JsonIgnoreProperties(ignoreUnknown = true)
class Struct1 {
private int year;
private Struct2 details;
private String aName;
private Struct3 amounts;
}
#JsonIgnoreProperties(ignoreUnknown = true)
class Struct2 {
private String id;
private String anotherId;
}
#JsonIgnoreProperties(ignoreUnknown = true)
class Struct3 {
private float First;
private float Second;
private float Third;
}
All of these also have appropriate setters and getters for all fields.
My problem is that the number values in Struct3 are not filled in. I've tried making them float, Float, String, and BigDecimal, and the result is either null or 0.0.
I've tried putting a breakpoint in the setter for the first field, hoping
What am I missing? Can the capital letters in the JSON be causing a problem, do I need alternate field names?
It turned out to be the capital letters at the beginning of the field names; I added annotations like #JsonProperty("First") on the line before the getter of the field, and renamed the field to first, and now it's working.

Categories

Resources