Parsing String with JSONTokener to JSONObject OR JSONArray - java

I'm using the following code to handle REST responses from my server:
if (response.getEntity() != null) {
BufferedReader reader = new BufferedReader(new InputStreamReader(response.getEntity().getContent(), "UTF-8"));
StringBuilder builder = new StringBuilder();
for (String line = null; (line = reader.readLine()) != null;) {
builder.append(line).append("\n");
}
JSONTokener tokener = new JSONTokener(builder.toString());
try {
rr.jsonObject = new JSONObject(tokener);
} catch (JSONException e) {
e.printStackTrace();
Log.d("parsing", "creating json array");
try {
rr.jsonArray = new JSONArray(tokener);
} catch (JSONException e1) {
e1.printStackTrace();
}
}
}
If the response is an JSONObject, it works perfectly but if the server returns a JSONArray, the second try block also throws although it's correct json.
03-30 14:09:15.069: W/System.err(6713): org.json.JSONException: End of input at character 314 of [{"__className":"stdClass","char3code":"DEU","fips_name":"Germany","alternate_names":"Germany, Deutschland, Allemagne, Alemania"},{"__className":"stdClass","char3code":"USA","fips_name":"United States","alternate_names":"United States of America, Vereinigte Staaten von Amerika, \u00c9tats-Unis, Estados Unidos"}]

I expect the reason that this is failing is that when you call new JSONArray(tokener) the tokener is no longer positioned at the start of the token stream. Try creating a new JSONTokener instance for the 2nd attempt at parsing..

Related

Java : Not Able to cast jsonobject to Json array

I was able to pull data from an api using my get request method
{"vulnerabilities":[{"id":5027994,"status":"open","closed_at":null,"created_at":"2019-06-07T06:10:15Z","due_date":null,"notes":null,"port":[],"priority":null,"identifiers":["adobe-reader-apsb09-15-cve-2009-2990"],"last_seen_time":"2019-07-24T05:00:00.000Z","fix_id":4953,"scanner_vulnerabilities":[{"port":null,"external_unique_id":"adobe-reader-apsb09-15-cve-2009-2990","open":true}],"asset_id":119920,"connectors":[{"name":"Nexpose Enterprise","id":7,"connector_definition_name":"Nexpose Enterprise","vendor":"R7"}],"service_ticket":null,"urls":{"asset":"dummy.com"},"patch":true,"patch_published_at":"2009-10-08T22:40:52.000Z","cve_id":"CVE-2009-2990","cve_description":"Array index error in Adobe Reader and Acrobat 9.x before 9.2, 8.x before 8.1.7, and possibly 7.x through 7.1.4 might allow attackers to execute arbitrary code via unspecified vectors.","cve_published_at":"2009-10-19T22:30:00.000Z","description":null,"solution":null,"wasc_id":null,"severity":9,"threat":9,"popular_target":false,"active_internet_breach":true,"easily_exploitable":true,"malware_exploitable":true,"predicted_exploitable":false,"custom_fields":[],"first_found_on":"2019-06-05T05:22:23Z","top_priority":true,"risk_meter_score":100,"closed":false}
but in my request method I have received an error in parsing this data , which is that I can not cast an jsonobject to jsonarray.
here is the get request method:
public static void GetRequest() {
BufferedReader reader;
String access_token = "blahblahblah";
String line;
StringBuffer responseContentReader = new StringBuffer();
try {
URL url = new URL("https://api.security.com/vulnerabilities/");
connection = (HttpsURLConnection) url.openConnection();
connection.setRequestProperty("X-Risk-Token ", access_token);
connection.setRequestProperty("Accept", "application/json");
//here we should be able to "request" our setup
//Here will be the method I will use
connection.setRequestMethod("GET");
//after 5 sec if the connection is not successful time it out
connection.setConnectTimeout(5000);
connection.setReadTimeout(5000);
int status = connection.getResponseCode();
//System.out.println(status); //here the connect was established output was 200 (OK)
//here we are dealing with the connection isnt succesful
if (status > 299) {
reader = new BufferedReader(new InputStreamReader(connection.getErrorStream()));
while ((line = reader.readLine()) != null) {
responseContentReader.append(" ");
responseContentReader.append(line);
responseContentReader.append("\n");
}
reader.close();
//returns what is successful
} else {
reader = new BufferedReader(new InputStreamReader(connection.getInputStream()));
while ((line = reader.readLine()) != null) {
responseContentReader.append(" ");
responseContentReader.append(line);
responseContentReader.append("\n");
}
reader.close();
}
JsonParser parser = new JsonParser();
Object object = parser.parse(responseContentReader.toString());
JsonArray array = (JsonArray) object; // here is where the exception occurs
for (int i = 0; i < array.size(); i++) {
JsonArray jsonArray = (JsonArray) array.get(i);
JsonObject jsonobj = (JsonObject) jsonArray.get(i);// cannot cast jsonobject to jsonarray
}
//JsonObject jsonObject = (JsonObject) object;
System.out.println( responseContentReader.toString());
} catch (MalformedURLException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IOException e) {
// TODO: handle exception
e.printStackTrace();
} finally {
connection.disconnect();
}
}
here is where the error occurs specifically, I honestly dont know how to go forward with this:
JsonParser parser = new JsonParser();
Object object = parser.parse(responseContentReader.toString());
JsonArray array = (JsonArray) object; // here is where the exception occurs
for (int i = 0; i < array.size(); i++) {
JsonArray jsonArray = (JsonArray) array.get(i);
JsonObject jsonobj = (JsonObject) jsonArray.get(i);// cannot cast jsonobject to jsonarray
}
//JsonObject jsonObject = (JsonObject) object;
System.out.println( responseContentReader.toString());
the error message is
Exception in thread "main" java.lang.ClassCastException: com.google.gson.JsonObject cannot be cast to com.google.gson.JsonArray
you forgot to close your json with brackets and braces like this:
{"vulnerabilities":[{"id":5027994,"status":"open","closed_at":null,"created_at":"2019-06-07T06:10:15Z","due_date":null,"notes":null,"port":[],"priority":null,"identifiers":["adobe-reader-apsb09-15-cve-2009-2990"],"last_seen_time":"2019-07-24T05:00:00.000Z","fix_id":4953,"scanner_vulnerabilities":[{"port":null,"external_unique_id":"adobe-reader-apsb09-15-cve-2009-2990","open":true}],"asset_id":119920,"connectors":[{"name":"Nexpose Enterprise","id":7,"connector_definition_name":"Nexpose Enterprise","vendor":"R7"}],"service_ticket":null,"urls":{"asset":"dummy.com"},"patch":true,"patch_published_at":"2009-10-08T22:40:52.000Z","cve_id":"CVE-2009-2990","cve_description":"Array index error in Adobe Reader and Acrobat 9.x before 9.2, 8.x before 8.1.7, and possibly 7.x through 7.1.4 might allow attackers to execute arbitrary code via unspecified vectors.","cve_published_at":"2009-10-19T22:30:00.000Z","description":null,"solution":null,"wasc_id":null,"severity":9,"threat":9,"popular_target":false,"active_internet_breach":true,"easily_exploitable":true,"malware_exploitable":true,"predicted_exploitable":false,"custom_fields":[],"first_found_on":"2019-06-05T05:22:23Z","top_priority":true,"risk_meter_score":100,"closed":false}]}
try this json and it should work!
I highly recommend you use this website for formmating your jsons
https://jsonformatter.org/
Instead of casting, retrieve the array from the object or json response like below:
JsonObject object = ...
JsonArray array = object.getJSONArray("vulnerabilities");
The response returned by the GET API is not a JsonArray but a JsonObject.
You can correct the following line -- JsonArray array = (JsonArray) object; to --
JsonObject jsonObject = (JsonObject) object;
Further, you could read the "vulnerabilities" within by --
JsonArray vulnerabilitiesArray = jsonObject.getJsonArray("vulnerabilities");

How to print the values of a dictionary-like StringBuffer in java?

I have this code :
StringBuffer sb = new StringBuffer();
try {
BufferedReader reader = request.getReader();
String line = null;
while ((line = reader.readLine()) != null) {
sb.append(line);
System.out.println(line);
}
} catch (Exception e) {
e.printStackTrace();
}
the line :
System.out.println(line);
prints in console at the end of the loop like this:
{"signupname":"John","signuppassword":"1234","signupnickname":"Jonny",
"signupdescription":"student","signupphoto":"(here photo url)"}
how can I get only the values of the keys? I want something like this:
John
1234
Jonny
student
(here photo url)
Thanks for helpers:)
If each row is a complete JSON object. You can use Gson JSON parser.
https://mvnrepository.com/artifact/com.google.code.gson/gson
StringBuffer sb = new StringBuffer();
try {
BufferedReader reader = request.getReader();
String line;
Gson gson = new Gson();
while ((line = reader.readLine()) != null) {
Map map = gson.fromJson(line, Map.class);
for(Object value : map.values()) {
System.out.println(value);
}
sb.append(line);
System.out.println(line);
}
} catch (Exception e) {
e.printStackTrace();
}
The format looks like JSON. If that's true, use any JSON parser you like and get only the keys.
E.g. org.json:json in Maven Central.
https://github.com/stleary/JSON-java

JSON Object GSON into list

I want to implement my old code when I was populating JSON array into listview but my current json haven't specified array, overall json is an array...
Can somebody tell me how to transform my code to use JSON like this?
https://api-v2.hearthis.at/categories/drumandbass/?page=15&count=2
Code to use gson, my old:
protected List<Model> doInBackground(String... params) {
HttpURLConnection connection = null;
BufferedReader reader = null;
try {
URL url = new URL(params[0]);
connection = (HttpURLConnection) url.openConnection();
connection.connect();
InputStream stream = connection.getInputStream();
reader = new BufferedReader(new InputStreamReader(stream));
StringBuffer buffer = new StringBuffer();
String line ="";
while ((line = reader.readLine()) != null){
buffer.append(line);
}
String finalJson = buffer.toString();
JSONObject parentObject = new JSONObject(finalJson);
JSONArray parentArray = new JSONArray("arrayname");
List<Model> dataModelList = new ArrayList<>();
Gson gson = new Gson();
for(int i=0; i<parentArray.length(); i++) {
JSONObject finalObject = parentArray.getJSONObject(i);
Model modelList = gson.fromJson(finalObject.toString(), Model.class);
dataModelList.add(modelList);
}
return dataModelList;
} catch (MalformedURLException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
} catch (JSONException e) {
e.printStackTrace();
} finally {
if(connection != null) {
connection.disconnect();
}
try {
if(reader != null) {
reader.close();
}
} catch (IOException e) {
e.printStackTrace();
}
}
return null;
}
Instead of doing this:
JSONObject parentObject = new JSONObject(finalJson);
JSONArray parentArray = new JSONArray("arrayname");
Just do this:
JSONArray parentArray = new JSONArray(finalJson);
If i understand the problem correctly, i guess you are having trouble parsing the array who's name is not specified with a key. So, a simple but not a very good way of doing this would be, when you create your finalJson like this:
String finalJson = buffer.toString();
just add a line to check if it contains an array opening bracket, like this:
if(finalJson.contains("[")){
finalJson = finalJson.replace("[","{
"arrayname": [");
}
also, close the array appropriately.
if(finalJson.contains("]")){
finalJson = finalJson.replace("]","]
}");
}
This way, u will have a name for the array to parse, and i guess this is what you are looking for. But this approach might fail if you have more than 1 array in your Json, in that case you will have to use startsWith & endsWith string methods to give a name to your array. But, as of now, from what your Json looks like, this would work.

How to pull individual pieces of data from a JSON to string?

public static void main(String[] args) throws IOException {
try {
JSONObject json = new JSONObject(readUrl("http://api.wunderground.com" +"/api/106c4dee47162999/history_20060405/q/CA/San_Francisco.json"));
JSONObject data = json.getJSONObject("observations.tempm");
System.out.println(data);
} catch (JSONException e) {
e.printStackTrace();
}
}
private static String readUrl(String string) throws IOException {
BufferedReader reader = null;
try {
String urlString = string;
URL url = new URL(urlString);
reader = new BufferedReader(new InputStreamReader(url.openStream()));
StringBuffer buffer = new StringBuffer();
int read;
char[] chars = new char[1024];
while ((read = reader.read(chars)) != -1)
buffer.append(chars, 0, read);
return buffer.toString();
} finally {
if (reader != null)
reader.close();
}
}
}
2.errors :
org.json.JSONException: JSONObject["observations.tempm"] not found.
at org.json.JSONObject.get(JSONObject.java:454)
at org.json.JSONObject.getJSONObject(JSONObject.java:553)
at com.parser.ParserObject.main(ParserObject.java:17)
The intersting part of the JSON you use is:
{'history':
{'observations':
[
{'tempm':'10.0'}
]
}
}
Use this:
JSONObject json = ...;
JSONObject history = (JSONObject) json.get("history");
JSONArray observations = (JSONArry) json.get("observations");
JSONObject observation0 = (JSONObject) observations.get(0);
String tempm = observation0.get("tempm");
If you are interested in other array elements, use a different index.
'observations' isnt in root. you need to get 'history' first. 'observations' is a part of 'history'. and 'observations' is a list/array.
i suggest using 'jackson' or 'gson' library.parsing native json is really a pain.
you can even go to a extent of un/marshalling only required fields/objects from JSON.

JSON Data Formatting

I am passing the following JSON object from a .jsp page to a java servlet using JSON.stringify and JQuery.ajax():
{"bin":[{"binId":"0","binDetails":[{"productCode":"AU192","qty":"4"},{"productCode":"NE823","qty":"8"}],"comments":"store pickup"},{"binId":"1","binDetails":[{"productCode":"AF634","qty":"2"}],"comments":""},{"binId":"2","binDetails":[{"productCode":"QB187","qty":"3"}],"comments":"international shipping"},{"binId":"3","binDetails":[{"productCode":"AF634","qty":"2"},{"productCode":"QB187","qty":"2"}],"comments":""}]}
This is the code in my java servlet:
StringBuffer strBuffer = new StringBuffer();
String line = null;
try {
BufferedReader reader = request.getReader();
while((line = reader.readLine()) != null){
strBuffer.append(line);
}
} catch (Exception e) {
}
try {
JSONObject jsonObj = new JSONObject(new JSONTokener(strBuffer.toString()));
// I call a method here and pass jsonObj
} catch (Exception e) {
}
In the method to which I pass jsonObj I am using jsonObj.length() to find out how many items are in jsonObj and it tells me 1, which in this case I would have expected 3. I even tried this:
JSONObject bins = jsonObj.get("bin");
bins.length();
which told me jsonObj.get("bin") was not a JSONObject. Is my data formatted incorrectly before I pass it from my .jsp or am I using the JSONObject in my java servlet incorrectly? How do I access the values in the JSONObject?
JSONArray bins = jsonObj.getJSONArray("bin");
bins.length();

Categories

Resources