How to extract multiple JSON Objects into String - java

I am reading multiple JSONObject from a file and converting into a string using StringBuilder.
These are the JSON Objects.
{"Lng":"-1.5908601","Lat":"53.7987816"}
{"Lng":"-2.5608601","Lat":"54.7987816"}
{"Lng":"-3.5608601","Lat":"55.7987816"}
{"Lng":"-4.5608601","Lat":"56.7987816"}
{"Lng":"-5.560837","Lat":"57.7987816"}
{"Lng":"-6.5608294","Lat":"58.7987772"}
{"Lng":"-7.5608506","Lat":"59.7987823"}
How to convert into a string?
Actual code is:-
BufferedReader reader = new BufferedReader(new InputStreamReader(contents.getInputStream()));
StringBuilder builder = new StringBuilder();
String line;
try {
while ((line = reader.readLine()) != null) {
builder.append(line);
}
}
catch(IOException e)
{
msg.Log(e.toString());
}
String contentsAsString = builder.toString();
//msg.Log(contentsAsString);
I tried this code
JSONObject json = new JSONObject(contentsAsString);
Iterator<String> iter = json.keys();
while(iter.hasNext())
{
String key = iter.next();
try{
Object value = json.get(key);
msg.Log("Value :- "+ value);
}catch(JSONException e)
{
//error
}
}
It just gives first object. How to loop them?

try this and see how it works for you,
BufferedReader in
= new BufferedReader(new FileReader("foo.in"));
ArrayList<JSONObject> contentsAsJsonObjects = new ArrayList<JSONObject>();
while(true)
{
String str = in.readLine();
if(str==null)break;
contentsAsJsonObjects.add(new JSONObject(str));
}
for(int i=0; i<contentsAsJsonObjects.size(); i++)
{
JSONObject json = contentsAsJsonObjects.get(i);
String lat = json.getString("Lat");
String lng = json.getString("Lng");
Log.i("TAG", lat + lng)
}

What you do is you are loading multiple JSON objects into one JSON object. This does not make sense -- it is logical that only the first object is parsed, the parser does not expect anything after the first }. Since you want to loop over the loaded objects, you should load those into a JSON array.
If you can edit the input file, convert it to the array by adding braces and commas
[
{},
{}
]
If you cannot, append the braces to the beginning of the StringBuilder and append comma to each loaded line. Consider additional condition to eliminate exceptions caused by inpropper input file.
Finally you can create JSON array from string and loop over it with this code
JSONArray array = new JSONArray(contentsAsString);
for (int i = 0; i < array.length(); ++i) {
JSONObject object = array.getJSONObject(i);
}

Related

Parse JSON response into a List

I'm trying to parse a JSON response
it's structure is:
{
"metric": {
"name": "string",
"values": [
"string"
]
}
}
My code so far:
StringBuilder sb = new StringBuilder();
String line;
BufferedReader reader = new BufferedReader(new InputStreamReader(conn.getInputStream()));
while ((line = reader.readLine()) != null) {
sb.append(line);
}
wr.close();
reader.close();
JSONObject json = new JSONObject(sb.toString());
JSONArray jsonArray = json.getJSONArray("values");
List<String> list = new ArrayList<>();
String errorPercent ="";
for(int i = 0 ; i < json.length() ; i++){
errorPercent = jsonArray.getJSONArray(i).getString(i);
list.add(errorPercent);
}
The output I'm getting is saying that "values " was not found,
am I misunderstanding the structure of the JSON response?
Edit
It appears the structure I was given on the site I'm receiving the response from is not correct. it appears to be a more complicated structure
I have modified my code accordingly:
JSONObject json = new JSONObject(sb.toString());
JSONObject metricsData = json.getJSONObject("metric_data");
JSONArray metrics = metricsData.getJSONArray("metrics");
System.out.println(metrics.toString());
The print out is as follows:
[{"timeslices":[{"values":{"max_response_time":0,"calls_per_minute":0,"average_be_response_time":0,"error_percentage":0,"min_response_time":0,"requests_per_minute":0,"average_network_time":0,"average_response_time":0,"average_fe_response_time":0,"total_app_time":0,"call_count":0,"fe_time_percentage":0,"total_network_time":0,"total_fe_time":0,"network_time_percentage":0},"from":"2015-10-25T22:39:00+00:00","to":"2015-10-25T22:40:00+00:00"},{"values":{"max_response_time":0,"calls_per_minute":0,"average_be_response_time":0,"error_percentage":0,"min_response_time":0,"requests_per_minute":0,"average_network_time":0,"average_response_time":0,"average_fe_response_time":0,"total_app_time":0,"call_count":0,"fe_time_percentage":0,"total_network_time":0,"total_fe_time":0,"network_time_percentage":0},
There appears to be another array within the array: "timeslices" is that right? how do I get at that array?
I unsuccessfully tried:
JSONArray timeslices = metrics.getJSONArray("timeslices");
values is a field inside metric.
You'd need to first get the metric object, then look inside that for values.
JSONObject metric = json.getJSONObject("metric");
JSONArray jsonArray = metric.getJSONArray("values");

Parse HTTP JSONObject response in java

From the endpoint "test" I am returning a JSONObject:
#POST("/test")
#PermitAll
public JSONObject test(String name) {
JSONObject jsonval=new JSONObject();
json.put("key1",true);
json.put("key2","test");
return json;
}
in the method that checks the returned value I want to search for value of "key1".
BufferedReader in = new BufferedReader(new InputStreamReader(con.getInputStream()));
String json = null;
String res = "";
while ((res = in.readLine()) != null) {
json += res + "\n";
}
in.close();
if (jsonData has key1 with value true){
//do sth
}
else{
//do sth else
}
How can I parse the returned JSONObject?
Have you tried constructing the JSONObject from its string representation (see http://www.json.org/javadoc/org/json/JSONObject.html):
JSONObject result = new JSONObject(json)
where json is the string you've read from the InputStream
Note: you might have to strip the last new line char or even omit new lines altogether

OutOfMemoryError in StringBuilder and HashSet

I have a JSON file (.json) in Amazon S3. I need to read it and create a new field called Hash_index for each JsonObject. The file is very big, so I am using a GSON library to avoid my OutOfMemoryError in reading the file. Below is my code. Please note that I am using GSON
//Create the Hashed JSON
public void createHash() throws IOException
{
System.out.println("Hash Creation Started");
strBuffer = new StringBuffer("");
try
{
//List all the Buckets
List<Bucket>buckets = s3.listBuckets();
for(int i=0;i<buckets.size();i++)
{
System.out.println("- "+(buckets.get(i)).getName());
}
//Downloading the Object
System.out.println("Downloading Object");
S3Object s3Object = s3.getObject(new GetObjectRequest(inputBucket, inputFile));
System.out.println("Content-Type: " + s3Object.getObjectMetadata().getContentType());
//Read the JSON File
/*BufferedReader reader = new BufferedReader(new InputStreamReader(s3Object.getObjectContent()));
while (true) {
String line = reader.readLine();
if (line == null) break;
// System.out.println(" " + line);
strBuffer.append(line);
}*/
// JSONTokener jTokener = new JSONTokener(new BufferedReader(new InputStreamReader(s3Object.getObjectContent())));
// jsonArray = new JSONArray(jTokener);
JsonReader reader = new JsonReader( new BufferedReader(new InputStreamReader(s3Object.getObjectContent())) );
reader.beginArray();
int gsonVal = 0;
while (reader.hasNext()) {
JsonParser _parser = new JsonParser();
JsonElement jsonElement = _parser.parse(reader);
JsonObject jsonObject1 = jsonElement.getAsJsonObject();
//Do something
StringBuffer hashIndex = new StringBuffer("");
//Add Title and Body Together to the list
String titleAndBodyContainer = jsonObject1.get("title")+" "+jsonObject1.get("body");
//Remove full stops and commas
titleAndBodyContainer = titleAndBodyContainer.replaceAll("\\.(?=\\s|$)", " ");
titleAndBodyContainer = titleAndBodyContainer.replaceAll(",", " ");
titleAndBodyContainer = titleAndBodyContainer.toLowerCase();
//Create a word list without duplicated words
StringBuilder result = new StringBuilder();
HashSet<String> set = new HashSet<String>();
for(String s : titleAndBodyContainer.split(" ")) {
if (!set.contains(s)) {
result.append(s);
result.append(" ");
set.add(s);
}
}
//System.out.println(result.toString());
//Re-Arranging everything into Alphabetic Order
String testString = "acarpous barnyard gleet diabolize acarus creosol eaten gleet absorbance";
//String testHash = "057 1$k 983 5*1 058 52j 6!v 983 03z";
String[]finalWordHolder = (result.toString()).split(" ");
Arrays.sort(finalWordHolder);
//Navigate through text and create the Hash
for(int arrayCount=0;arrayCount<finalWordHolder.length;arrayCount++)
{
if(wordMap.containsKey(finalWordHolder[arrayCount]))
{
hashIndex.append((String)wordMap.get(finalWordHolder[arrayCount]));
}
}
//System.out.println(hashIndex.toString().trim());
jsonObject1.addProperty("hash_index", hashIndex.toString().trim());
jsonObject1.addProperty("primary_key", gsonVal);
jsonObjectHolder.add(jsonObject1); //Add the JSON Object to the JSON collection
jsonHashHolder.add(hashIndex.toString().trim());
System.out.println("Primary Key: "+jsonObject1.get("primary_key"));
//System.out.println(Arrays.toString(finalWordHolder));
//System.out.println("- "+hashIndex.toString());
//break;
gsonVal++;
}
System.out.println("Hash Creation Completed");
}
catch(Exception e)
{
e.printStackTrace();
}
}
When this code is executed, I got the following error
Exception in thread "main" java.lang.OutOfMemoryError: Java heap space
at java.util.Arrays.copyOf(Arrays.java:2894)
at java.lang.AbstractStringBuilder.expandCapacity(AbstractStringBuilder.java:117)
at java.lang.AbstractStringBuilder.append(AbstractStringBuilder.java:407)
at java.lang.StringBuilder.append(StringBuilder.java:136)
at HashCreator.createHash(HashCreator.java:252)
at HashCreator.<init>(HashCreator.java:66)
at Main.main(Main.java:9)
[root#ip-172-31-45-123 JarFiles]#
Line number 252 is - result.append(s);. It is Inside the HashSet loop.
Previously, it generated OutOfMemoryError in line number 254. Line number 254 is - set.add(s); it is also inside the HashSet array.
My Json files are really really big. Gigabytes and Terabytes. I have no idea about how to avoid the above issue.
Use a streaming JSON library like Jackson.
Read in a some JSON, add the hash, and write them out.
Then read in some more, process them, and write them out.
Keep going until you have processed all the objects.
http://wiki.fasterxml.com/JacksonInFiveMinutes#Streaming_API_Example
(See also this StackOverflow post: Is there a streaming API for JSON?)

Java JSON array

I have output from url as following:
["HANK-TPSSL4-app","acgeneral-app","acgeneral-web","achalf-app","acproduct-app"]
My Java code to get each object from this array:
BufferedReader in = new BufferedReader(new InputStreamReader((HttpURLConnection) alertHandleUrl.openConnection().getInputStream()));
String output;
while ((output = in.readLine()) != null) {
JSONArray array = new JSONArray(output);
for (int i =0; i < array.length(); i++)
JSONObject row = array.getJSONObject(i);
System.out.println(row);
}
The error I am getting is
Exception in thread "main" org.json.JSONException: JSONArray[0] is not a JSONObject.
at org.json.JSONArray.getJSONObject(JSONArray.java:330)
at com.ebay.sherlock.calc.AutoConfigFunc.main(AutoConfigFunc.java:70)
Can someone help me? Thanks in advance
Yes, this output is a simple String array not a JSON object. You need to trim the leading and trailing braces and then split the string by comma ","

Convert a .json file to a JSONArray

I used cURL to get some twitter feeds in the form of a json file ("twitter-feed.json"). I want to convert this json file to a JSONArray object. How do I do it?
I am new to Java and json. Your suggestions are most welcome.
FileInputStream infile = new FileInputStream("input/twitter-feed.json");
// parse JSON
JSONArray jsonArray = new JSONArray(string);
// use
for (int i = 0; i < jsonArray.length(); i++) {
JSONObject jsonObject = jsonArray.getJSONObject(i);
System.out.println(jsonObject.getString("id"));
System.out.println(jsonObject.getString("text"));
System.out.println(jsonObject.getString("created_at"));
}
Thanks,
PD.
You need to read the file first, convert it to String then feed it to the JSONArray (I am assuming that you are using the JSON-Java Project. The code below illustrates how to read the file and set it to JSONArray
// read the source file, source comes from streaming API delimited by newline
// done by curl https://stream.twitter.com/1/statuses/sample.json?delimited=newline -utwitterUsername:twitterPasswd
// > /Projects/StackOverflow/src/so7655570/twitter.json
FileReader f = new FileReader("/Projects/StackOverflow/src/so7655570/twitter.json");
BufferedReader br = new BufferedReader(f);
ArrayList jsonObjectArray = new ArrayList();
String currentJSONString = "";
// read the file, since I ask for newline separation, it's easier for BufferedReader
// to separate each String
while( (currentJSONString = br.readLine()) != null ) {
// create new JSONObject
JSONObject currentObject = new JSONObject(currentJSONString);
// there are more than one way to do this, right now what I am doing is adding
// each JSONObject to an ArrayList
jsonObjectArray.add(currentObject);
}
for (int i = 0; i < jsonObjectArray.size(); i++) {
JSONObject jsonObject = jsonObjectArray.get(i);
// check if it has valid ID as delete won't have one
// sample of JSON for delete :
// {"delete":{"status":{"user_id_str":"50269460","id_str":"121202089660661760","id":121202089660661760,"user_id":50269460}}}
if(jsonObject.has("id")) {
System.out.println(jsonObject.getInt("id"));
System.out.println(jsonObject.getString("text"));
System.out.println(jsonObject.getString("created_at") + "\n");
}
}
Steps explanation :
Stream API does not provide valid JSON as a whole but rather a valid one specified by the delimited field. Which is why, you can't just parse the entire result as is.
In order to parse the JSON, I use the delimited to use newline since BufferedReader has a method readLine that we could directly use to get each JSONObject
Once I get each valid JSON from each line, I create JSONObject and add it to the ArrayList
I then iterate each JSONObject in the ArrayList and print out the result. Note that if you want to use the result immediately and don't have the need to use it later, you can do the processing itself in while loop without storing them in the ArrayList which change the code to:
// read the source file, source comes from streaming API
// done by curl https://stream.twitter.com/1/statuses/sample.json?delimited=newline -utwitterUsername:twitterPasswd
// > /Projects/StackOverflow/src/so7655570/twitter.json
FileReader f = new FileReader("/Projects/StackOverflow/src/so7655570/twitter.json");
BufferedReader br = new BufferedReader(f);
String currentJSONString = "";
// read the file, since I ask for newline separation, it's easier for BufferedReader
// to separate each String
while( (currentJSONString = br.readLine()) != null ) {
// create new JSONObject
JSONObject currentObject = new JSONObject(currentJSONString);
// check if it has valid ID as delete status won't have one
if(currentObject.has("id")) {
System.out.println(currentObject.getInt("id"));
System.out.println(currentObject.getString("text"));
System.out.println(currentObject.getString("created_at") + "\n");
}
}
You may try Gson:
For just arrays you can use:
Gson gson = new Gson();
//(Deserialization)
int[] ints2 = gson.fromJson("[1,2,3,4,5]", int[].class);
To deserialize an array of objects, you can just do:
Container container = new Gson().fromJson(json, Container.class);
As shown here
Use ObjectMapper Class from jackson library like this :
//JSON from file to Object
Staff obj = mapper.readValue(new File("c:\\file.json"), Staff.class);
//JSON from URL to Object
Staff obj = mapper.readValue(new URL("http://mkyong.com/api/staff.json"), Staff.class);
//JSON from String to Object
Staff obj = mapper.readValue(jsonInString, Staff.class);

Categories

Resources