How to parse a JSON string using ggson to get field values - java

I have a sample JSON as below. I need to get the individual fields like ASIdentifer and ExternalIdentifer. I have stored this JSON data in a string.
Using GoogleJson as the module(ggson)
JSON data:
{
"DeviceCommon": {
"ASIdentifier": "123",
"DatadeliveyMechanism": "notify",
"MobileOriginatorCallbackReference": {
"url": "http://application.example.com/inbound/notifications/modatanotification/"
},
"AccessiblityCallbackReference": {
"url": "http://application.example.com/inbound/notifications/accessibilitystatusnotification"
}
},
"DeviceList": [{
"ExternalIdentifer": "123456#mydomain.com",
"msisdn": "123456",
"senderName": "Device1",
"MobileOriginatorCallbackReference": {
"notifyURL": "http://application.example.com/inbound/notifications/modatanotification/"
},
"ConfigurationResultCallbackReference": {
"notifyURL": "http://application.example.com/inbound/notifications/configurationResult"
},
"ASreferenceID": "AS000001",
"NIDDduration": "1d"
}]
}
I created the POJO classes and parsed the data using below code
data = new Gson().fromJson(new FileReader("/home/raj/apache-tomcat-8.0.3/webapps/file.json"), Data.class);
System.out.println(data);
Output:
Data{
deviceCommon=DeviceCommon{
asIdentifier='123'
datadeliveyMechanism='notify'
mobileOriginatorCallbackReference=http://application.example.com/inbound/notifications/modatanotification/
accessiblityCallbackReference=http://application.example.com/inbound/notifications/accessibilitystatusnotification
}
deviceList=[DeviceListEntry{
externalIdentifer='123456#mydomain.com'
msisdn='123456'
senderName='Device1'
mobileOriginatorCallbackReference=http://application.example.com/inbound/notifications/modatanotification/
configurationResultCallbackReference=http://application.example.com/inbound/notifications/configurationResult
asReferenceID='AS000001'
nidDduration='1d'
}]
}
String jsonInString = gson.toJson(data);
System.out.println("String is"+ jsonInString);
Output:
String is{"DeviceCommon":{"ASIdentifier":"123","DatadeliveyMechanism":"notify","MobileOriginatorCallbackReference":{"url":"http://application.example.com/inbound/notifications/modatanotification/"},"AccessiblityCallbackReference":{"url":"http://application.example.com/inbound/notifications/accessibilitystatusnotification"}},"DeviceList":[{"ExternalIdentifer":"123456#mydomain.com","msisdn":"123456","senderName":"Device1","MobileOriginatorCallbackReference":{"notifyURL":"http://application.example.com/inbound/notifications/modatanotification/"},"ConfigurationResultCallbackReference":{"notifyURL":"http://application.example.com/inbound/notifications/configurationResult"},"ASreferenceID":"AS000001","NIDDduration":"1d"}]}
I need to parse this JSON string to get individual fields like ExternalIdentifier and ASIdentifier.
I tried something like this but it is not working.
JsonObject jobj = new Gson().fromJson(jsonInString, JsonObject.class);
String result = jobj.get("ASIdentifier").toString();
System.out.println("value is"+ result);
Note: ExternalIdentifier is within the array, so I need to loop through the array to find it.
Can you please tell me what I'm doing wrong?

Possible solution:
String result = jobj.get("DeviceCommon").getAsJsonObject().get("ASIdentifier").getAsString();
System.out.println("ASIdentifier: "+ result);
JsonArray jsonArray = jobj.get("DeviceList").getAsJsonArray();
for (JsonElement device : jsonArray ) {
result = device.getAsJsonObject().get("ExternalIdentifer").getAsString();
System.out.println("ExternalIdentifer: "+ result);
}
Output:
ASIdentifier: 123
ExternalIdentifer: 123456#mydomain.com

public static void printJson(JsonElement jsonElement,String key) {
// Check whether jsonElement is JsonObject or not
if (jsonElement.isJsonObject()) {
Set<Entry<String, JsonElement>> ens = ((JsonObject) jsonElement).entrySet();
if (ens != null) {
// Iterate JSON Elements with Key values
for (Entry<String, JsonElement> en : ens) {
// System.out.println("##key is"+en.getKey() + " : ");
printJson(en.getValue(), en.getKey());
// System.out.println(en.getValue().getAsString());
// System.out.println(jsonElement.getAsString());
}
}
}
// Check whether jsonElement is Primitive or not
else if (jsonElement.isJsonPrimitive()) {
// print value as String
System.out.println("###key is"+key);
System.out.println("### value is"+jsonElement.getAsString());
}
else if (jsonElement.isJsonArray()) {
JsonArray jarr = jsonElement.getAsJsonArray();
// Iterate JSON Array to JSON Elements
System.out.println("\n###Array size is"+ jarr.size());
for (JsonElement je : jarr) {
printJson(je,key);
}
}
}

Related

Adding json array in a json object in java

I am struggling to fit in a jsonArray inside a json object (through java code).. please help me out.
My Input JsonObject is :
{
"products":{
"productId":"712161780324",
"imageURL":"http:example.com/imageResource.jpg",
"internalItemCode":"N08792 8W"
}
}
I will have to read "imageURL" property from this JSONObject and append its variants to the same json object (image variants will be in SortedSet data structure).
Sample O/P 1 :
{
"products":{
"productId":"712161780324",
"imageURL":"http:example.com/imageResource.jpg",
"internalItemCode":"N08792 8W",
"variants":[
"http:example.com/imageResource_variant1.jpg",
"http:example.com/imageResource_variant2.jpg"
]
}
}
Sample O/P 2 :
{
"products":{
"productId":"712161780324",
"imageURL":"http:example.com/imageResource.jpg",
"internalItemCode":"N08792 8W",
"variants":[
{
"url" : "http:example.com/imageResource_variant1.jpg"
},
{
"url" : "http:example.com/imageResource_variant2.jpg"
}
]
}
}
The logic i tried to get sample output 2 is some what like below,
// productDetail is the give input JSONObject
JSONObject product = productDetail.optJSONObject("products");
SortedSet<String> imageUrls = new TreeSet<>();
imageUrls.add("http:example.com/imageResource_variant1.jpg");
imageUrls.add("http:example.com/imageResource_variant2.jpg");
Iterator<String> itr = imageUrls.iterator();
JSONArray imageUrlsArray = new JSONArray();
while (itr.hasNext()) {
JSONObject imageUrlObj = new JSONObject();
imageUrlObj.put("url", itr.next());
imageUrlsArray.put(imageUrlObj);
}
product.append("variants", imageUrlsArray);
When i tried to print the productDetail JSON object after executing above logic
System.out.println(productDetail.toString());
I observed the following output :
{
"products":{
"productId":"712161780324",
"imageURL":"http:example.com/imageResource.jpg",
"internalItemCode":"N08792 8W",
"variants":[
[
{
"url" : "http:example.com/imageResource_variant1.jpg"
},
{
"url" : "http:example.com/imageResource_variant2.jpg"
}
]
]
}
}
If you notice, It's coming up like Array of arrays (extra [ ] for "variants"),
Please help me in understanding Where my logic is going wrong.
And also, Please help me getting the First sample out put.
Appreciate quick response..
Thanks,
Rohit.
First sample can be archivable as simple as this:
JSONObject product = productDetail.optJSONObject("products");
JSONArray imageUrlsArray = new JSONArray();
imageUrlsArray.put(0, "http:example.com/imageResource_variant1.jpg");
imageUrlsArray.put(1, "http:example.com/imageResource_variant2.jpg");
product.append("variants", imageUrlsArray);
Try using put instead of append:
JSONObject product = productDetail.optJSONObject("products");
SortedSet<String> imageUrls = new TreeSet<>();
imageUrls.add("http:example.com/imageResource_variant1.jpg");
imageUrls.add("http:example.com/imageResource_variant2.jpg");
Iterator<String> itr = imageUrls.iterator();
JSONArray imageUrlsArray = new JSONArray();
while (itr.hasNext()) {
JSONObject imageUrlObj = new JSONObject();
imageUrlObj.put("url", itr.next());
imageUrlsArray.put(imageUrlObj);
}
-product.append("variants", imageUrlsArray);
+product.put("variants", imageUrlsArray);
From the docs:
Append values to the array under a key. If the key does not exist in the JSONObject, then the key is put in the JSONObject with its value being a JSONArray containing the value parameter. If the key was already associated with a JSONArray, then the value parameter is appended to it.

Extract json subset with few attributes from the main json

Is there an API/tool available for extracting specific attributes(json subset) of a json in java, similar to apache-commons beanutils copy?
For example I have the following JSON
{
"fixed":[
{
"b":"some value",
"c":"some value",
"d":"some value",
"e":"some value",
"f":"some value"
},
{
"b":"value",
"c":"value",
"d":"value",
"e":"value",
"f":"value"
}
]
}
I would like to have the following json
{
"fixed":[
{
"b":"some value",
"e":"some value",
"f":"some value"
},
{
"b":"value",
"e":"value",
"f":"value"
}
]
}
I came up the following method, but not sure if its the right approach
public JSONObject parseJSON(JSONObject data,List<String> subset){
JSONArray fixedArray = (JSONArray) data.get("fixed");
JSONObject resObj = new JSONObject();
JSONArray resArray = new JSONArray();
for(int i=0;i<fixedArray.size();i++){
JSONObject element = (JSONObject) fixedArray.get(i);
JSONObject resElement = new JSONObject();
for(String s:subset){
resElement.put(s, element.get(s));
}
resArray.add(resElement);
}
return resObj.put("fixed", resArray);
}
I had a look at this SO question, but wasn't helpful for this topic.
https://docs.oracle.com/javase/tutorial/jaxb/intro/arch.html you can also create you own pojo class from JAXB ,if you want.

How do I get a list of all JSON paths to values from a JSON String?

My goal is to read a JSON file and understand the location of all the values, so that when I encounter that same JSON, I can easily read all the values. I am looking for a way to return a list containing all of the paths to each data value, in Jayway JsonPath format.
Example JSON:
{
"shopper": {
"Id": "4973860941232342",
"Context": {
"CollapseOrderItems": false,
"IsTest": false
}
},
"SelfIdentifiersData": {
"SelfIdentifierData": [
{
"SelfIdentifierType": {
"SelfIdentifierType": "111"
}
},
{
"SelfIdentifierType": {
"SelfIdentifierType": "2222"
}
}
]
}
}
Ideally I would like to take that JSON as a String and do something like this:
String json = "{'shopper': {'Id': '4973860941232342', 'Context': {'CollapseOrderItems': false, 'IsTest': false } }, 'SelfIdentifiersData': {'SelfIdentifierData': [{'SelfIdentifierType': {'SelfIdentifierType': '111'} }, {'SelfIdentifierType': {'SelfIdentifierType': '2222'} } ] } }";
Configuration conf = Configuration.defaultConfiguration();
List<String> jsonPaths = JsonPath.using(conf).parse(json).read("$");
for (String path : jsonPaths) {
System.out.println(path);
}
This code would print this, which is the location of all values in the JSON:
$.shopper.Id
$.shopper.Context.CollapseOrderItems
$.shopper.Context.IsTest
$.SelfIdentifiersData[0].SelfIdentifierData.SelfIdentifierType.SelfIdentifierType
$.SelfIdentifiersData[1].SelfIdentifierData.SelfIdentifierType.SelfIdentifierType
Then ideally, I would be able to take that list and parse the same JSON object to get each value present.
//after list is created
Object document = Configuration.defaultConfiguration().jsonProvider().parse(json);
for (String path : jsonPaths) {
Object value = JsonPath.read(document, path);
//do something
}
I am aware that I could get a Map that is a representation of the JSON file, but I am not sure that provides the same ease of access to retrieve all the values. If there is a easy way to do with JSONPath, that would be great, otherwise any other approaches are welcome.
I came up with a solution, sharing in case anyone else is looking for the same thing:
public class JsonParser {
private List<String> pathList;
private String json;
public JsonParser(String json) {
this.json = json;
this.pathList = new ArrayList<String>();
setJsonPaths(json);
}
public List<String> getPathList() {
return this.pathList;
}
private void setJsonPaths(String json) {
this.pathList = new ArrayList<String>();
JSONObject object = new JSONObject(json);
String jsonPath = "$";
if(json != JSONObject.NULL) {
readObject(object, jsonPath);
}
}
private void readObject(JSONObject object, String jsonPath) {
Iterator<String> keysItr = object.keys();
String parentPath = jsonPath;
while(keysItr.hasNext()) {
String key = keysItr.next();
Object value = object.get(key);
jsonPath = parentPath + "." + key;
if(value instanceof JSONArray) {
readArray((JSONArray) value, jsonPath);
}
else if(value instanceof JSONObject) {
readObject((JSONObject) value, jsonPath);
} else { // is a value
this.pathList.add(jsonPath);
}
}
}
private void readArray(JSONArray array, String jsonPath) {
String parentPath = jsonPath;
for(int i = 0; i < array.length(); i++) {
Object value = array.get(i);
jsonPath = parentPath + "[" + i + "]";
if(value instanceof JSONArray) {
readArray((JSONArray) value, jsonPath);
} else if(value instanceof JSONObject) {
readObject((JSONObject) value, jsonPath);
} else { // is a value
this.pathList.add(jsonPath);
}
}
}
}
Refer to this utility : https://github.com/wnameless/json-flattener
Perfect answer to your requirement. Provides Flattened map and Flattened strings for complex json strings.
I am not the author of this but have used it successfully for my usecase.

How to get dynamically changed Key's value in Json String using java

I'm trying to parse Json string using java, I have stuck up with some scenario.
See below is my JSON String:
"NetworkSettings": {
"Ports": {
"8080/tcp": [ // It will change dynamically like ("8125/udp" and "8080/udp" etc....)
{
"HostIp": "0.0.0.0",
"HostPort": "8080"
}
]
}
}
I try to parse the above json string by using the following code:
JsonObject NetworkSettings_obj=(JsonObject)obj.get("NetworkSettings");
if(NetworkSettings_obj.has("Ports"))
{
JsonObject ntw_Ports_obj=(JsonObject)NetworkSettings_obj.get("Ports");
if(ntw_Ports_obj.has("8080/tcp"))
{
JsonArray arr_ntwtcp=(JsonArray)ntw_Ports_obj.get("8080/tcp");
JsonObject ntwtcp_obj=arr_ntwtcp.get(0).getAsJsonObject();
if(ntwtcp_obj.has("HostIp"))
{
ntw_HostIp=ntwtcp_obj.get("HostIp").toString();
System.out.println("Network HostIp = "+ntw_HostIp);
}
if(ntwtcp_obj.has("HostPort"))
{
ntw_HostPort=ntwtcp_obj.get("HostPort").toString();
System.out.println("Network HostPort = "+ntw_HostPort);
}
}
else
{
ntw_HostIp="NA";
ntw_HostPort="NA";
}
}
else
{
ntw_HostIp="NA";
ntw_HostPort="NA";
}
In my code I have used this code
JsonArray arr_ntwtcp=(JsonArray)ntw_Ports_obj.get("8080/tcp");
to get the value of "8080/tcp"
How can I get the values of dynamically changing key like ("8125/udp","8134/udp", etc...)
Note: I'm using gson library for parsing
After modification
public static void main(String args[])
{
try
{
JsonParser parser = new JsonParser();
JsonObject obj=(JsonObject)parser.parse(new FileReader("sampleJson.txt"));
System.out.println("obj = "+obj);
JsonObject NetworkSettings_obj=(JsonObject)obj.get("NetworkSettings");
if(NetworkSettings_obj.has("Ports"))
{
JsonObject ntw_Ports_obj=(JsonObject)NetworkSettings_obj.get("Ports");
System.out.println("ntw_Ports_obj = "+ntw_Ports_obj);
Object keyObjects = new Gson().fromJson(ntw_Ports_obj, Object.class);
List keys = new ArrayList();
System.out.println(keyObjects instanceof Map); //**** here the statement prints false
if (keyObjects instanceof Map) // *** so controls doesn't enters into the if() condition block *** //
{
Map map = (Map) keyObjects;
System.out.println("Map = "+map);
keys.addAll(map.keySet());
String key = (String) keys.get(0);
JsonArray jArray = (JsonArray) ntw_Ports_obj.get(key);
System.out.println("Array List = "+jArray);
}
}
}
catch(Exception e)
{
}
}
You can do something like that (not tested but should be ok) :
if (ntw_Ports_obj.isJsonArray()) {
Iterator it = ntw_Ports_obj.getAsJsonArray().iterator();
while (it.hasNext()) {
JsonElement element = (JsonElement) it.next();
if(element.isJsonArray()){
JsonArray currentArray = element.getAsJsonArray();
// Do something with the new JsonArray...
}
}
}
So your problem is the key 8080/tcp is not fixed and it may change. when this situation you can try like this to get the value of the Dynamic key.
Set<Map.Entry<String, JsonElement>> entrySet = ntw_Ports_obj
.entrySet();
for (Map.Entry<String, JsonElement> entry : entrySet) {
String key = entry.getKey();
JsonArray jArray = (JsonArray) ntw_Ports_obj.get(key);
System.out.println(jArray);
}
Edit:
Object keyObjects = new Gson().fromJson(ntw_Ports_obj, Object.class);
List keys = new ArrayList();
/** for the given json there is a one json object within the 'Ports' so the 'keyObjects' will be the 'Map'**/
if (keyObjects instanceof Map) {
Map map = (Map) keyObjects;
keys.addAll(map.keySet());
/**
* keys is a List it may contain more than 1 value, but for the given
* json it will contain only one value
**/
String key = (String) keys.get(0);
JsonArray jArray = (JsonArray) ntw_Ports_obj.get(key);
System.out.println(jArray);
}

how to get specific value from json file in java

I have a json file like this:
{
"list": [
{
"ID" : "1",
"value" : "value is one"
}
{
"ID" : "2",
"value" : "value is two"
}
{
"ID" : "3",
"value" : "value is three"
}
{
"ID" : "4",
"value" : "value is four"
}
]
}
what I want to do is read the josn file and returns the message based on the ID i specify. So for example
if (this.list.containsKey("1"))
{
return this.list.get(messageTitle);
}
That's what I tried but it returns all the values and ID.
JSONParser parser = new JSONParser();
try {
Object obj = parser.parse(new FileReader("jsonFile.json"));
JSONObject jsonObject = (JSONObject) obj;
// loop array
JSONArray msg = (JSONArray) jsonObject.get("list");
Iterator<String> iterator = msg.iterator();
while (iterator.hasNext()) {
System.out.println(iterator.next());
}
}
How try like this,
JSONArray msg = (JSONArray) jsonObject.get("list");
for(int i = 0;i < msg.length();i++ ) {
JSONObject jsonObj = msg.getJSONObject(i);
//now get id & value
int id = jsonObj.getInt("ID");
String value = jsonObj.getString("value");
if (1 == id) {
//now 'value' is what you want
System.out.println(value);
}
}
Note: can break the loop when the result is satisfied.
You can try with TypeReference using ObjectMapper to convert it into appropriate Map object.
sample code:
BufferedReader reader = new BufferedReader(new FileReader(new File("jsonFile.json")));
TypeReference<Map<String, ArrayList<Map<String, String>>>> typeRef = new TypeReference<Map<String, ArrayList<Map<String, String>>>>() {};
ObjectMapper mapper = new ObjectMapper();
try {
Map<String, ArrayList<Map<String, String>>> data = mapper.readValue(reader, typeRef);
ArrayList<Map<String, String>> list = data.get("list");
for (Map<String, String> map : list) {
if (map.get("ID").equals("1")) {
System.out.println(map.get("value"));
}
}
} catch (Exception e) {
System.out.println("There might be some issue with the JSON string");
}
output:
value is one

Categories