May be it's a simple task for some one.
I've json like below.
{
"address": {
"state": "World",
"address": "infinite space, 000",
"city": "Android city",
"address2": {
"state": "World2",
"address": "infinite space2, 002",
"city": "Android city2",
"address3": {
"state": "World3",
"address": "infinite space3, 003",
"city": "Android city3"
}
}
},
"valid": {
"state": "World",
"address": "infinite space, 000",
"city": "Android city",
"valid2": {
"state": "World2",
"address": "infinite space2, 002",
"city": "Android city2",
"valid3": {
"state": "World3",
"address": "infinite space3, 003",
"city": "Android city3"
}
}
}
}
This is a sample structure. Some times may have many objects inside of one object. I know this is a bad format of JSON but i've to achieve my requirement by using this only :-(.
My requirement is: when we sending the object name like address3 or valid3 to a method as argument. My method have to return key and value of object (Which we passed as argument). Any one know, how to achieve this in Java?
You can parse the JSON and convert the result into a HashMap<String,String>
Here is sample code for this JSON object .
public HashMap<String,String> getKeyValuePairs(JSONObject json,String key){
HashMap<String,String> jsonHashList=new HashMap<String,String>();
JSONObject desiredJSON = json.get(key);
Iterator<?> keys = desiredJSON.keys();
while( keys.hasNext() ) {
String key2 = (String)keys.next();
if ( desiredJSON.get(key2) instanceof JSONObject ) {
String value = desiredJSON.get(key2);
jsonHashList.add(key2,value);
}
}
return jsonHashList;
}
Note : In this case key is assumed to be at level one of passed JSON so if you want to pass any JSON to get it's key values separated pass the Level One JSON.
This is the solution
private void parseJson(JSONObject jsonObject, String objName){
try {
for(int i = 0; i < jsonObject.length(); i++){
if(jsonObject.get(jsonObject.names().getString(i)) instanceof JSONObject){
JSONObject singleObj = new JSONObject(jsonObject.get(jsonObject.names().getString(i)).toString());
Iterator<String> keys= singleObj.keys();
while (keys.hasNext()){
String keyValue = keys.next();
final String valueString = singleObj.getString(keyValue);
if(!isJSONObjectOrString(valueString)){
if(keyValue.contains(objName) || valueString.contains(objName)
|| jsonObject.names().getString(i).contains(objName)){
Log.e("objectName", jsonObject.names().getString(i));
Log.e(keyValue, valueString);
}
}
}
parseJson(singleObj);
}
}
} catch (JSONException e) {
e.printStackTrace();
}
}
Related
so there is a jsonReqObj,
jsonReqObj = {
"postData" : {
"name":"abc",
"age": 3,
"details": {
"eyeColor":"green",
"height": "172cm",
"weight": "124lb",
}
}
}
And there is a save function that will return a string. I want to use that save function, but the input parameter for the save json should be the json inside postData.
public String save(JsonObject jsonReqObj) throw IOException {
...
return message
}
below are my code
JsonObject jsonReqPostData = jsonReqObj.get("postData")
String finalMes = save(jsonReqPostData);
But I am getting the error that
com.google.gson.JsonElement cannot be convert to com.google.gson.JsonObject.
JsonObject.get returns a JsonElement - it might be a string, or a Boolean value etc.
On option is to still call get, but cast to JsonObject:
JsonObject jsonReqPostData = (JsonObject) jsonReqObj.get("postData");
This will fail with an exception if it turns out that postData is a string etc. That's probably fine. It will return null if jsonReqObj doesn't contain a postData property at all - the cast will succeed in that case, leaving the variable jsonReqPostData with a null value.
An alternative option which is probably clearer is to call getAsJsonObject instead:
JsonObject jsonReqPostData = jsonReqObj.getAsJsonObject("postData");
I have validated your JSON file with https://jsonlint.com/ and it looks like the format is incorrect, instead of be:
jsonReqObj = {
"postData": {
"name": "abc",
"age": 3,
"details": {
"eyeColor": "green",
"height": "172cm",
"weight": "124lb",
}
}
}
Should be:
{
"postData": {
"name": "abc",
"age": 3,
"details": {
"eyeColor": "green",
"height": "172cm",
"weight": "124lb"
}
}
}
Maybe thats why you cant convert to an object
Note: I would put this as a comment instead as an answer, but i dont have enought reputation T_T
I have define List of HashMap and reading the response of JSON API . Currently able to read only one value from the list and I want to read all the values.
List<HashMap<String,Object>> allids = response.jsonPath().getList("data");
HashMap<String,Object> firstid = allids.get(0);
Object a = firstid.get("country");
System.out.println(a);
JSON Response in PostMan
{
"response": {
"code": 200,
"status": "success",
"alert": [
{
"message": "Success",
"type": "success",
"skippable": 1
}
],
"from_cache": 0,
"is_data": 1
},
"data": [
{
"id": 6004,
"airport_name": "Adampur Airport",
"city": "Adampur",
"country": "India",
"iata": "AIP",
"icao": "VIAX",
"latitude": "31.4338",
"longitude": "75.758797",
"altitude": "775"
}
]
}
Just forEach on your List you will get Map and then get all your Object bu using get .
List<HashMap<String,Object>> allids = response.jsonPath().getList("data");
allids.forEach(elem->{
String country = (String) elem.get("country");
String city = (String) elem.get("city");
// and so on.
});
Judging from the context, you can iterate over the list and get the Map values
List<HashMap<String,Object>> allids = response.jsonPath().getList("data");
for(int i=0; i<allids.size(); i++){
HashMap<String,Object> firstid = allids.get(i);
String country = (String) firstid.get("country");
String city = (String) firstid.get("city");
String iata = (String) firstid.get("iata");
String altitude = (String) firstid.get("altitude");
//similarly get others
System.out.println(country);
}
**My result of JSONObject to convert as follows bellow code and have searched for many this how to convert using java but I converted that **
{
"result": {
"accountnames": [{
"accountName": "Hari",
"accountId": 878488
}, {
"accountName": "ravi",
"accountId": 878487
}],
"sales": [{
"accountSales": "89",
"accountId": 878488
}, {
"accountName": "98",
"accountId": 878487
}],
"countResult": [{
"accountResult": "945",
"accountId": 878488
}, {
"accountResult": "9452",
"accountId": 878489
}]
}
}
*and this is where the sample code to be converted *
{
"result": [{
"accountName": "Hari",
"accountSales": "89",
"accountResult": "945",
"accountId": 878488
},
{
"accountName": "ravi",
"accountSales": "98",
"accountId": 878487
},
{
"accountResult": "9452",
"accountId": 878489
}
]
}
My required JSON data has to be formatted as below
You need to group all the elements by accountId. You can use something like this depending on the json library that you are using.
Initialize the json object:
JSONObject rootJson = new JSONObject(json);
JSONObject resultJson = rootJson.getJSONObject("result");
Create a map to hold the objects by accountId:
Map<String, JSONObject> accountIds = new HashMap<>();
Then iterate for each key in the json, then for each element in the arrays and then for each property of the object inside the json:
Iterator mainKeys = resultJson.keys();
while (mainKeys.hasNext()) {
String key = (String) mainKeys.next();
JSONArray array = resultJson.getJSONArray(key);
for (int index = 0; index < array.length(); index++) {
JSONObject object = array.getJSONObject(index);
if (object.has("accountId")) {
String accountId = object.get("accountId").toString();
JSONObject accum = accountIds
.computeIfAbsent(accountId, (k) -> new JSONObject());
// depending on the json impl you can use putAll or similar
Iterator objKeys = object.keys();
while (objKeys.hasNext()) {
String property = (String) objKeys.next();
accum.put(property, object.get(property));
}
} else {
// does not have account id, ignore or throw
}
}
}
Finally create the json file and add the elements to the JSONArray:
JSONObject finalJson = new JSONObject();
finalJson.put("result", new JSONArray(accountIds.values()));
System.out.println(finalJson.toString());
(note: the json has an error in sales array accountName instead of accountSales)
Json1:
{
"array1": [
{
"Name": "Xytrex Co.",
"Description": "Industrial Cleaning Supply Company",
"Account Number": "ABC15797531",
"Address": {
"Street": "st.road",
"pin": "789723"
}
},
{
"Name": "XYZ Company",
"Address": {
"Street": "Peters road",
"pin": "789700"
}
}
]
}
Json2:
{
"array2":[
{
"Name": "Xytrex Co.",
"Description": "Industrial Cleaning Supply Company",
"Account Number": "ABC15797531",
"Address": {
"Street": "st.road",
"pin": "789723"
}
},
{
"Name": "XYZ Company",
"Description": "Domestic Cleaning Supply Company",
"Address": {
"Street": "Peters road",
"pin": "789700"
}
}
]
}
Java Code used by me:
JsonParser Parser = new JsonParser();
Object obj1 = Parser.parse(new
FileReader("/home/cloudera/Desktop/SampleJson/src/JSON1.json"));
Object obj2 = Parser.parse(new
FileReader("/home/cloudera/Desktop/SampleJson/src/JSON2.json"));
JsonObject jsonObject1 = (JsonObject) obj1;
JsonObject jsonObject2 = (JsonObject) obj2;
Set<Map.Entry<String, JsonElement>> entries1 = jsonObject1.entrySet();
Set<Map.Entry<String, JsonElement>> entries2 = jsonObject2.entrySet();
for (Map.Entry<String, JsonElement> entry : entries1) {
//System.out.println("FirstJson:"+entry.getKey());
}
for (Map.Entry<String, JsonElement> entry : entries2) {
//System.out.println("SecondJson:"+entry.getKey());
}
if (jsonObject1.equals(jsonObject2)) {
System.out.println("Success");
} else {
entries1.removeAll(entries2);
//System.out.println("\n");
System.out.println("Result:" + entries1);
}
I have to compare two json files which contain arrays using Java, In array1 "Description" is missing I have to print that exact key and not the entire Json from first to last. In my output also "Description" is not there, but it's not printing exactly that key, its printing from first to last. Please help me with this.
The output I got:
Result:[array1=[{"Name":"Xytrex Co.","Description":"Industrial Cleaning Supply Company","Account Number":"ABC15797531","Address":{"Street":"st.road","pin":"789723"}},{"Name":"XYZ Company","Address":{"Street":"Peters road","pin":"789700"}}]]
This library is clean way to handle json comparison. It also has compare mode like strict check etc.
http://jsonassert.skyscreamer.org/javadoc/org/skyscreamer/jsonassert/JSONCompare.html
For your usecase you can check JSONCompareResult solves your problem.
I'd suggest you to use https://github.com/eBay/json-comparison library.
This library based on JsonAssert project but provide additional features
such as 'Exclude paths' , dealing with order and more
where I want to check which elements of the 1st file are missing in the second one.
Here is the form of the first one:
[
{
"pId": "pId1",
"Platform":["ios","and","web","winph","win"],
"Name": "ay",
"ShortDescription": "Mobi",
"Detail" : {
"IncentiveInformation": "ppp",
"DisplayName" : "vvv!",
"Description" : "mmm",
"TermsAndConditions": ".."
}
},
{
"pId": "pId2",
"Platform":["afasd","sdfsd","pppp","asdas","win"],
"Name": "ay",
"ShortDescription": "mob",
"PromotionDetail": {
"DebugMode": false,
"PromoDate": ["2015.01.01-00:01","2015.01.01-23:59"],
"IncentiveInformation": "PRO",
"Name": "iTunes",
"ShortDescription": "Punkte sammeln bei iTunes",
"DisplayName": null,
"Description": null,
"ImageURL": null,
"JumpToShopURL": "urlHere",
"JumpToShopName" : "Zu iTunes"
}
},
{
"pId": "pId3",
"Platform":["wqdsa"],
"Name": "poti",
"ShortDescription": "pun",
"ImageURL": "url.here",
"Promotion" : false,
"PromotionDetail": {
"DebugMode": false,
"PromoDate": ["2015.01.01-00:00","2015.01.01-23:59"],
"IncentiveInformation": "ppeur",
"Name": "namehere",
"ShortDescription": "tune",
"DisplayName": null,
"Description": null,
"ImageURL": null,
"JumpToShopURL": "noq",
"JumpToShopName" : "Zu"
}
}
]
and here is the form of the 2nd one:
{
"pList": [{
"shortName": "bb",
"longName": "bb",
"pId": "pId2",
"featured": true,
"pLog": "url.here",
"incentivation": "eu",
"details": {
"teaserImage": "image.url",
"description": "desc here",
"jumpToShopURL": "nurl",
"jumpToShopButton": "zubay",
"terms": [{
"headline": "Wichtig",
"body": "bodyline"
}]
}
}, {
"shortName": "one short name",
"longName": "bkp",
"pId": "pId1",
"featured": true,
"pLo": "some.pLo",
"incentivation": "1p",
"details": {
"teaserImage": "some.url",
"description": "desc",
"jumpToShopURL": "short url",
"jumpToShopButton": "Zuay",
"terms": [{
"headline": "Wichtig",
"body": "bodyhere"
}]
}
}]
}
Si I thought to save all the "pId" of the first one in a List(or array) and then iterate over that list and check for each one if the pId exists in the new one.
So I tried this, but it is not working..
Could anyone help me with that? I tried a bit and then I found that I have too many difficulties, to get the pIds saved in a list or an array.
So has someone an idea?
import java.io.*;
import org.json.*;
public class MainDriver {
public static void main(String[] args) throws JSONException {
String jsonData = readFile("C:\\Users\\kbelkhiria\\Desktop\\Karim_JSON\\alt.json");
JSONObject jobj = new JSONObject(jsonData);
JSONArray jarr = new JSONArray(jobj.getJSONArray("pList").toString());
for(int i = 0; i < jarr.length(); i++)
System.out.println("id: " + jarr.getString(i));
}
public static String readFile(String filename) {
String result = "";
try {
BufferedReader br = new BufferedReader(new FileReader(filename));
StringBuilder sb = new StringBuilder();
String line = br.readLine();
while (line != null) {
sb.append(line);
line = br.readLine();
}
result = sb.toString();
} catch(Exception e) {
e.printStackTrace();
}
return result;
}
}
For the 2nd form, you have an JSONObject, but it contains some errors. Please fix them, or use a the 1st form again.
SOLUTION
I found some errors in the second file so I suggest the following edits:
change "jumpToShopURL": nurl", to "jumpToShopURL": null,
add a comma at the end of "description": "desc"
add a comma at the end of "jumpToShopURL": "short url"
For the code, you can use the following lines:
/*first file*/
String jsonData = readFile("C:\\Users\\kbelkhiria\\Desktop\\Karim_JSON\\alt.json");
JSONArray jarr = new JSONArray(jsonData);
/*array of first file's ids*/
ArrayList<String> srcArray = new ArrayList<>();
for(int i = 0; i < jarr.length(); i++) {
srcArray.add(jarr.getJSONObject(i).getString("pId"));
}
/*second file*/
// second form in a seperate file
JSONObject obj = new JSONObject(readFile("C:\\Users\\kbelkhiria\\Desktop\\Karim_JSON\\alt2.json"));
JSONArray arr = obj.getJSONArray("pList");
/*array of second file's ids*/
ArrayList<String> dstArray = new ArrayList<>();
for(int i = 0; i < arr.length(); i++) {
dstArray.add(jarr.getJSONObject(i).getString("pId"));
}
for (String string : srcArray) {
if (dstArray.indexOf(string)==-1)
System.out.println(string + " is missing in the second file");
}
Luckily for you there are already developed libraries to parse any JSON string, like the one's you provided. One of the most popular is
org.json
Using this you can write code similar to this:
import org.json.*;
String myString = ".." // The String representation you provided
JSONObject obj = new JSONObject(myString);
JSONArray arr = obj.getJSONArray("pList");
Another popular library for the same task is GSON
One possible solution using Jackson is the following:
private static final String JSON1 = // first json;
private static final String JSON2 = //second json;
public static void main(String[] args) throws IOException {
ObjectMapper mapper = new ObjectMapper();
List<LinkedHashMap> list1 = Arrays.asList(mapper.readValue(JSON1, LinkedHashMap[].class));
List<LinkedHashMap> list2 = Arrays.asList(mapper.readValue(mapper.readTree(JSON2).get("pList").toString(), LinkedHashMap[].class));
List<LinkedHashMap> missingItens = new ArrayList<>();
for (LinkedHashMap o1 : list1) {
if (!objectExistsInList(o1.get("pId").toString(), list2)) {
missingItens.add(o1);
}
}
}
private static boolean objectExistsInList(String pIdValue, List<LinkedHashMap> objs) {
for (LinkedHashMap map : objs) {
if (map.containsValue(pIdValue)) {
return true;
}
}
return false;
}
Please keep in mind this is a very specific implementation to the given JSONs.