change json elements' value in javax.json.JsonArray - java

[
{
"key":"key1",
"value":"key one value",
"description":""
},
{
"key":"key2",
"value":"key two value",
"description":""
},
{
"key":"key3",
"value":"key three value",
"description":""
},
{
"key":"key4",
"value":"key four value",
"description":""
},
{
"key":"key5",
"value":"key five value",
"description":""
}
]
This above is my an example json file I'm working with, I'm putting it into an JsonArray like this
BufferedReader reader = Files.newBufferedReader(file,
Charset.defaultCharset());
JsonReader jsonReader = Json.createReader(reader);
JsonArray array = jsonReader.readArray();
And My issue is I want to access the JsonArray and change the value part of each json element but is unable to do this.
the collection doesn't seem to offer anyways to replace values of any json element.
Do you know anyways I could achieve what I'm set to to do??
PS: also open to suggestions on using an alternative collection, but please educate me on why should I choose said collection.

Since you did not mention which JSON library you are using, you can use element method if you are using json-lib to replace an element
public JSONArray element(int index,
Object value)
If you want to update a specific attribute of the JSONObject element, you can try something like below
array.getJSONObject(0).put("key","new key value")
Please note that I have used hard coded value 0 for demonstration purposes.

Related

How to check if a value exists in a JSON Array for a particular key?

My JSON array file:
[
{
"setName": "set-1",
"testTagName": "Test1",
"methodName": "addCustomer"
},
{
"setName": "set-1",
"testTagName": "Test2",
"methodName": "addAccount"
},
{
"setName": "set-2",
"testTagName": "Test3",
"methodName": "addRole"
}
]
I use Java. I have the above JSON Array in a Gson object.
How do I iterate through this Gson array to check if a particular method name (eg: addRole), exists in the array for the key "methodName" in any of the objects of the JSON array? I am expecting true/false as a result.
I checked the GSON doc - (https://github.com/google/gson/blob/master/gson/src/main/java/com/google/gson/JsonObject.java#L141)
The has method seems to check for the key. I am looking for a method that can iterate through the objects of the array and check if a particular value exists for a specific key.
How can I achieve this?
First you need to deserialize the JSON code to a JsonArray in this way:
JsonArray jsonArr = gson.fromJson(jsonString, JsonArray.class);
After that you can create this method:
public boolean hasValue(JsonArray json, String key, String value) {
for(int i = 0; i < json.size(); i++) { // iterate through the JsonArray
// first I get the 'i' JsonElement as a JsonObject, then I get the key as a string and I compare it with the value
if(json.get(i).getAsJsonObject().get(key).getAsString().equals(value)) return true;
}
return false;
}
Now you can call the method:
hasValue(jsonArr, "methodName", "addRole");
You can get the JSON in a JsonArray and then iterate over the elements while checking for the desired value.
One approach is suggested by #Crih.exe above. If you want to use Streams, you can convert the JsonArray into a stream and use anyMatch to return a boolean value
...
// Stream JsonArray
Stream<JsonElement> stream = StreamSupport.stream(array.spliterator(), true);
// Check for any matching element
boolean result = stream.anyMatch(e -> e.getAsJsonObject()
.get("methodName").getAsString().equals("addRole"));
System.out.println(result);
...

JSON Array key on an index value

I have two json response that are like so:
{
"test": [
{
"value": "abc"
}
]
}
Below is a different response
{
"test2": [
{
"value": "abc"
}
]
}
I have this line of code to grab an object from an array:
httpResponse.getBody()
.getObject()
.getJSONArray("test")
.getJSONObject(0)
.get("value")
.toString();
I have another one which is exactly the same but the DTD it's looking at is different:
httpResponse.getBody()
.getObject()
.getJSONArray("test2")
.getJSONObject(0)
.get("value")
.toString();
Instead of having two lines of code, one for each jsonArray key, I want a dynamic one where it simply selects the initial DTD value and then goes in and retrieve the value. How can this be done?
Can you not just make a method inside your class to help you with this?
String extractValue(HttpResponse httpResponse, String key) {
return httpResponse.getBody()
.getObject()
.getJSONArray(key)
.getJSONObject(0)
.get("value")
.toString();
}

I have to parse JSON response, I have to fetch a child node which is under leet speak (random string which contains symbols, chars, numbers)

I have to parse the JSON response, which has a leet speak, the node which I want to extract is the child of leet speak. am not able to extract the required child form the response.
Ex: following is the JSON structure. from which I want to extract name
"debug": {
"|\"|2()|\\|+3/\\/|)": {
"child1": [],
"child2": {
"Name": "abcd",
"Id": "123"
},
"child3": {
"location": "Delhi"
}
}
}
JSON document is equivalent of the Map, and your leet speak string is a key. That is very bad idea as keys should be easily identifiable. So I would suggest to re-think the structure. May be introduce another level where your leet speak string would be contained as a child under some easily identifiable key. But if you can not do that, you can convert your JSON into Map and then extract ALL keys and then traverse through them and find the one that you need and then get your content by that key
You can create pojo and get that node value
Gson g = new Gson();
Pojo1 p1=g.fromJson(jo.toString(), Pojo1.class);
System.out.println(p1.getDebug().get23().getChild2().getName());

Print JSON with ordered properties

I have JSON with objects in specific order:
{
"Aaa": {
"Langs": {
"Val": [
"Test"
],
"Pro": [
"Test2"
]
}
},
"Bbb": {
"Langs": {
"Val": [
"Test"
],
"Pro": [
"Test2"
]
}
},
"Ddd": {
"Langs": {
"Val": [
"Test"
],
"Pro": [
]
}
},
}
And I would like to add new object Ccc between Bbb and Ddd. I tried to configure object mapper like this:
ObjectMapper mapper = new ObjectMapper()
.enable(SerializationFeature.INDENT_OUTPUT)
.configure(MapperFeature.SORT_PROPERTIES_ALPHABETICALLY, true)
.configure(SerializationFeature.ORDER_MAP_ENTRIES_BY_KEYS, true);
and then print with this code, but Ccc ends at the end of file.
DefaultPrettyPrinter prettyPrinter = new DefaultPrettyPrinter();
prettyPrinter.indentArraysWith(DefaultIndenter.SYSTEM_LINEFEED_INSTANCE);
//Write whole JSON in FILE
String finalJson = mapper.writer(prettyPrinter).writeValueAsString(rootFlores);
finalJson = finalJson.replaceAll("\\[ ]", "[" + System.lineSeparator() + " ]");
finalJson = finalJson.replaceAll("/", "\\\\/");
Files.write(Paths.get("DictionaryFlores_new.json"), Collections.singleton(finalJson));
Is here a way how to print JSON ordered?
Jackson deserialization/serialization does not sort properties
According to this answer, the Jackson SORT_PROPERTIES_ALPHABETICALLY only applies to POJO properties, not Maps. In JSON there is no difference between a Map and an Object, so you need to set the order in the Map first by using a LinkedHashMap or TreeMap
By definition, the keys of an object are unordered. I guess some libraries could offer an option to control the order of the keys when stringifying, but I wouldn't count on it.
When you need a certain order in json, you need to use an array. Of course, then you'd have to move the keys to a property in the child objects, and then the resulting array could only be indexed by number (not by the key). So then you might have to do additional processing to covert the data structure in the JSON to the data structure you really want to process.
Since you seems ready to use regex to update a JSON, I would suggest a "safer" approach. Don't try to create a pattern that would unsure that you don't update a value somewhere.
Iterate you values, on object at the time. Stringify the object and append the String yourself. That way, you are in charge of the object order. Example :
StringBuilder sb = new StringBuilder("{");
List<JsonPOJO> list = new ArrayList<>();
//populate the list
for(JsonPOJO pojo : list){
sb.append(pojo.stringify()).append(",");
}
sb.setLength(sb.length() - 1); //remove the last commma
sb.append("}");
Here, you are only managing the comma between each JSON object, not create the "complex" part about the JSON. And you are in full control of the order of the value in the String representation, it will only depend on the way you populate the List.
Note: sorry for the "draft" code, I don't really have access to my system here so just write this snippet to give you a basic idea on how to "manage" a JSON without having to recreating an API completely.
Note2: I would note suggest this unless this looks really necessary. As you mention in a comment, you are have only the problem with one key where you already have a JSON with 80000 keys, so I guess this is a "bad luck" scenario asking for last resort solution ;)

Using GSON to parse Json into a JAVA Object where the Json Elements may vary

I am trying to parse a JSON .txt file into a JAVA object using GSON. The JSON file has the following structure:
{
"event0" : {
"a" : "abc",
"b" : "def"
},
"event1" : {
"a" : "ghi",
"b" : "jkl",
"c" : "mno"
}
}
I have read the text file into a String called dataStr. I want to use the fromJson method to capture the events into the following JAVA class:
public class Event {
private String a;
private String b;
private String c;
public Event() {}
}
The problem is that the JSON might have one extra field "c" in some of the elements. I want to parse all the events into Event class objects, and for the cases where there is no "c" field, I want to make it null or zero in my object. It is not known beforehand which of the elements will have the "c" field.
Specifically, I was not able to figure out how to handle one extra field in some of the JSON elements. I want to do something along the lines of:
Gson gson = new Gson();
ArrayList<Event> events = gson.fromJson(dataStr, Event.class);
But I am stuck with first, how to iterate over the events in the Json file, and secondly, how to handle some occasional missing fields into the same Event object. I would really appreciate a kick in the right direction. Thank you all.
I am fairly new to JSON parsing, and might have missed something in the following answers:
Using Gson to convert Json into Java Object
Mapping JSON into POJO using Gson
Using gson to parse json to java object
Parse JSON into a java object
How to parse a json file into a java POJO class using GSON
I'm not sure if I understood your question right. As per my understanding, you are trying to convert a json object with an extra field which is not available in the java class. Frankly, I don't understand why you want that or if it's possible to start with. You can have a workaround by converting the json to Map.
Map map = gson.fromJson(jsonString, Map.class);
Gson automatically do that for you.
So, if you have a class "Alpha" with 3 fields ("a", "b" and "c") and you try to work on a json object that has 2 fields with names that match with Alpha's "a" and "b", Gson will fill "a" and "b" with json file's value and "c" will automatically set as null.
So, in your case, if you write this:
ArrayList<Event> events = gson.fromJson(dataStr, Event.class);
And in your json there are events with only 2 fields (that match with any Event's class fields) and events with all fields set, you will get a list of Events with no errors. Maybe you'll get some fields null, but the code will work.
I hope to be helpful! Ask for further informations, if you want to!
EDIT
Note that your json file has not to be .txt but .json instead!
First I believe your JSON should look like this:
{
"events": [
{
"name": "event0",
"a": "abc",
"b": "def"
},
{
"name": "event1",
"a": "abc",
"b": "def",
"c": "mno"
}
]
}
This will need two classes for your model:
public List<Event> events = null;
public class Event {
public String name;
public String a;
public String b;
public String c;
}
And then then with GSON
Events events = gson.fromJson(jsonData, Events.class);
Also I recommend to always use an online validator for JSON so you are sure your JSON structure is correct before coding against it.
https://jsonlint.com/
Or for formate the JSON:
http://jsonprettyprint.com/
Also this website can create the Java classes for you from either a JSON Schema or by using an example file.
http://www.jsonschema2pojo.org/
Try the below code snippet:
Gson gson = new Gson();
ArrayList<Event> events = gson.fromJson(dataStr, new TypeToken<ArrayList<Event>>(){}.getType());
In the source code of Gson has a very clear explain

Categories