Json parser error? Amazon API incorrect JSON response? - java

So here is the code I use to parse the amazon JSON response for my inventory of products.
ListInventorySupplyResponse response = client.listInventorySupply(request);
ResponseHeaderMetadata rhmd = response.getResponseHeaderMetadata();
String responseJSON = response.toJSON();
JSONParser parser = new JSONParser();
try {
json = (JSONObject) parser.parse(responseJSON);
It worked for a week, and then I got this error today.
Unexpected token VALUE(-1) at position 5948.
looking through the response JSON. I put it in a JSON validator (http://jsonlint.com/)
jsonlint told me that the response I was getting was not correct json! Here was the error
{
"SellerSKU": "zz",
"FNSKU": "B006T5BLTO",
"ASIN": "B006T5BLTO",
"Condition": "NewItem",
"TotalSupplyQuantity": 92,
"InStockSupplyQuantity": 44,
"EarliestAvailability": {
"TimepointType": "DateTime",
"DateTime": 2015-01-13T09: 00: 00Z
},
"SupplyDetail": {
"member": [
]
}
},
{
"SellerSKU": "yyC",
"FNSKU": "B00IHMDJ7Y",
"ASIN": "B00IHMDJ7Y",
"Condition": "NewItem",
"TotalSupplyQuantity": 63,
"InStockSupplyQuantity": 63,
"EarliestAvailability": {
"TimepointType": "Immediately"
},
"SupplyDetail": {
"member": [
]
}
},
Parse error on line 398:
... "DateTime": 2015-01-13T09: 00: 00Z
----------------------^
Expecting '}', ',', ']'
As you can see, for some reason most of products are available immediately but one is not and Amazon sends me a "datetime" for when it is. However they dont put the date time in quotes making it an invalid JSON.
Is it me? Is it them? How do I handle this. My program doesnt need this part of the JSON but I dont know how to take this field out or tell the parser to "skip over it" so that it can parse the rest of the fields minus this one incorrect field that I dont care about anyway.
Thanks!

Related

how to make fault tolerant code when parsing JSONObject?

currently I retrieve a JSON object from algolia like this to my app:
{
"title": "Manajemen Masjid sesuai sunnah Rasulullah",
"address": "Jl. Tebet Utara I No.40, RT.8/RW.2, Tebet Tim., Tebet, Kota Jakarta Selatan, Daerah Khusus Ibukota Jakarta 12820, Indonesia",
"additionalAddress": "",
"capacity": 0,
"city": "Jakarta",
"creatorIsVerified": true,
"description": "Dua aplikasi milik Facebook",
"email": "abcd#gmail.com",
"eventID": "000b4e1a-f65e-4d77-83ce-d0770d344d4b",
"eventType": "Kajian Umum",
"_geoloc": {
"lat": -6.2256428,
"lng": 106.8527658
},
"hasBeenApproved": true,
"numberOfContact": "081808664",
"price": 0,
"rankPoint": 300000000,
"speaker": "Syafiq Reza Basalamah",
"venue": "Aql Islamic Center 2",
"website": "http://www.lakuin.id"
}
as you can see, in this record, there is no "instagram" field in the JSON above. but other records have "instagram" field in the JSON. I have problem when parsing that JSON in my Android app because not all data has "instagram" field in it.
I parse the "instagram" field using this code, If the "instagram" field is not available from incoming JSON, then I want to assign an empty string like the code below:
val instagram = jsonObject.get("instagram") as? String ?: ""
the jsonObject data type is java class JSONObject (import org.json.JSONObject)
but that line will make a crash. error message:
Caused by: org.json.JSONException: No value for instagram
E/CrashlyticsCore: Unexpected method invoked on
AppMeasurement.EventListener: onEvent(java.lang.String,
java.lang.String, android.os.Bundle, java.lang.Long); returning null
so how to write code that can handle both case, either it has "instagram" field or not from the incoming json ?
As #Pemba Tamang suggested, use jsonObject.optString("instagram",""); or use gson library, it handles errors in json
You can use try , catch for that :
try{
// try to parse ur Json here
}catch (JSONException e){
// here you can assign the empty String
}

Parsing JSON object from service call Spring JAVA

I am getting the following response from some service call . I am trying to parse the JSON . I am actually new to JAVA and not sure about how to parse JSON objects returned from HTTP call . I am getting the following error :
org.json.JSONException: JSONArray initial value should be a string or collection or array.
at org.json.JSONArray.<init>(JSONArray.java:197) ~[json-20180813.jar!/:na]
Code :
Object resp = hiveApiClient.getEnrollmentSearchDetails(certificate, employeeId);
logger.info("response : " + resp);
JSONArray mainArray = new JSONArray(resp);
// The nested array is at the second position : 1
JSONArray nestedArray = mainArray.getJSONArray(1);
// the interesting main JSONObject is on the first position
// of the nested array : 0
JSONObject interestingJSONObject = nestedArray.getJSONObject(0);
logger.info("XXX :{}", interestingJSONObject);
String courseId = interestingJSONObject.getJSONObject("additionalData").getString("courseId");
logger.info("XXXX :{}",courseId);
return courseId;
Response :
[
"list", [{
"#type": "com.saba.services.calendar.CalendarElementDetail",
"eventType": "ILTCLASS",
"elementName": "Microservice Application Architecture",
"elementId": "class000000000013497",
"eventId": "timel000000000103609",
"ownerID": "emplo000000000096641",
"locationId": "locat000000000003165",
"locationName": "IND-Bangalore-Karnataka",
"additionalData": {
"#type": "map",
"locationTimeZone": "tzone000000000000042",
"eventID": "class000000000013497",
"locationName": "IND-Bangalore-Karnataka",
"locationId": "locat000000000003165",
"transcriptID": "ofapr000000002962367",
"registrationID": "regdw000000001766254",
"eventName": "Microservice Application Architecture",
"moduleID": "regmd000000002147176",
"courseID": "cours000000000031995"
},
"startDate": {
"#type": "com.saba.customtypes.DateWithLocale",
"date": 1538613000000,
"locale": "03-OCT-2018",
"timeInLocale": "8:30 PM",
"dateInUserTimeZone": "03-OCT-2018",
"timeInUserTimeZone": "5:30 PM",
"dateInCustomTimeZone": null,
"timeInCustomTimeZone": null,
"customTimeZoneDate": 0,
"timeInStandardFormat": "8:30 PM",
"dateInStandardFormat": "10/03/2018"
}
}]
]
Well first of all, your json is not valid because of this}:
["list" : /* something here but anyway, not the concern here */ ]
when it should have been
{"list" : /* something here but anyway not the concern here */}
I think your problem is with the understanding of how a JSON file works and what is a json object and a json array. Please correct your JSON input so that we can provide you with insights on how to retrieve the value you need.
Additionally, I would recommend you looking into Jackson lib for parsing JSON objects to JAVA POJOs directly really easily. The link is a great tutorial to get you started here. Furthermore, jackson is already included with Spring so that you literally have nothing to install.
Edit
I misread the JSON input : I saw a : after "list" instead of a ,.
So your JSON is a proper JSON but its a quite uncommon JSON as it is loosely typed and therefore cannot be that easily parsed with standard Jackson library for example. In fact, in the main array, a string is put together with a Json Object which is a very bad practice but that's not your fault as I suppose you are not responsible for the output of this HTTP call.
So how can you actually get your value ? Well let's describe the JSON, you've got here : a JSON array containing a String and another sub JSON array. You want to take some values from the very first JSON object inside the nested json array.
This one :
{
"#type": "com.saba.services.calendar.CalendarElementDetail",
"eventType": "ILTCLASS",
"elementName": "Microservice Application Architecture",
"elementId": "class000000000013497",
"eventId": "timel000000000103609",
"ownerID": "emplo000000000096641",
"locationId": "locat000000000003165",
"locationName": "IND-Bangalore-Karnataka",
"additionalData": {
"#type": "map",
"locationTimeZone": "tzone000000000000042",
"eventID": "class000000000013497",
"locationName": "IND-Bangalore-Karnataka",
"locationId": "locat000000000003165",
"transcriptID": "ofapr000000002962367",
"registrationID": "regdw000000001766254",
"eventName": "Microservice Application Architecture",
"moduleID": "regmd000000002147176",
"courseID": "cours000000000031995"
},
"startDate": {
"#type": "com.saba.customtypes.DateWithLocale",
"date": 1538613000000,
"locale": "03-OCT-2018",
"timeInLocale": "8:30 PM",
"dateInUserTimeZone": "03-OCT-2018",
"timeInUserTimeZone": "5:30 PM",
"dateInCustomTimeZone": null,
"timeInCustomTimeZone": null,
"customTimeZoneDate": 0,
"timeInStandardFormat": "8:30 PM",
"dateInStandardFormat": "10/03/2018"
}
}
The first task here is to gather this object. Let's suppose the nested json array is always in the second position after the string and that the JSON object you want is always at the first position of the nested array which might not be the case depending on your input JSON but this was not precised in your question.
JSONArray mainArray = new JSONArray(resp);
// The nested array is at the second position : 1
JSONArray nestedArray = mainArray.getJSONArray(1);
// the interesting main JSONObject is on the first position
// of the nested array : 0
JSONObject interestingJSONObject = nestedArray.getJSONObject(0);
So now we want "courseId" from "additionnalData" Json Object :
String courseId = interestingJSONObject.getJSONObject("additionalData").getString("courseId");
And there you go!

Parsing nested json array in java

I have json file in below format.
{
"data":[
{
"prjId": 1,
"name" : "Forj1",
"issue": [
{
"id": 00001,
"status" : "Closed"
},
{
"id": 00002,
"status" : "Open"
}
]
},
{
"prjId": 2,
"name" : "Forj2",
"issue": [
{
"id": 00003,
"status" : "Closed"
},
{
"id": 00004,
"status" : "Open"
}
]
}],
"issueCounter": 7,
"success": true
}
Here "data" is array of projects, and within project attribute there is array of "issue".
So far if I remove "issue" array, I am able to traverse the json to one level down in "data" attribute, If this json has "issue" array I get an error saying missing comma.
javax.json.stream.JsonParsingException: Invalid token=NUMBER at (line no=15, column no=14, offset=242) Expected tokens are: [COMMA]
Below is the code that I have right now. I have two problems with this, one is the error while reading if I place the "issue" attribute, and secondly a way to read the "issue" array and traverse all attributes within.
InputStream fis = new FileInputStream(pathToFile+"data3.json");
JsonReader jsonReader = Json.createReader(fis);
//the error is thrown on below line while reading the above json.
JsonObject jsonObject = jsonReader.readObject();
jsonReader.close();
fis.close();
System.out.println(jsonObject.getInt("issueCounter"));
//reading arrays from json
JsonArray jsonArrayData = jsonObject.getJsonArray("data");
Project [] prj = new Project[jsonArrayData.size()];
int index = 0;
for(JsonValue value : jsonArrayData){
JSONObject jsonObj = new JSONObject(value.toString());
System.out.println(jsonObj.getString("name"));
System.out.println(jsonObj.getInt("prjId"));
//this is also the place where I am stuck, I know I need to construct an array out of it by obtaining issue attribute. Below is very very wrong.
/*
JsonArray jsonArrayIssue = jsonObj.getJsonArray("issue");
for(JsonValue issue : jsonArrayIssue){
JSONObject jsonIssueObj = new JSONObject(issue.toString());
System.out.println(jsonIssueObj.getString("status"));
System.out.println(jsonIssueObj.getInt("id"));
}
*/
}
Any help or pointers is deeply appreciated. I can tweak the json if its required ultimately I need to maintain an array of issues.
The problem as others said is the JSON.
"id": 00001 <-- this is a number, numbers cannot start with a leading zero as per JSON stadard.
If you control the JSON you should tweak it.
Alternatively ff you don't, you can use a less strict parser like org.json.simple https://mvnrepository.com/artifact/com.googlecode.json-simple/json-simple
The code will be the same as yours, just adjusted to org.json.simple
try { ...
JSONObject rootJSON = (JSONObject) new JSONParser().parse(jsonString);
JSONArray dataList = (JSONArray) rootJSON.get("data");
for(Object projectObj: dataList.toArray()){
JSONObject project = (JSONObject)projectObj;
JSONArray issueList = (JSONArray) project.get("issue");
for(Object issueObj: issueList.toArray()){
JSONObject issue = (JSONObject) issueObj;
//do something with the issue
}
}
} catch (ParseException e) {
//do smth
e.printStackTrace();
}
Your json data is invalid.You can check here.
http://jsonlint.com
...issue": [{ "id": 00001,
"status": ----------------------^
Your id must be string number,string,boolean.Send 1,2,3,.... as return values and check if it works.
Your code looks okay the problem is the JSON formatting. Specifically the following lines:
"id": 00001,
"id": 00002,
"id": 00003,
"id": 00004,
Basically if you want it in that format you will need to set them as strings by wrapping the values in quotations i.e. "id": "00001" or you can use a valid number i.e. "id": 1

How to escape HTML in JSON

I'm wondering how can I escape HTML code in JSON ? I'm using Jackson as my JSON mapper.
In my content I have various characters: tags, single quotes, double quotes, new lines character (\n), tabs etc. I tried to use CharacterEscapes class, but with no results.
My JSON response blows up after using CharacterEscapes. I tried to escape it manually, but also without any results.
So the question is, lets say that we have:
<p>Some text</p>\n<p>"SomeText"</p>
How can I send it back to browser as value of the JSON object?
UPDATE:
Input is:
{
"code": {
"num": 12
},
"obj": {
"label": "somelabel",
"order": 1
},
"det": {
"part": "1",
"cont": true
},
"html": "<p>Mine text</p>"
}
Output:
{
"code": {
"num": 12
},
"obj": {
"label": "somelabel",
"order": 1
},
"det": {
"part":"1",
"cont": true
},
"html":{"code": {
"num": 12
},
"obj": {
"label": "somelabel",
"order": 1
},
"det": {
"part":"
}
For now I have found following solution:
I have added CharacterEscapes to the JsonFactory of the ObjectMapper class.
Also I have changed way of writting JSON into response.
Instead of
objectMapper.writeValue(response.getWriter(), myObject)
I'm doing this:
PrintWriter writer = response.getWriter();
writer.print(String.valueOf(objectMapper.writeValueAsBytes(myObject));
writer.flush();
And it works as I wanted.
I would suggest to use either of below.
1.You can use GSON library for this purpose.
Gson gson = new GsonBuilder().disableHtmlEscaping().create();
2.Use Apache commons StringEscapeUtils.escapeHtml("JSON string").

Trying to extract data from JSON or JSONP using WOT api

I was using WOT(web of trust) api.In this, i am getting response in this format,
process( {
"www.google.com": {
"target": "google.com",
"0": [ 95, 84 ],
"1": [ 95, 84 ],
"2": [ 95, 84 ],
"4": [ 93, 78 ],
"categories": {
"501": 92
}
}
} )
I am very confused to extract the data string from this format of JSON. I searched a lot but could not find any way.
I want to extract from categories... means I want to save '502' value.
Problem : JSON Objects starts with "{" and ends with "}", the response you're getting is not a correct JSON Format.
Analysis : Why? you might ask, the response started with p char from process, and ends with ) char, instead of "}".
Solution : To fix the json, we will need to remove the process ( and ) string, so that the response can be parsed as JSON.
Hint : Use String.replace() method to replace the unwanted string with empty string "", more information here and here
Hope this helps, and Good Luck! ^^
Reid

Categories

Resources