how to parse multiple json objects with no name - java

im having some trouble parsing json. I have json in the format of:
{"blah":"blah","blah":"blah"}
{"blah":"blah","blah":"blah"}
{"blah":"blah","blah":"blah"}
Here is the link to the JSON: http://gerrit.aokp.co/query?format=JSON&q=status:merged&age:1d
I cant make this a jsonobject and iterate over it. I currently have it as a string.
Is there a way to iterate over this? there will be over 500.
I tried making it an array by adding square brackets around it, but it didnt work because i needed to divide them with commas. I cant manipulate this by hand because im getting it from the web. So i tried this.
jsonString = jsonString.replaceAll("}(?!,)", "},");
the reason im adding the negative comma is that sometimes i might have a jsonobject inside of of these objects so I only want to add a comma in front of the '}' without commas.
when i do the replaceall i get this error.
Error in fetching or parsing JSON: java.util.regex.PatternSyntaxException: Syntax error in regexp pattern near index 1:
}(?!,)
^
What am I doing wrong or is there an easier way to do this that im looking over?
EDIT:
Oh yes, I need to implement this in java because this is in an android app.

here is an example how you can accomplish what you want using Jackson's ObjectMapper.
ObjectMapper om = new ObjectMapper();
try {
List<Object> obj = om.readValue(yourJsonString, new TypeReference<List<Object>> () { });
} catch (IOException e1) {
e1.printStackTrace();
}
Now you will have a list of each of the individual Objects in your JSON string. To take it a step further you could create a POJO for the Object you are parsing.
Something like:
public class MyObject{
private String project;
private String branch;
}
That is just an exmple, you would need to define a property for each json property.
Then you can turn :
List<Object> obj = om.readValue(yourJsonString, new TypeReference<List<Object>> () { });
Into
List<MyObject> obj = om.readValue(yourJsonString, new TypeReference<List<MyObject>> () { });
Hope this helps!

From the link you posted, it looks like there are newlines between objects (and only between objects). If that's right, I'd approach it like this:
String[] items = dataFromWeb.split("\n");
String asJSONArrayString = Arrays.toString(items);
JSONArray jsonArray = new JSONArray(asJSONArrayString);
This splits the data at newlines, then joins it together with commas between elements and brackets around the whole thing.

JSONObject jObject = null;
mJsonString = downloadFileFromInternet(urlString);
jObject = new JSONObject(mJsonString);
This will get you json object.
This is the way to get json array from json object:
JSONArray jsonImageArray = jObject.getJSONArray("your string");

Related

Why can't read a .json?

I want to read a .json using library json-simple, my json file is:
{
"Subjects": {
"subject1": "MIS",
"subject2": "DBMS",
"subject3": "UML"
}
}
And my code is:
import java.io.*;
import java.util.*;
import org.json.simple.*;
import org.json.simple.parser.*;
public class JSONReadFromTheFileTest {
public static void main(String[] args) {
JSONParser parser = new JSONParser();
try{
Object obj = parser.parse(new FileReader("/Users/User/Desktop/course.json"));
JSONObject jsonObject = (JSONObject)obj;
JSONArray subjects = (JSONArray)jsonObject.get("Subjects");
Iterator iterator = subjects.iterator();
while (iterator.hasNext()) {
System.out.println(iterator.next());
}
}catch(Exception e){
e.printStackTrace();
}
}
}
I would like to get in console:
subject1: MIS
subject2: DBMS
subject3: UML
But instead of that, I just get the next error:
java.lang.ClassCastException: org.json.simple.JSONObject cannot be cast to org.json.simple.JSONArray
at project.Main(Main.java:11)
But I searched in internet, and I found that if I change sintaxys of the .json in the next way:
{
"Subjects": [
"subject1: MIS",
"subject2: DBMS",
"subject3: UML"
]
}
I get in console what I want:
subject1: MIS
subject2: DBMS
subject3: UML
And you may think my problem is solved, but not yet, because I want to read the json file in the first way.
I hope someone can help me. Thanks in advance.
The first example shows a Subjects key containing a single object with several properties (subject1, subject2, etc).
Consider those properties like the member variables of a class.
In order to let you better understand if the class is Person those variables could be name and surname.
What you try to achieve in your code is extracting a JSONArray from the JSON you are providing.
Going back to the example for Person the array could be - sorry for the silly example - an Array containing phone numbers.
So what you are expecting is that one of the member properties of the class is an array.
This is not possible in the first example because the first example does not contain a json array.
This line extracts the whole json object:
JSONObject jsonObject = (JSONObject)obj;
This one tries to get an array out but no array is there in the first example:
JSONArray subjects = (JSONArray)jsonObject.get("Subjects");
Square brackets represent an array, which you've casted the getter into.
The second json shown is more correct for the code you've written, however, arrays cannot hold key-value pairs, so that's why you've made second JSON have an array of strings
To parse the first file, you'd need to start with
JSONObject subjects = (JSONObject)jsonObject.get("Subjects")
If you have full control over the file, I'd suggest just storing ["MIS", "DBMS", "UML"] then write a simple loop
for (int i = 0; i < jsonArray.length; i++) {
System.out.printf("subject%d: %s%n", i+1, jsonArray.get(i));
}
To make your code work with your json, you should not use JSONArray for "Subjects" but instead JSONObject. The reason is that [ and ] indicates beginning and ending of array element in json which is represented by JSONArray. If you have { and } element then its object represented by JSONObject. zz So replace this:
JSONArray subjects = (JSONArray)jsonObject.get("Subjects");
Iterator iterator = subjects.iterator();
while (iterator.hasNext()) {
System.out.println(iterator.next());
}
with following (I have not compiled it):
JSONObject subjects = (JSONObject)jsonObject.get("Subjects");
for(Iterator iterator = subjects.keySet().iterator(); iterator.hasNext();) {
String key = (String) iterator.next();
System.out.println(key + ": " + subjects.get(key));
}
As others mentioned you should replace JSONArray with JSONObject in your code. But I would suggest to switch to different JSON library all together. I would recommend to use Json-Jackson library. Also, there is another library that provides a wrapper over Json-Jackson library. It has JsonUtils class that can simply parse your JSON in one line. Just read first your Json from file into a String jsonString and do this.
Map<String, Object> myMap = JsonUtils.readObjectFromJsonString(jsonString, Map.class);
You will get a Map with one key "Subjects" that will have a value of a Map with your 3 keys and values:
subject1: MIS
subject2: DBMS
subject3: UML
Here is the JavaDoc for the JsonUtils class. The library could be found as Maven artifact and on Github (including source code and Javadoc).

Selecting a subset of JSON properties and values using JSONPath

Given a JSON like:
{
"a":1,
"b":2,
"c":3,
"d":4,
"e":5
}
How can I select out b, d and e to get the following JSON?
{
"b":2,
"d":4,
"e":5
}
I want a JSON object and NOT only 2, 4 and 5 values?
This is what I'm trying with and failing:
$.[b,d,e]
JSONPath is not suitable for what you are trying to achieve: JSONPath is designed to select values and not key-value pairs. What you want could be achieved with Jackson or any JSON parser for Java.
If you want to go for Jackson here's the code that will do the trick:
String json = "{\"a\":1,\"b\":2,\"c\":3,\"d\":4,\"e\":5}";
ObjectMapper mapper = new ObjectMapper();
JsonNode tree = mapper.readTree(json);
ObjectNode node = mapper.createObjectNode();
node.set("b", tree.get("b"));
node.set("d", tree.get("d"));
node.set("e", tree.get("e"));
String result = mapper.writerWithDefaultPrettyPrinter().writeValueAsString(node);
Elements must be in single quotes.
$.['b','d','e']
Works fine for JsonPath from com.jayway.jsonpath:json-path:2.4.0
Your json path is correct, while json it self is not. It should be:
{
"a":1,
"b":2,
"c":3,
"d":4,
"e":5
}
BTW there is good online testing resources for these purposes: http://jsonpath.com/
You need to modify your JSON to (as said by Andremoniy)
{
"a":1,
"b":2,
"c":3,
"d":4,
"e":5
}
and to select b,d,e use this
$.b,d,e

Gson - Merge multiple JSONs objects into one JSON

I have a case where I need to merge multiple JSONs objects into one JSON.
A single response looks like this:
{"name":"MyName"}
Multiple merged JSON looks like this:
["{\"name\":\"name\"}","{\"name\":\"MyName\"}"]
The problem here is that the child JSONs that I want to include can come either from a Java object or are available as String itself.
MyRequest request = new MyRequest();
request.setName("name");
String singleJson = new Gson().toJson(request);
String fromSomePlaceElse = "{\"name\":\"MyName\"}";;
List<String> list = Lists.newArrayList(singleJson,fromSomePlaceElse);
System.out.println(new Gson().toJson(list));
The above gives me the following output:
["{\"name\":\"name\"}","{\"name\":\"MyName\"}"]
instead of:
[{"name":"MyName"}, {"name":"MyName"}]
I don't want to parse the already existing JSON and do the following:
List<MyRequest> list2 = Lists.newArrayList(request, new Gson().fromJson(fromSomePlaceElse, MyRequest.class));
System.out.println(new Gson().toJson(list2));
Can this be done using Gson ?
Just print it.
List<String> list = Lists.newArrayList(singleJson,fromSomePlaceElse);
System.out.println(list);
Then you can get
[{"name":"name"}, {"name":"MyName"}]
if you want json in form of string,you can directly use ---
new Gson().toJson(yourList, new TypeToken<List<JsonObject>>(){}.getType())
Try the given library to merge any amount of JSON-objects at once. The result can be returned as String or JsonObject (GSON). Please reference the code in this answer.

converting string into json object

I am getting a string like String s = "abc:xyz". Is there any direct method to convert it into JsonObject having abc as key and xyz as value.
I know there a way by converting string into String s = "{\"abc\":\"xyz\"}" and then I can use JSONObject j =(JSONObject) new JSONParser().parse(s); But I have too large list of string to convert into json object. So i don't want to preprocess to convert into quoted string.
And one more way to split string on : . But i want to know any parser method which convert directly into object. So that i does not have to split. It is also a kind of preprocessing.
If there is any way to convert by passing string to method. please suggest.
It sounds like you just want:
String[] bits = s.split(":");
if (bits.length() != 2) {
// Throw an exception or whatever you want
}
JSONObject json = new JSONObject();
json.put(bits[0], bits[1]);
Split the string on :; use the parts to make your object.

How can i sort Nested JSON Array?

How can i sort Nested JSON Array? Like for a JSON below...
{
"id":"rtmc05.lax.someabc.net",
"name":"rtmc05.lax.someabc.net",
"tenants":[{
"id":"rtmc",
"name":"rtmc"
},{
"id":"hrs",
"name":"hrs"
},{
"id":"amotelbe1",
"name":"amotelbe"
},{
"id":"cds",
"name":"cds"
},{
"id":"idx-server",
"name":"idx-server",
"tenants":[{
"id":"amotelbe",
"name":"amotelbe",
"tenants":[{
"id":"amotelui",
"name":"amotelui"
}]
}]
}]
}
There's a few parts implicit to your question, and it's not clear where you're having trouble:
How do you take a JSON string and make usable Java objects out of it. (I'm assuming Java, not JavaScript, since you've tagged your question with "java".)
How do you sort those objects after they're made?
How do you handle sorting the nested parts? (In your example, "idx-server" has sub-tenants.)
Not sure exactly which parts of this you're having trouble with, so here's some notes for all three.
Part 1: Getting Java objects
I agree with the other guy that Jackson is a good JSON parser to use. Here's a couple lines of code you could use to parse some JSON:
String jsonString = "..."; // Load this in whatever way makes sense for you
ObjectMapper mapper = new ObjectMapper();
Map<String,Object> parsedJson = mapper.readValue(jsonString, Map.class);
If your JSON string is really huge, then there are other readValue overloads that you can use to avoid reading the whole String into memory.
Part 2: Sorting Java objects
Once you've got the parsed JSON, sorting is just a matter of calling Collections.sort(...), passing in the tenants array. Plus you'll need to write a Comparator that defines the ordering that you want. For example, here's a comparator that sorts by name:
public class NameComparator implements Comparator<Map<String,Object>> {
public int compare(Map<String,Object> o1, Map<String,Object> o2) {
String name1 = (String) o1.get("name");
String name2 = (String) o2.get("name");
return name1.compareTo(name2);
}
}
Then you get the tenants array out (Jackson makes them into ArrayList objects) and call Collections.sort(...). For example,
List<Map<String,Object>> tenants =
(List<Map<String,Object>>) parsedJson.get("tenants");
Collections.sort(tenants, new NameComparator());
Part 3: Handling the nesting
The clearest way to do this is to add some extra code to walk through your JSON looking for any object with a tenants array, and sort it. For example, here's a recursive function that should do it:
public static void recursiveSortTenants(Map<String,Object> jsonObject) {
List<Map<String,Object>> tenants =
(List<Map<String,Object>>) jsonObject.get("tenants");
if (tenants != null) {
Collections.sort(tenants, new NameComparator());
// For each tenant, see if it has sub-tenants. If so,
// call this function again to sort them.
for (Map<String,Object> tenant : tenants) {
if (tenants.containsKey("tenants")) {
recursiveSortTenants(tenant);
}
}
}
}
Hope this helps!
Parse it into (javascript) objects then write a sort function that sorts an array of such javascript objects.
Deserialize it to POJOs(with Gson or Jackson), and write a Comparator for that POJOs.

Categories

Resources