Forgive me if this is too broad a question, shout at me if so.
I'm retrieving data from a rest API in java. I then want to be able to search through the JSON data for a particular key-value pair. As far as I'm aware, a JSONObject from org.json is a good way of doing this. So far I have:
URL url = new URL("api string");
HttpURLConnection connnection = (HttpURLConnection)url.openConnection();
BufferedReader br = new BufferedReader(new InputStreamReader(connection.getInputStream()));
String input;
StringBuffer sb = new StringBuffer();
while ((input = br.readLine()) != null){
sb.append(input);
}
br.close();
returnedJSON = new JSONObject(sb.toString());
So fairly standard get request code.
Firstly, I can't tell if I need a JSONObject or JSONArray. Everything I've researched uses JSONObjects for writing to from an API, but I'll be retrieving JSON that is in the following form:
[ { x:y, a:b, foo:bar }, { x:y, a:b, foo:bar }, ... , ... ]
So there's multiple JSON "entries" if that makes sense, and I'd like to look through the entire JSON string to see if two pieces of data exist in the same record. Ex: Is the value of 'foo' the expected value for the record where the value of 'x' is 'y'?
I'm unclear on how to proceed here as it is the first time I've properly used JSON.
First of all you should use JSONArray instead of JSONObject because it's a array of object that you receive from API Response..
Now iterate this array and grab each of the JSONObject , which actually received in a form of HashMap (key-value pair).
Now you can get each element of JSONObject by accessing their keys..
Related
I did a http client and I'm getting a response. I am using a JSONObject to parse the data and when I execute the code below it prints out all of the JSON just fine
HttpResponse response = httpclient.execute(httppost);
HttpEntity entity = response.getEntity();
if(entity!=null){
try(InputStream instream = entity.getContent()) {
String responseString = readInputStream(instream);
JSONObject job = new JSONObject(responseString);
statusLabel.setText("Command Result: " + job.toString());
Here is the readInputSream function:
static private String readInputStream(InputStream inputStream) throws IOException {
BufferedReader reader = new BufferedReader(new InputStreamReader(
inputStream, "UTF-8"));
String tmp;
StringBuilder sb = new StringBuilder();
while ((tmp = reader.readLine()) != null) {
sb.append(tmp).append("\n");
}
if (sb.length() > 0 && sb.charAt(sb.length() - 1) == '\n') {
sb.setLength(sb.length() - 1);
}
reader.close();
return sb.toString();
}
If I change it from job.toString() to:
statusLabel.setText("Command Result: " + job.get("result"));
it prints a 1 which is correct, it works all the way up to my_list. I'm not sure how to parse the list. I put a snippet of the response below. Ive tried "my_list", "my_list[]", my_list[0]" which none have worked. I get JSONObject "blank" not found
{"result":1, "ver":1,"total":2,"catch":true,"my_list":[{"id":3,"mid":0,"format":3,"user":4,"property":1,"type":0,"title":"hello","start":146,"end":1464,"hid":3,"bid":1,"reason":1,"time":0,"creator":"1","hello":0,"my":0,"year":"0","ggg":614,"name":"","ch":"0","attr":0,"type":1,"vtype":1,"tm_log": {"fr":4,"action":0,"vr":"82","started":1,"av_ended":2,"tr":1}}
The element you trying to retrieve is parsed into a JSONArray, not a JSONObject. Try:
JSONArray my_list = job.getJSONArray("my_list");
Assuming that you are using json parser project JSON-java to parse your JSON you need to retrieve a JSONArray instance - this is how arrays are storred in JSONObject. so do the following: JSONArray my_list = job.getJSONArray("my_list"); and then use methods of JSONArray class to access your array. The Javadoc to JSON-java package can be found here: http://stleary.github.io/JSON-java/index.html. Also note that JSON-java is very simple and easy to use JSON parser project but it is not very efficient for any serious project. Common recommendation for commercial use is Jackson JSON Processor which is one of the fastest and powerful JSON parsers. Here are some links to read about it: https://github.com/FasterXML/jackson, http://wiki.fasterxml.com/JacksonHome
I have json response from a url like following
{
"data": [
{
"fav": "",
"name": "u0637u0627u062cu0646 u0627u0644u062fu062cu0627u062c u0627u0644u0633u0648u064au0633u0631u064a u0627u0644u062bu0627u0646u064a",
"imageurl": "http://images.media.com/userphotos/250x250/26847.jpg",
"description": "u0633u062eu0646 u0627u0644u0641u0631u0646 <BR> u0625u0644u0649 350 u062fu0631u062cu0629 u0641u0647u0631u0646u0647u0627u064au062a (175 u062fu0631u062cu0629 u0645u0626u0648u064au0629) . <BR> u062au0631u062au064au0628 u0627u0644u062fu062cu0627u062c u0641u064a u0645u062fu0647u0648u0646 12 u00d7 8 u00d7 2 u0635u062du0646 u0627u0644u062eu0628u0632 . ",
"details": "<BR> 6 u062cu0644u062f u060c u0627u0644u062bu062fu064a u0627u0644u062fu062cu0627u062c u0627u0644u062eu0627u0644u064au0629 u0645u0646 u0627u0644u0639u0638u0645 <BR> 6 u0634u0631u0627u0626u062d u0627u0644u062cu0628u0646 u0627u0644u0633u0648u064au0633u0631u064a <BR> 1 ( 10.75 u0623u0648u0646u0635u0629 ) u064au0645u0643u0646 u0643u0631u064au0645 u0645u0643u062bu0641 u0645u0646 u062du0633u0627u0621 u0627u0644u062fu062cu0627u062c <BR> 1/4 u0643u0648u0628 u062du0644u064au0628 u0627u0644u0635u0641u062du0629 2 u0643u0648u0628 u0645u0632u064au062c u062du0634u0648 - u0645u062du0646u0643 u0639u0634u0628u0629 <u0631 ",
"tduration": "1 HR"
}
]
}
In this the name, description and details field contain some language translated content.
I need to encode this into UTF-8 in my android application.
I have used the below code but this doesnot seems working.
reader = new BufferedReader(new InputStreamReader(stream,"UTF-8"));
Anyone having idea about this?
Note : The code is working fine but the characters are not encoded.
You need to create a json object from the input stream.
StringBuilder jsonResults = new StringBuilder();
BufferedReader rd = new BufferedReader(new InputStreamReader(
response.getEntity().getContent()));
String line = "";
while ((line = rd.readLine()) != null) {
jsonResults.append(line);
}
rd.close();
JSONObject jsonObj = new JSONObject(jsonResults.toString());
boolean result = jsonObj.getBoolean("someDummyKey");
There is also a great library https://github.com/loopj/android-async-http on gitub wich will do all the magic for you. Check it out.
Firstly, you text should contain sequences like \u0637\u0627\u062c\u0646 (note the \).
This notation is known as an Unicode escape syntax. See http://docs.oracle.com/javase/specs/jls/se7/html/jls-3.html
When used in a String literal, such as String a = "\u0060";, this is interpreted by the compiler, and the String a contains only 1 character.
When used in a JSON String, it is decoded by the JSON parser. In your case, once the escape sequences are properly fixed, you can simply do:
StringBuffer sb = new StringBuffer();
String line = null;
while ((line = reader.readLine() != null) {
sb.append(line).append(System.getProperty("line.separator"));
}
JSONObject object = new JSONObject(sb.toString());
In the even that you were not able to fix the escape sequence (for example in the case of a bug on the server side that you are not in a position to have fixed), you could possibly consider doing something like :
JSONObject object = new JSONObject(sb.toString().replace("u06", "\\u06"));
Since all your problematic sequences seem to be in the 06 unicode plane (which makes sense, it is where the arabic characters are: http://en.wikibooks.org/wiki/Unicode/Character_reference/0000-0FFF )
Having received the following response from Foursquare, when I try to parse it, I get the error below:
Response:
{"meta":{"code":200},"response":{"venues":[{"id":"4b1c3ce9f964a520d60424e3","name":"Folsom Lake Bowl","contact":{},"location":{"address":"511 East Bidwell","lat":38.67291745,"lng":-121.165447,"distance":39,"postalCode":"95630","city":"Folsom","state":"CA"},"categories":[{"id":"4bf58dd8d48988d1e4931735","name":"Bowling Alley","pluralName":"Bowling Alleys","shortName":"Bowling Alley","icon":{"prefix":"https://foursquare.com/img/categories/arts_entertainment/bowling_","sizes":[32,44,64,88,256],"name":".png"},"primary":true}],"verified":false,"stats":{"checkinsCount":592,"usersCount":284,"tipCount":2},"hereNow":{"count":0}}]}}
Error:
Exception in thread "main" org.codehaus.jettison.json.JSONException: JSONObject["groups"] not found.
at org.codehaus.jettison.json.JSONObject.get(JSONObject.java:360)
at org.codehaus.jettison.json.JSONObject.getJSONArray(JSONObject.java:436)
at playaround.FoursquareAPI.get(FoursquareAPI.java:56)
at playaround.FoursquareAPI.main(FoursquareAPI.java:31)
Code:
StringBuilder sb = new StringBuilder();
BufferedReader reader = new BufferedReader(new InputStreamReader(response.getEntity().getContent()));
for (String line; null != (line = reader.readLine());) {
sb.append(line);
}
String output = sb.toString();
JSONObject json = new JSONObject(output);
JSONArray venues = json.getJSONObject("response").getJSONArray("groups").getJSONObject(0).getJSONArray("items");
System.out.println(venues.length());
All I want is to read the response from Foursquare as JSONObject in Java. Any help?
Reading that stack trace, the JSON is being parsed just fine.
The problem is that you are trying to read a property that doesn't exist -- "groups"
From my experience, if you get the JSON object - such as the problem I had ;parsing a returned LOCATION field. I started with the following code:
JSONObject jsonObjLoc = new JSONObject(myLocation);
If you can get the Object, then simply refer to "has" parameter like:
if(jsonObjLoc.has("myAddress")) { // name of field to look for
myTextAddress = jsonObjLoc.getString("address");
}
I use has to protect against the empty or null field not being returned.
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);
I want to make an Http request and store the result in a JSONObject. I haven't worked much with servlets, so I am unsure as to whether I am 1) Making the request properly, and 2) supposed to create the JSONObject. I have imported the JSONObject and JSONArray classes, but I don't know where I ought to use them. Here's what I have:
public void doGet(HttpServletRequest req, HttpServletResponse resp)
throws IOException {
//create URL
try {
// With a single string.
URL url = new URL(FEED_URL);
// Read all the text returned by the server
BufferedReader in = new BufferedReader(new InputStreamReader(url.openStream()));
String str;
while ((str = in.readLine()) != null) {
// str is one line of text; readLine() strips the newline character(s)
}
in.close();
} catch (MalformedURLException e) {
}
catch (IOException e) {
}
My FEED_URL is already written so that it will return a feed formatted for JSON.
This has been getting to me for hours. Thank you very much, you guys are an invaluable resource!
First gather the response into a String:
BufferedReader in = new BufferedReader(new InputStreamReader(url.openStream()));
StringBuilder fullResponse = new StringBuilder();
String str;
while ((str = in.readLine()) != null) {
fullResponse.append(str);
}
Then, if the string starts with "{", you can use:
JSONObject obj = new JSONObject(fullResponse.toString()); //[1]
and if it starts with "[", you can use:
JSONArray arr = new JSONArray(fullResponse.toStrin()); //[2]
[1] http://json.org/javadoc/org/json/JSONObject.html#JSONObject%28java.lang.String%29
[2] http://json.org/javadoc/org/json/JSONArray.html#JSONArray%28java.lang.String%29
Firstly, this is actually not a servlet problem. You don't have any problems with javax.servlet API. You just have problems with java.net API and the JSON API.
For parsing and formatting JSON strings, I would recommend to use Gson (Google JSON) instead of the legacy JSON API's. It has much better support for generics and nested properties and can convert a JSON string to a fullworthy javabean in a single call.
I've posted a complete code example before here. Hope you find it useful.