I have to create POJO class of following JSON, Problem is that key p_d has variables with dynamic name like s_t, n_t, n_p and etc. the real JSON is big and i am facing problem with that part only, i shared partial JSON.
i am using jackson for parsing.
{
"flag": true,
"flag2": false,
"r_no": [
{
"room_type": 250067,
"no_of_rooms": 1,
"no_of_children": 1,
"no_of_adults": 2,
"description": "Executive Room, 1 King Bed, Non Smoking",
"children_ages": [
8
]
},
{
"room_type": 250067,
"no_of_rooms": 1,
"no_of_children": 0,
"no_of_adults": 2,
"description": "Executive Room, 1 King Bed, Non Smoking"
}
],
"r_code": "abc",
"r_key": "123",
"p_d": {
"s_t": [
{
"name": "xyz",
"cur": "INR"
},
{
"name": "xyz1",
"cur": "INR"
}
],
"n_t": [
{
"name": "xyz2",
"cur": "INR"
}
],
"n_p": [
{
"name": "xyz5",
"cur": "INR"
}
]
},
"cur": "INR"
}
For dynamic keys, use a Map<String, Object>:
ObjectMapper mapper = new ObjectMapper();
Map<String, Object> parsed = mapper.readValue(json,
new TypeReference<Map<String, Object>>() {});
Related
I have the below Json that I'm reading into nested POJOs with the same structure.
{
"employees": [
{
"name": "John",
"age": "30",
"proData": [
{
"year": "1",
"idList": [
"234342",
"532542",
"325424",
"234234"
]
},
{
"year": "2",
"idList": [
"234342",
"532542",
"325424",
"234234"
]
},
{
"year": "3",
"idList": [
"234342",
"532542",
"325424",
"234234"
]
}
]
},
{
"name": "Scott",
"age": "32",
"proData": [
{
"year": "1",
"idList": [
"234342",
"532542",
"325424",
"234234"
]
},
{
"year": "2",
"idList": [
"234342",
"532542",
"325424",
"234234"
]
},
{
"year": "3",
"idList": [
"234342",
"532542",
"325424",
"234234"
]
}
]
}
]
}
Now I wanted to map this to a structure like below, the ProData can be initialized using each of the string in the idList.
Map<String,Map<String,List<ProData>>> finalMap
I have written something like the below and it works.
Map<String,Map<String,List<ProData>>> finalMap = new HashMap<>();
for(Employee employee:root.getEmployees()){
Map<String,List<ProData>> proDataMap = new HashMap<>();
for(ProData proData: employee.getProData()){
List<ProData> finalObjs = new ArrayList<>();
for(String id:proData.getIdList()){
finalObjs.add(new ProData(id));
}
proDataMap.put(proData.getYear(),finalObjs);
}
finalMap.put(employee.getName(),proDataMap);
}
I wanted to make a better version using the stream API.
The end result is a map, so use the toMap collector. The maps' keys are the employee names (assuming no duplicates), and the map values require a little bit more work.
root.getEmployees().stream().collect(
Collectors.toMap(
Employee::getName,
Employee::getProDataMap
)
}
Now let's try writing getProDataMap in Employee. Again we use the toMap collector. The keys are the years (assuming no duplicates), and the values are the id lists mapped to ProData using the constructor.
public Map<String, List<ProData>> getProDataMap() {
return this.getProData().stream().collect(
Collectors.toMap(
ProData::getYear,
proData -> proData.getIdList().stream()
.map(ProData::new)
.collect(Collectors.toList())
)
)
}
should be something similar to,
root.stream().forEach(employee -> {
Map<String,List<ProData>> proDataMap = new HashMap<>();
employee.getProdData().stream().forEach(data -> {
List<ProData> finalObjs = new ArrayList<>();
data.getIdList().stream().forEach(data -> {
finalObjs.add(new ProData(id));
});
});
});
but regardless you can also use Gson to parse it
https://mkyong.com/java/how-to-parse-json-with-gson/
I would like to modify the data inside nested json (Map<String, Object>) by using java.util.stream.
This is Json Data
{
"schoolId": "10928391",
"schoolName": "school A",
"teachers" : [
{
"teacherId": "00001",
"teacherName:": "teacher A",
"subject": "Computer Science",
"lectures": [
{
"id": "CS102",
"name": "Algorithm"
},
{
"id": "CS330",
"name": "Data Communications and Networking"
}
]
},
{
"teacherId": "00002",
"teacherName:": "teacher B",
"subject": "Computer Science",
"lectures": [
{
"id": "CS103",
"name": "Data Structure"
},
{
"id": "CS104",
"name": "Data Structures in C++"
}
]
},
{
"teacherId": "00003",
"teacherName:": "teacher C",
"subject": "Computer Science",
"lectures": [
{
"id": "CS100",
"name": "Introduction to Programming (Java)"
},
{
"id": "CS401",
"name": "Object Oriented Programming"
}
]
}
]
}
--
ObjectMapper mapper = new ObjectMapper();
Map<String, Object> schoolInfo = mapper.converValue(restTemplate.exchange(url, HttpMethod.GET, .... ).getBody(), HashMap.class);
the Json data above is inside schoolInfo
the data what I want to access and modify is lectures.
I tried to modify all the elements inside lectures(array).
for example,
"lectures": [
{
"id": "CS102",
"name": "Algorithm"
},
{
"id": "CS330",
"name": "Data Communications and Networking"
}
]
Replace all lecture information in the lecture data as follows.
"lectures": [
{
"lectureId": "CS102",
"lectureName": "Algorithm",
"lectureRoom": "Room A-1"
},
{
"lectureId": "CS330",
"lectureName": "Data Communications and Networking",
"lectureRoom": "Room A-2"
}
]
with map, filter I could access to "teachers" object
but I couldn't figure out how to get "lectures" objects inside the "teachers"
System.out.println(jsonMap.entrySet().stream()
.filter(map -> map.getKey().equals("teachers")).collect(Collectors.toList()).toString());
Any advice would be very helpful !
I am trying to call an API using Retrofit in android. For this API I need the input parameter JSON object in proper sequence.
Only if I have the json in required sequence I get successful response from the API, otherwise it gives an error. To handle this issue I got one solution that is to first create a LinkedHashMap of input parameter then create the JSON of that LinkedHashMap. This way I'm acheaving the response from api.
but right now im confused how to create linkedHash map for below json
{
"RequestXml": {
"Authenticate": {
"InterfaceCode": "1",
"InterfaceAuthKey": "AirticketOnlineWebSite",
"AgentCode": "MOS0000001",
"Password": "KGBW5P"
},
"BookTicketRequest": {
"TrackNo": "0$182967|4|1AO",
"MobileNo": "9099776464",
"AltMobileNo": "9898989898",
"Email": "abc#gmail.com",
"Address": "Test",
"ClientRequestID": "",
"Passengers": {
"Passenger": [
{
"PaxSeqNo": "1",
"Title": "Mr",
"FirstName": "Savan",
"LastName": "Test",
"PassengerType": "A",
"DateOfBirth": "01/12/1992",
"PassportNo": "RTTTTGGBGB56356",
"PassportExpDate": "01/12/2024",
"PassportIssuingCountry": "IND",
"NationalityCountry": "IND"
}
]
},
"Segments": {
"Segment": [
{
"TrackNo":"0$182967|4|1AO",
"SegmentSeqNo": "1",
"AirlineCode": "UK",
"FlightNo": "888",
"FromAirportCode": "BOM",
"ToAirportCode": "DEL",
"DepDate": "30/09/2019",
"DepTime": "14:00",
"ArrDate": "30/09/2019",
"ArrTime": "16:00",
"FlightClass": "E",
"MainClass": "Y"
}
]
},
"AdditionalServices": {
},
"TotalAmount": "4735",
"MerchantCode": "PAY9zJhspxq7m",
"MerchantKey": "eSpbcYMkPoZYFPcE8FnZ",
"SaltKey": "WHJIIcNjVXaZj03TnDme",
"IsTicketing": "Yes"
}
}
}
[
{
"sentence": "I want to buy shoes .",
"tree": {
"ROOT": [
{
"index": 2,
"token": "want",
"label": "VERB",
"pos": "VBP",
"tree": {
"nsubj": [
{
"index": 1,
"token": "I",
"label": "PRON",
"pos": "PRP"
}
],
"xcomp": [
{
"index": 4,
"token": "buy",
"label": "VERB",
"pos": "VB",
"tree": {
"aux": [
{
"index": 3,
"token": "to",
"label": "PRT",
"pos": "TO"
}
],
"dobj": [
{
"index": 5,
"token": "shoes",
"label": "NOUN",
"pos": "NNS"
}
]
}
}
],
"punct": [
{
"index": 6,
"token": ".",
"label": ".",
"pos": "."
}
]
}
}
]
}
}
]
This is tree represented in Json. But the keys for nested nodes keep changing.
For example "ROOT, nsubj, xcomp" ... etc.
How do I convert above json code to Java Object using gson.
Above response is from syntaxnet Parsey_Mcparseface api I'm trying to use.
Thanks in advance.
Gson has a method Gson#fromJson. For example, this is a code to read a simple String object.
Gson gson = new Gson();
String str = gson.fromJson("\"hello\"", String.class);
System.out.println("String: " + str);
You need to prepare Java Object to read your proposed JSON. But, you don't need to write code by yourself. There is a website providing automatical JSON object generator.
jsonschema2pojo
enter following items:
Target language: Java
Source type: JSON
Annotation type: Gson
and enter your class name, for example "ParsedSentence"
then, write code. You will get object.
Gson gson = new Gson();
ParsedSentence parsed = gson.fromJson(longLongJsonString, ParsedSentence.class);
I have a schema like this (simplified):
{
"range": {
"offset": 0,
"limit": 1,
"total": 2
},
"items": [
{
"id": 11,
"name": "foo",
"children": [
{
"id": 112,
"name": "bar",
"children": [
{
"id": 113,
"name": "foobar",
"type": "file"
}
],
"type": "folder"
},
{
"id": 212,
"name": "foofoo",
"type": "file"
}
],
"type": "room"
},
{
"id": 21,
"name": "barbar",
"type": "room"
}
]
}
I need to read only specific values like "id" from the first room (item). For this I need to iterate trough all items on every level (n items for root, n items for n children) with type folder or file.
For now i have this code:
POJO
public static class Item {
public int id;
}
Jackson Tree Iteration
ObjectMapper mapper = new ObjectMapper();
com.fasterxml.jackson.databind.JsonNode root = mapper.readTree(JSON);
root = root.get("items").get(0);
TypeReference<List<Item>> typeRef = new TypeReference<List<Item>>(){};
List<Item> list = mapper.readValue(root.traverse(), typeRef);
for (Item f : list) {
System.out.println(f.id);
}
How can i get all id's of all children in all items with specific type?
How to avoid the "Unrecognized field" exception without defining the whole schema?
Thank you very much for your help!
Try using java8 functions it has lot to do it in lesser lines ,
ObjectMapper mapper = new ObjectMapper();
Pass your json value
Map obj = mapper.readValue(s, Map.class);
List<Object> items= (List<Object>) obj.get("items");
Object[] Ids= items
.stream()
.filter(items-> ((Map)items).get("type").equals("room"))
.toArray()
Use the readTree(...) method to parse the JSON without needing to define the entire schema and find Nodes called "id".
You can then use findValues("id") to get the List of values back.