I want to find a key in JSON that has repeated more than certain times or not. Based on the result I have to add some other key/value pairs to another JSON object. Is there any way that I can achieve this?
Thanks in Advance.
You can use the JSON Simple library to parse a json object: https://code.google.com/p/json-simple/
After that you can simply iterate over the objects and count their occurrences.
Maybe ... something like this:
public int countOccurrenceOfKey(final String jsonString, final String key) {
int occurrenceCounter = 0;
String[] jsonParts = jsonString.split(","); // maybe another splitter if comma appears within values
for(int i = 0; i < jsonParts.length; i=i+2) { // step to every second index so you only check the keys. start with i = 1 to check only values
String part = jsonParts[i];
if(part.contains(key) {
occurrenceCounter++;
}
}
return occurrenceCounter;
}
Why using a JSON library could probably create problems...
If your JSON string contains the same key more than 1 time (maybe you generated it manually):
A. The JSON converter could raise an exception and abort creating the object.
B. The library could only take the first or last appearance of the key so all other values for the same key could be lost.
Depends on the library implementation and on the JSON specification.
{
"responseCode": 200,
"responseMessage": "COMPLETE",
"responseData": "95W_RTXszAuuwsLxp8pA56UJQhMfNSVRQ-6OWd_f5-4tvBHp9WI4UgPBfop2AWPBY7xCI0QQcb2QwKuCRhSNdzbGOHlNL_Oectcb4xeUV_-cN8mqPo5iVyqXn_QtOtpn9GxlocFyLmXsjOKQgd5W_HsrmIwwldEwKLlcAzDTy9MIVSiZ3O97YXAzVZleV_yM0V4IqEd68wK3xGamCf05d_e4W-pnc56y3MSXRpu9op3Km0IdQAXj6gqeYCXe-AoZhj_OSP4pHpRJipixFpQGxWsSK2fhvZmdoNGxQRKtZGBzgJ9blCRFmNteio9_GbhOMXL6ySnSRbtSZ_RfBsjMu2m1MKWb0YOwQyOrIjKpQ3KOnXNCc0j54nF24YRmdFMZXbPktzrU90Y3HpzuX1xAZM0oAoUOm2xiJii1CJmH9YCOq3vR_eFneBFXFrOVCz29YKOkE4hlRHLlYxwgmWh91BFney0QIF9f9lyjHLTN958murr8dm6cS4BHSqWzeCrS86QuU4j7Zpgz6_jZUP-jK9Damjph2ZYJsIw5YHG_1dXRqse1RwbPYzP5xjADqgDVZm4IJfOwSiaYsuXtmm0hBj9fCj4DTVjVptnoYcv8Z649TquOYgbs-58st_bycROo9i1erwLz_nDdjIlQKPfz64a5UA",
"responseVersion": 3
}
Related
I'm looking for a way to hide/mask the sensitive details of JSON output coming from a response, like account number.
All the answers I got over the web requires me to know the JSON structure before hand. Isn't there any way to extensively traverse each key and then replace it's value with required masking character, without knowing the JSON structure beforehand, which means the required key can be within a JSONArray or JSONObject and sometimes within one another.
Check if the following link to handle dynamic Json helps.
Basically the link highlights two options.
a) Using JsonNode
b) Mapping Dynamic properties using a Map
If you are using the com.google.gson.GsonBuilder.GsonBuilder(). You can add Type adapters, using the method registerTypeAdapter(TypeToAdapt.class, myTypeAdapter), where myTypeAdapter extends TypeAdapter<TypeToAdapt>.
Possibly more to your case, you can set exclusion classes, see:
https://howtodoinjava.com/gson/gson-gsonbuilder-configuration/
It is also possible to add bespoke Serialisers and deserialisers by using the #JsonAdapter(BespokeSerialiser.class) or #JsonAdapter(BespokeDeserialiser.class) to your model class.
The BespokeSerialiser or BespokeDeserialiser must implement JsonSerializer<ModelClass> or JsonDeserializer<ModelClass>.
Thank you all for the replies, it gave me an insight into the solution I was looking for. However, me and my colleague wrote the exact method we were looking for. The method we wrote accepts a JSON as an JSON Object, the key to be searched and the mask string by which I want the key's value to be replaced with.
Feel free to contribute on improving the below code.
public static JSONObject maskJSONValue(JSONObject jsonObject, String key, String mask) throws Exception{
Iterator iterator = jsonObject.keys();
String localKey = null;
while (iterator.hasNext()){
localKey = (String) iterator.next();
if((jsonObject.optJSONArray(localKey) == null) && (jsonObject.optJSONObject(localKey) == null)){
if((localKey.equals(key))){
jsonObject.put(localKey, mask);
return jsonObject;
}
}
}
if(jsonObject.optJSONObject(localKey) != null)
maskJSONValue(jsonObject.getJSONObject(localKey), key, mask);
if(jsonObject.optJSONArray(localKey) != null){
JSONArray jArray = jsonObject.getJSONArray(localKey);
for( int i = 0; i < jArray.length(); i++)
maskJSONValue(jArray.getJSONObject(i), key, mask);
}
return jsonObject;
}
I am doing a POST call action through my selenium Automation program using Rest Assured API & Java. IO get a response as mentioned below-
{
"cmsContract": "HA1123",
"groupId": "12345",
"siteId": "4444-AP",
"stateCountyCode": "7978790"
},
{
"cmsContract": "HB2345",
"groupId": "9876",
"siteId": "8888-DK",
"stateCountyCode": "111225"
}
There are about 1000 or more JSON Objects in the response. And they don't have a identifier for the response like "name" or "contractinfo"
My query:
1. How do I retrieve the total count of the arrays (like one from '{' to '}') using Rest Assured APIs in conjuncture with JAVA and selenium?
If I had to retrieve 'stateCountyCode' for the result set with 'cmsContract' as HB2345 , how would I do that? I would want to see the value return as 111225
Please suggest.
Libraries used-
org.json.JSONObject;
io.restassured.RestAssured;
io.restassured.response.Response;
io.restassured.specification.RequestSpecification;
You can use JsonPath to parse JSON response. Basically, you can get JsonPath class from String, File or Response.
From String:
JsonPath path = JsonPath.from("json string");
From File:
JsonPath path = JsonPath.from(new File("path to file"));
From Response:
Response response; //we get it from RestAssured by calling POST/GET etc
JsonPath path = response.body().jsonPath();
In order to get any element in the JSON Structure, just like in your case, we have to provide it to JsonPath. Example JSON:
{
"data": [
{
"name": "test"
},
{
"name": "test1"
}
]
}
In order to access an element in the Array, we have to know ALL of its parents.
The structure looks like this:
path.get("parent.child.anotherChild");
The thing gets more tricky with Arrays because we have to use indexes.
The "data" in the example above is an array. In order to access test1 we would use:
path.get("data[1].name"); //second element in the array
But that's the standard approach. JsonPath is a much stronger library.
Finally, to answer your question. How do we get a count of JSON Objects in the Array?
List<HashMap<String, Object>> jsonObjects = path.getList("data"); //You have to provide name of the Array's parent. In my case, it's `data`
In the above List of HashMaps, we have ALL of JSON Objects in the JSON Array. So you can use multiple ways to count the elements.
To count how many JSON Objects there is you can simply use List's method:
jsonObjects.size();
With the same List, we can get cmsContract value, as in your example. We look for value HB2345.
Standard for loop. You can use Streams if you know how.
public String getStateCountryCodeFromCmsContract(String cmsContractValue) {
for (HashMap<String, Object> singleJsonObject : jsonObjects) {
String cmsContract = (String) singleJsonObject.get("cmsContract");
if (cmsContract.equals(cmsContractValue)) {
return (String) singleJsonObject.get("stateCountyCode");
}
}
}
We iterate over each JSON Object, check the value of cmsContract element, and if it equals the desired value - return stateCountryCode value.
Hope it helps!
Hi i have a php script that input user data into mysql and from mysql i get the results in an array and finally to json format by json_encode functino of PHP. The contents of the file are provided below.
[{"priority":"1","rule_body":"person(?x),pid(?y),haspid(?x,?y)","cons":"patient(?x)","boolean":"1"},
{"priority":"1","rule_body":"patient(?x),hasbp(high)","cons":"situation(emergency)","boolean":"1"},
{"priority":"1","rule_body":"patient(?x),hasbp(high)","cons":"situation(emergency)","boolean":"1"},
{"priority":"1","rule_body":"patient(?x),hasbp(high)","cons":"situation(emergency)","boolean":"1"},
{"priority":"1","rule_body":"aaa(bbb)","cons":"z(x)","boolean":"1"},
{"priority":"1","rule_body":"aaa(bbb)","cons":"z(x)","boolean":"1"},
{"priority":"1","rule_body":"aaa(bbb)","cons":"z(x)","boolean":"1"}]
However now i need to get the json read in the JAVA and for ease i copy and paste the contents of the json file to string. I am able to read the contents but the positions has changed to the following sequence
here is the output
LENGTH IS____7
{"priority":"1","boolean":"1","rule_body":"person(?x),pid(?y),haspid(?x,?y)","cons":"patient(?x)"}
{"priority":"1","boolean":"1","rule_body":"patient(?x),hasbp(high)","cons":"situation(emergency)"}
{"priority":"1","boolean":"1","rule_body":"patient(?x),hasbp(high)","cons":"situation(emergency)"}
{"priority":"1","boolean":"1","rule_body":"patient(?x),hasbp(high)","cons":"situation(emergency)"}
{"priority":"1","boolean":"1","rule_body":"aaa(bbb)","cons":"z(x)"}
{"priority":"1","boolean":"1","rule_body":"aaa(bbb)","cons":"z(x)"}
{"priority":"1","boolean":"1","rule_body":"aaa(bbb)","cons":"z(x)"}
as you can see that the boolean has to be in the end but it pops up on the second number. i treid differenct codes from tutorials and did some my own as below but the result is same: help is needed in this matter.
jsonInput=[....as shown above the json contents....]
JSONArray ja = new JSONArray(jsonInput);
System.out.println("LENGTH IS____"+ja.length());
for(int x=0;x<ja.length();x++)
{
JSONObject jb = ja.getJSONObject(x);
System.out.println(jb);
}
System.out.println("KKKKKKKKKKKKKKKKKKKKKKKKKKKKKK");
JSON doesn't specify an order for keys As Adrian Smith said :
JSON libraries are free to rearrange the order of the elements as they see fit. This is not a bug.
You probably use org.json. You can use the getString("myKey") to access the value in your JSONObject without knowing his position.
An other solution is to create a class that represents your data:
public class myClass{
private int priority;
private String rule_body;
private String cons;
private String boolean; //STRING ! 1 is not a valid boolean value.
}
Then create an ArrayList of your class and deserialize your JSON in it with Gson.
Gson myGsonTool = new Gson();
ArrayList<myClass> myData = gson.fromJson(myJsonString, ArrayList<myClass>.class);
Then, you have a POJO with all your data. You can access easily to your data now:
//If i want the value of rule body:
myData.get(0).getRule_Body();
I do not know the purpose of your program, so this is maybe not the best solution.
Edit: Gson maintains the order of records.
The code that we already have return us JsonObject. What I want to do is to add a new key and the value for it.
For example, we have an object like this:
{"id":"12","name":"test"}
I want to transform it into this:
{"id":"12","name":"test","status":"complete"}
I didn't find what I need in documentation except using put method. So I wrote this code:
JsonObject object = getJsonObject();
JsonString val = new JsonString() {
public JsonValue.ValueType getValueType() {
return JsonValue.ValueType.STRING;
}
public String getString() {
return "complete";
}
public CharSequence getChars() {
return (CharSequence) "complete";
}
};
object.put("status", val);
But it doesn't work, crashing with :
java.lang.UnsupportedOperationException
I can't understand what is wrong. Have I any other option to complete such a task?
I don't think JsonObject instances are meant to be modified.
I think your best option is to create a new object, copy the existing properties and add the new property to it.
You can use https://docs.oracle.com/javaee/7/api/javax/json/JsonObjectBuilder.html
Not sure if object.put works but you can use the following way to append the details to JSON value:
You can create a different JSON object with the key and value that you want to add to the JSON object and the user object.merge(status, complete, String::concat);
merge() checks for the key:'status' in your JSON object if it does'nt find it then it adds that key:value pair or else it replaces it
.You are not able to compile it because you may not be using jre 1.8.
I've Just verified the following method:
Just create a new JSONObject(org.json.JSONObject not javax.json.JsonObject)
JSONObject modifiedJsonObject= new JSONObject(object.toString());
modifiedJsonObject.put("status", "complete");
So, I get some JSON values from the server but I don't know if there will be a particular field or not.
So like:
{ "regatta_name":"ProbaRegatta",
"country":"Congo",
"status":"invited"
}
And sometimes, there will be an extra field like:
{ "regatta_name":"ProbaRegatta",
"country":"Congo",
"status":"invited",
"club":"somevalue"
}
I would like to check if the field named "club" exists so that at parsing I won't get
org.json.JSONException: No value for club
JSONObject class has a method named "has":
http://developer.android.com/reference/org/json/JSONObject.html#has(java.lang.String)
Returns true if this object has a mapping for name. The mapping may be NULL.
You can check this way where 'HAS' - Returns true if this object has a mapping for name. The mapping may be NULL.
if (json.has("status")) {
String status = json.getString("status"));
}
if (json.has("club")) {
String club = json.getString("club"));
}
You can also check using 'isNull' - Returns true if this object has no
mapping for name or if it has a mapping whose value is NULL.
if (!json.isNull("club"))
String club = json.getString("club"));
you could JSONObject#has, providing the key as input and check if the method returns true or false. You could also
use optString instead of getString:
Returns the value mapped by name if it exists, coercing it if
necessary. Returns the empty string if no such mapping exists
just before read key check it like before read
JSONObject json_obj=new JSONObject(yourjsonstr);
if(!json_obj.isNull("club"))
{
//it's contain value to be read operation
}
else
{
//it's not contain key club or isnull so do this operation here
}
isNull function definition
Returns true if this object has no mapping for name or
if it has a mapping whose value is NULL.
official documentation below link for isNull function
http://developer.android.com/reference/org/json/JSONObject.html#isNull(java.lang.String)
You can use has
public boolean has(String key)
Determine if the JSONObject contains a specific key.
Example
JSONObject JsonObj = new JSONObject(Your_API_STRING); //JSONObject is an unordered collection of name/value pairs
if (JsonObj.has("address")) {
//Checking address Key Present or not
String get_address = JsonObj .getString("address"); // Present Key
}
else {
//Do Your Staff
}
A better way, instead of using a conditional like:
if (json.has("club")) {
String club = json.getString("club"));
}
is to simply use the existing method optString(), like this:
String club = json.optString("club);
the optString("key") method will return an empty String if the key does not exist and won't, therefore, throw you an exception.
Try this:
let json=yourJson
if(json.hasOwnProperty(yourKey)){
value=json[yourKey]
}
Json has a method called containsKey().
You can use it to check if a certain key is contained in the Json set.
File jsonInputFile = new File("jsonFile.json");
InputStream is = new FileInputStream(jsonInputFile);
JsonReader reader = Json.createReader(is);
JsonObject frameObj = reader.readObject();
reader.close();
if frameObj.containsKey("person") {
//Do stuff
}
Try this
if(!jsonObj.isNull("club")){
jsonObj.getString("club");
}
I used hasOwnProperty('club')
var myobj = { "regatta_name":"ProbaRegatta",
"country":"Congo",
"status":"invited"
};
if ( myobj.hasOwnProperty("club"))
// do something with club (will be false with above data)
var data = myobj.club;
if ( myobj.hasOwnProperty("status"))
// do something with the status field. (will be true with above ..)
var data = myobj.status;
works in all current browsers.
You can try this to check wether the key exists or not:
JSONObject object = new JSONObject(jsonfile);
if (object.containskey("key")) {
object.get("key");
//etc. etc.
}
I am just adding another thing, In case you just want to check whether anything is created in JSONObject or not you can use length(), because by default when JSONObject is initialized and no key is inserted, it just has empty braces {} and using has(String key) doesn't make any sense.
So you can directly write if (jsonObject.length() > 0) and do your things.
Happy learning!
You can use the JsonNode#hasNonNull(String fieldName), it mix the has method and the verification if it is a null value or not