1

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.

momo
  • 21,233
  • 8
  • 39
  • 38
user979511
  • 11
  • 1
  • 1
  • 2

3 Answers3

1

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");    
    }
}
momo
  • 21,233
  • 8
  • 39
  • 38
  • Thanks Momo for your suggestion. I tried it and I get this error: Exception in thread "main" java.text.ParseException: "A JSONArray must start with '[' at character 1 of.." My json file starts with { and ends with }. There must be a way to convert this into an array.... – user979511 Oct 05 '11 at 02:38
  • That means the input is not correct. I get the JSON input via URL like http://twitter.com/statuses/user_timeline/109531911.json and tested it before I post the answer. Can you copy and paste some of the input from your input/twitter-feed.json? It should start with the character '[' – momo Oct 05 '11 at 02:44
  • Also, can I get the source of your twitter-feed.json? Maybe I am getting from different source than yours which has different JSON feed – momo Oct 05 '11 at 02:47
  • If I explicitly add "[" and "]" to the start and end of my json input file, I am able to get the output nicely. The input json file has many records that begin and end with { and }. And, the argument to new JSONArray needs a "String". The error points to "JSONArray jsonArray = new JSONArray(jsonString.toString());" There must be a simple way to do this.... – user979511 Oct 05 '11 at 02:54
  • I saw your comment just now. I am getting my json file from cURL. On a linux terminal, I do: Mac@~ $ curl https://stream.twitter.com/1/statuses/sample.json?delimited=length -uttt:aaa123 > ~/twitter-feed.json. Json files got this way doesn't have a leading and trailing square brackets. – user979511 Oct 05 '11 at 02:57
  • The error that you mentioned in your first comment is because the JSON is not in correct format and it has a syntax error which throw the ParseException. JSON Array starts with "[" and ends with "]" which is why it would work if you manually add them. Are you sure you are getting the entire feed from Twitter? The feed that I am getting has "[" and "]". Every JSON Object start with "{" and ends with "}". Each member of the array is a JSON Object. The argument is a string already (via toString()) function. – momo Oct 05 '11 at 02:59
  • NOTE that I had heavily truncated my json file so that it has only one record. I enclosed that record with sqaure brackets and it works. Also, the twitter feeds I get through Curl has a number that precedes each record. So, there are 2 interesting things there: A) - no leading and trailing square brackets. B) each record begins with a integer (before even the record begins with "{". I do not yet know how to attach a small file here...else I would. – user979511 Oct 05 '11 at 03:04
  • Without the square brackets, that's not the right syntax for JSON Array. The sample URL you are using have syntax error for the JSON Array. I got my feed directly from twitter website. You could try pulling up any feed simply by replacing 109531911.json with the username twitter.com/statuses/user_timeline/109531911.json. For example http://twitter.com/statuses/user_timeline/kingjames.json would pull the statuses from LeBron James twitter. – momo Oct 05 '11 at 03:07
  • My previous comment had an error. This is what I do to get twitter 1% twitter status updates ===> Mac@~ $ curl https://stream.twitter.com/1/statuses/sample.json?delimited=length -uttt:aaa123 > ~/twitter-feed.json. Thanks for your suggestion. I shall try that now. – user979511 Oct 05 '11 at 03:08
  • Can't get to the sample, I got UNAUTHORIZED page instead. Looks like that the sample is not in right syntax (for example there shouldn't be an integer for each record). You might want to understand the JSON Specs better by reading [this link](http://www.json.org/) – momo Oct 05 '11 at 03:14
  • Since I am new to both Java and JSON, I learning both right now. Also, trying to learn Twitter APIs...to understand what they mean. I totally appreciate your helpful comments and links. Are you sure you are doing https://....? I can do it from here. Just checked. Mac@~ $ curl https://stream.twitter.com/1/statuses/sample.json?delimited=length -uttt:aaa123 > ~/twitter-feed.json % Total % Received % Xferd Average Speed Time Time Time Current Dload Upload Total Spent Left Speed 108 1296 108 1296 0 0 2114 0 --:--:-- --:--:-- --:--:-- 28173 – user979511 Oct 05 '11 at 03:26
  • Sorry for coming back late, I was sleeping :) I have explained based on your info which now should work. Stream API doesn't provide valid JSON as a whole but does provide valid one per delimited value. The integer that you get is because you specify delimited=length. It's easier to just use newline since Java has a way to separate newline as outline by the revised answer. – momo Oct 05 '11 at 09:50
0

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);
Utsav Gupta
  • 3,785
  • 5
  • 30
  • 52
0

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

Community
  • 1
  • 1
tolitius
  • 22,149
  • 6
  • 70
  • 81