i have trouble in parsing json
I have a nested json string, i need to convert to java object , the string look like this, i want to ask how to handle this nested dynamic json using jackson, how to decode dynamic nested json string
{
"resultCode": "0",
"dataObject": [
{
"lastSyncDate": "20140101000000",
"count": 2,
"refType": "ADO",
"update": [
{
"artist": "C",
"albumTitle": "道",
"productTitle": "道",
"thumbnail": "http://w.com/mposter/album/m/VACL00020880A_m.jpg",
"lastSyncDate": "20140425120159",
"refId": "VACL00214522"
},
{
"artist": "楊",
"albumTitle": "學",
"productTitle": "美",
"thumbnail": "http://m.jpg",
"lastSyncDate": "20140324161831",
"refId": "VACP00168673"
}
],
"delete": [ ]
},
{
"lastSyncDate": "20140101000000",
"count": 8,
"refType": "PAT",
"update": [
{
"artist": "方",
"thumbnail": "http://t.com/moov/images/profile/PAT/8/70/00021870_tn_1_s.jpg",
"lastSyncDate": "20140201010203",
"refId": "00021870"
},
{
"artist": "楊",
"lastSyncDate": "20140328120831",
"refId": "00000125"
},
{
"artist": "陳",
"thumbnail": "http://s.jpg",
"lastSyncDate": "20140328185030",
"refId": "00017704"
}
],
"delete": [ ]
},
{
"lastSyncDate": "20140101000000",
"count": 4,
"refType": "PAB",
"update": [
{
"artist": "陳",
"albumTitle": "The Key",
"thumbnail": "http:/m.jpg",
"lastSyncDate": "20140603143528",
"refId": "VAUN00031629A"
},
{
"artist": "何",
"albumTitle": "梁",
"thumbnail": "http://m.jpg",
"lastSyncDate": "20140603143528",
"refId": "VAEA00003170A"
},
{
"artist": "何",
"albumTitle": "艷",
"thumbnail": "http://m.jpg",
"lastSyncDate": "20110603151452",
"refId": "VAEA00003179A"
}
],
"delete": [ ]
},
{
"lastSyncDate": "20140101000000",
"count": 4,
"refType": "PP",
"update": [
{
"chiName": "其",
"engName": "Other",
"lastSyncDate": "20140130010203",
"chiAuthor": "",
"engAuthor": "",
"refId": "PP1000000003"
},
{
"chiName": "演",
"engName": "E演",
"thumbnail": "http://s.jpg",
"lastSyncDate": "20140126010758",
"chiAuthor": "專",
"engAuthor": "Recommended",
"refId": "PP1000000040"
},
{
"chiName": "日本派台歌",
"engName": "Japan New Releases",
"lastSyncDate": "20140126010758",
"chiAuthor": "",
"engAuthor": "",
"refId": "PP1000000057"
},
{
"chiName": "9",
"engName": "9",
"thumbnail": "http://s.jpg",
"lastSyncDate": "20140126010203",
"chiAuthor": "專",
"engAuthor": "Recommended",
"refId": "PP1000000048"
}
],
"delete": [ ]
}
]
}
You only need to reproduce the structure of the json using java class structure. For instance, for your case:
public class Result {
String resultCode;
List<DataObject> dataObjects;
<GETTERS & SETTERS>
}
public class DataObject {
String lastSyncDate;
int count;
String refType;
List<Update> updates;
List<Delete> deletes;
<GETTERS & SETTERS>
}
public class Update {
String artist;
String albumTitle;
String productTitle;
String thumbnail;
String lastSyncDate;
String refId;
<GETTERS & SETTERS>
}
public class Delete {
String refId;
<GETTERS & SETTERS>
}
I assumed that Delete class only contains the refId. With this structure, you'll be able to map the json to an object of the class Result without any problems doing:
byte[] jsonData = <YOUR JSON>
ObjectMapper objectMapper = new ObjectMapper();
Result result = objectMapper.readValue(jsonData, Result.class);
Since the field of Update is not fixed, use map instead of the Update class.
public class Result {
String resultCode;
List<DataObject> dataObject;
<GETTERS & SETTERS>
}
public class DataObject {
String lastSyncDate;
int count;
String refType;
List<Map<String, String>> update;
List<String> delete;
<GETTERS & SETTERS>
}
Assume that update only contains String values.
String jsonData = "YOUR JSON";
ObjectMapper objectMapper = new ObjectMapper();
Result result = objectMapper.readValue(jsonData, Result.class);
Related
Hi I have this response from google places api
"address_components": [
{
"long_name": "123",
"short_name": "123",
"types": ["street_number"]
},
{
"long_name": "Mulgoa Road",
"short_name": "Mulgoa Rd",
"types": ["route"]
},
{
"long_name": "Penrith",
"short_name": "Penrith",
"types": ["locality", "political"]
},
{
"long_name": "City of Penrith",
"short_name": "City of Penrith",
"types": ["administrative_area_level_2", "political"]
},
{
"long_name": "New South Wales",
"short_name": "NSW",
"types": ["administrative_area_level_1", "political"]
},
{
"long_name": "Australia",
"short_name": "AU",
"types": ["country", "political"]
},
{
"long_name": "2750",
"short_name": "2750",
"types": ["postal_code"]
}
],
Expected response
{
"postcode": "4215",
"unit_number": null,
"floor_number": null,
"building_name": null,
"building_number": null,
"block_number": null,
"street_number": "123",
"street_name": "Nerang",
"street_type": "Street",
"state": "Queensland",
"suburb": "Southport",
"city": null,
"district": null,
"fullAddress": "123 Nerang St, Southport QLD 4215, Australia"
}
On the basis of types array I want to populate values into response format.
This is what how I trying to implement it right now.
JsonNode resultData = new ObjectMapper().readTree(String.valueOf(response.getResponseBody()));
if (Objects.equals(resultData.get("status").asText(), "OK")) {
JsonNode addressComponentsArray = resultData.get("result").get("address_components");
LocationAddressComponent responseObject = new LocationAddressComponent();
if (addressComponentsArray.isArray()) {
for (JsonNode jsonNode : addressComponentsArray) {
Array res = jsonNode.get("types");
}
}
Can you please suggest how it can be done using stream or Jackson.
LocationComponentAddress.java
public class LocationAddressComponent {
String postcode;
String unit_number;
String floor_number;
String building_name;
String building_number;
String block_number;
String street_number;
String street_name;
String street_type;
String state;
String suburb;
String city;
String district;
String fullAddress;
}
This implementation only maps a few of the properties in the Google Places API response to the LocationAddressComponent object. You may need to add more mapping logic depending on your requirements.
if (addressComponentsArray.isArray()) {
for (JsonNode jsonNode : addressComponentsArray) {
ArrayNode types = (ArrayNode) jsonNode.get("types");
if (types.contains("street_number")) {
responseObject.setStreet_number(jsonNode.get("long_name").asText());
} else if (types.contains("route")) {
responseObject.setStreet_name(jsonNode.get("long_name").asText());
} else if (types.contains("locality")) {
responseObject.setSuburb(jsonNode.get("long_name").asText());
} else if (types.contains("administrative_area_level_1")) {
responseObject.setState(jsonNode.get("long_name").asText());
} else if (types.contains("postal_code")) {
responseObject.setPostcode(jsonNode.get("long_name").asText());
}
}
}
I'm having an issue comparing two json because some times the json that I recive from DB is oldEncodedString has values unordered
private static boolean encodeProduct(BaseProduct baseProduct) {
boolean saveProduct = false;
try {
saveProduct = true;
String oldEncodedString = baseProduct.getEncodedJson();
ObjectMapper objectMapper = new ObjectMapper();
objectMapper.configure(SerializationConfig.Feature.SORT_PROPERTIES_ALPHABETICALLY, true);
objectMapper.configure(SerializationConfig.Feature.FAIL_ON_EMPTY_BEANS, false);
String json = objectMapper.writeValueAsString(baseProduct);
Objects.requireNonNull(baseProduct).setEncodedJson(json);
if (Objects.nonNull(oldEncodedString) && JSONCompare.compareJSON(oldEncodedString, baseProduct.getEncodedJson(), JSONCompareMode.STRICT).passed()) {
saveProduct = false;
}
} catch (Exception exception) {
LOG.error("Error generating encode", exception);
}
return saveProduct;
}
eg:
oldEncodedString = {
"id": "0001",
"type": "donut",
"name": "Cake",
"ppu": 0.55,
"batters":
{
"batter":
[
{ "id": "1003", "type": "Blueberry" },
{ "id": "1001", "type": "Regular" },
{ "id": "1002", "type": "Chocolate" },
{ "id": "1004", "type": "Devil's Food" }
]
}}
baseProduct.getEncodedJson =
{
"id": "0001",
"type": "donut",
"name": "Cake",
"ppu": 0.55,
"batters":
{
"batter":
[
{ "id": "1001", "type": "Regular" },
{ "id": "1002", "type": "Chocolate" },
{ "id": "1003", "type": "Blueberry" },
{ "id": "1004", "type": "Devil's Food" }
]
}}
So the values are unordered and when I compare into that if with STRICT is said that is not the same , but because is not ordered the values I tryed adding ObjectMapper.configure(SerializationFeature.ORDER_MAP_ENTRIES_BY_KEYS, true)
but is not on this library
Now i take JsonObject from API like this:
Its XML object converted to JsonObject.
"Details": {
"row": [
{
"item": [
{
"name": "Account",
"value": 12521512
},
{
"name": "ACCNO",
"value": 4214
},
{
"name": "Number",
"value": 5436
}
]
},
"item": [
{
"name": "Account",
"value": 5789678
},
{
"name": "ACCNO",
"value": 6654
},
{
"name": "Number",
"value": 0675
}
]
},
But i need convert this object and send like this:
{
"Details": {
"row": [
{
"Account": 12521512,
"ACCNO": 4214,
"Number": 12412421
},
{
"Account": 5789678,
"ACCNO": 6654,
"Number": "0675"
}
]
}
}
I have rows more than 1000, i need faster way to handle.
How to handle, please help me
You could use the JSON-java library to parse your input and transform it to your desired format. Something like this works but you may need to adjust it to your needs:
JSONObject jsonObject = new JSONObject(json); // Load your json here
JSONObject result = new JSONObject("{\"Details\": {\"row\": []}}");
for (Object row : jsonObject.getJSONObject("Details").getJSONArray("row")) {
if (!(row instanceof JSONObject)) continue;
Map<Object, Object> values = new HashMap<>();
for (Object item : ((JSONObject) row).getJSONArray("item")) {
if (!(item instanceof JSONObject)) continue;
values.put(((JSONObject) item).get("name"), ((JSONObject) item).get("value"));
}
result.getJSONObject("Details").getJSONArray("row").put(values);
}
// Now result is in your format
What is the cheapest way to take the jsonstring and hashmap below and produce the result in JAVA?
pseudocode data example:
String jsonstring = {
"people": {
"name": "name1",
},
"addresses": {
"address1": {
"number": "1234",
"city": "europa"
}
}
}
HashMap hashmap = {
["string.a.1"] = "stringa1",
["string.a.2"] = "stringa2",
["object.a.1"] = "{/"item1/":/"value1/"}" // serialized JSON object
}
String result = {
"people": {
"name": "name1",
},
"addresses": {
"address1": {
"number": "1234",
"city": "europa"
}
},
"buffer": {
"string.a.1": "stringa1",
"string.a.2": "stringa2",
"object.a.1": {
"item1": "value1"
}
}
}
Thanks in advance for any help.
I am very new to json, How can I make a JSON object the structure (output string)would be like this? I am using the org.json library.
Is this a json array contians json array?
I have input like this:
111(root)
----222(child of 111)
--------333(child of 222)
--------444(child of 222)
----123(child of 111)
--------456(child of 123)
--------456(child of 123)
How can I make a json the output would be like blow,
{
"name": "flare",
"children": [
{
"name": "analytics",
"children": [
{
"name": "cluster",
"children": [
{
"name": "AgglomerativeCluster",
"value": 3938
},
{
"name": "CommunityStructure",
"value": 3812
}
]
},
{
"name": "graph",
"children": [
{
"name": "BetweennessCentrality",
"value": 3534
},
{
"name": "LinkDistance",
"value": 5731
}
]
}
]
},
{
"name": "animate",
"children": [
{
"name": "Easing",
"value": 17010
},
{
"name": "FunctionSequence",
"value": 5842
}
]
}
]
}
Thanks for you help!
You can change your dependency and use a library that allows Object mapping such as Jackson, or you can do the mapping by hand as follows:
private static JSONObject toJSONObject(String name, Object value) {
JSONObject ret = new JSONObject();
ret.put("name", name);
if (value != null) {
ret.put("value", value);
}
return ret;
}
public static JSONObject addChildren(JSONObject parent, JSONObject... children) {
parent.put("children", Arrays.asList(children));
return parent;
}
public static void main(String[] sargs) {
JSONObject flare = toJSONObject("flare", null);
addChildren(flare,
addChildren(toJSONObject("analytics", null),
addChildren(toJSONObject("cluster", null),
toJSONObject("AgglomerativeCluster", 3938),
toJSONObject("CommunityStructure", 3812)
),
addChildren(toJSONObject("graph", null),
toJSONObject("BetweennessCentrality", 3534),
toJSONObject("LinkDistance", 5731)
)
),
addChildren(toJSONObject("animate", null),
toJSONObject("Easing", 17010),
toJSONObject("FunctionSequence", 5842)
)
);
System.out.println(flare.toString());
}
You can simply have class like this.
public class Node {
String name;
List<Node> children;
String value;
}
This can be achieved by ObjectMapper's pretty print.
public String pretty(Object object) throws JsonProcessingException {
return OBJECT_MAPPER.writerWithDefaultPrettyPrinter().writeValueAsString(object);
}
You may use my library for it.
<dependency>
<artifactId>json-utils</artifactId>
<groupId>org.bitbucket.swattu</groupId>
<version>1.0.16</version>
</dependency>
new JsonUtil().pretty(object);