I'm currently parsing a JSON response from the Google Translate API. I'm able to do this with no problem. Seeing as how I don't have a lot of XML experience (I'm more of an XML guy), I'm having trouble figuring out how to implement some error handling in my JSON parsing. I am using the JSON j2me library.
Here is a successful response:
{"responseData": {"translatedText":"Teks te vertaal ...","detectedSourceLanguage":"en"}, "responseDetails": null, "responseStatus": 200}
And here is an unsuccessful response:
{"responseData": null, "responseDetails": "could not reliably detect source language", "responseStatus": 400}
So, if the translation is unsuccessful, I want to put the value of "responseDetails" into a string. Here is my parsing code, which is not currently parsing out responseDetails correctly. Instead, the "catch" of the "try" is being caught.
try {
JSONObject responseObject = new JSONObject(response);
if (responseObject != null) {
JSONObject responseData = responseObject
.getJSONObject("responseData");
if (responseData != null) {
String translatedText = responseData
.getString("translatedText");
Notify.alert(translatedText);
} else {
String responseDetails = responseObject
.getString("responseDetails");
Notify.alert(responseDetails);
}
}
} catch (Exception e) {
Notify.alert("Unable to translate!");
}
Can anyone see where I'm going wrong?
Thanks!
Since you say the catch block is being triggered, I'd start debugging by looking at what Exception is being thrown. You could simply append your alert string to include e.toString().
So change your alert in the catch block to be:
Notify.alert("Unable to translate! " + e.toString());
And see what the actual error that's being thrown is.
Based on your comment, yes it looks like it's trying to create a JSONObject on a null value, so nest another try/catch block and parse it accordingly that way.
try {
JSONObject responseObject = new JSONObject(response);
if (responseObject != null) {
/* Try create a new JSON object from the
* responseData object. If it fails,
* display an alert */
try {
JSONObject responseData = responseObject
.getJSONObject("responseData");
if (responseData != null) {
String translatedText = responseData
.getString("translatedText");
Notify.alert(translatedText);
}
} catch (Exception e) {
String responseDetails = responseObject
.getString("responseDetails");
Notify.alert(responseDetails);
}
}
} catch (Exception e) {
Notify.alert("Unable to translate outer block!");
}
Related
having some serious problem when trying to read a local JSON file. I've looked everywhere for many days now and the best and farthest I could get was copying from Faizan's answer.
Reading a json file in Android
How come that Android Studio doesn't let me generate the second try-catch code block here?
Help and advice are very much appreciated!!
This is My code
public String loadJSONFromAsset() {
String json = null;
try {
InputStream is = getAssets().open("names.json");
int size = is.available();
byte[] buffer = new byte[size];
is.read(buffer);
is.close();
json = new String(buffer, "UTF-8");
} catch (IOException ex) {
ex.printStackTrace();
return null;
}
return json;
}
String jsonString = loadJSONFromAsset();
try {
JSONObject json = new JSONObject(jsonString);
JSONObject jObject = json.getJSONObject("female");
JSONObject jObject2 = jObject.getJSONObject("adult");
String name = jObject2.toString();
}
catch (Exception e) {
e.printStackTrace();
}
}
How come that Android Studio doesn't let me generate the second
try-catch code block here?
Simply, because your code is not inside a method.
Doing something like below should solve the error.
public void someMethodIdentifier(){ // doesn't have to be void return type, you know better than me what type you want to return.
String jsonString = loadJSONFromAsset();
try {
JSONObject json = new JSONObject(jsonString);
JSONObject jObject = json.getJSONObject("female");
JSONObject jObject2 = jObject.getJSONObject("adult");
String name = jObject2.toString();
}
catch (Exception e) {
e.printStackTrace();
}
}
Note - from the looks of the statements that's contained within the try block I think you intended to return some data? if that's the case just replace the void return type with the appropriate return type and return that data.
When I'm trying to push a JSONObject over a data stream, and I've built the JSONObject properly, but then I try and publish it to the stream it is null.
JSONObject position = new JSONObject();
try {
position.put("lat", location.getLatitude());
position.put("lng", location.getLongitude());
} catch (JSONException e) {
System.out.println("json not work");
e.printStackTrace();
}
System.out.println(position) //result: {"lat":37,"lng":-122}
pubNub.publish().message(position)//never sent, if other type it works
try pubNub.publish().message(position.toString());
I am working on web services that I want from my Android application connect to Oracle database, so my server is in java which connects to database... and the connection is done! What I am stuck to is that I got data from database and converted to json in the server side when I retrieve it in my Android app there I get null pointer exception.
Function to create my json in server side:
public static String constructJSN(String tag, boolean status,ArrayList<Teacher> f) {
JSONObject obj = new JSONObject();
try {
for(int i=0;i<f.size();i++){
obj.put("tag", tag);
obj.put("status", new Boolean(status));
String json = new Gson().toJson(f);
obj.put("data",json);
}
} catch (JSONException e) {
// TODO Auto-generated catch block
}
return obj.toString();
}
and when i print it i get :
{"tag":"login","status":true,"data":"[{\"name\":\"rasha\",\"classes\":\"b\",\"freetime\":\"3-4\"},{\"name\":\"heba\",\"classes\":\"a\",\"freetime\":\"3-4\"},{\"name\":\"omnia\",\"classes\":\"c\",\"freetime\":\"2-6\"}]"}
in android client side :
String j= obj.get("data").toString();
JSONObject myJsonObj = new JSONObject(j);
String Name = myJsonObj.getString("name");
String Classes = myJsonObj.getString("classes");
Toast.makeText(getApplicationContext(), Name+ " " + Classes, Toast.LENGTH_LONG).show();
and here I get an error while debugging:
Method threw java.lang.NullPointerException exception. Cannot
evaluate org.json.JSONObject.toString()
JSONObject myJsonObj = new JSONObject(j);
JsonArray data = myJsonObj.getJsonArray("data");
for (JSONObject jObjc: JsonArray) {
String Classes = jObjc.getString("classes");
}
Try the below:
Declare a static JsonObject and assign it to null
static JSONObject jObj = null;
Then in ur web service call, assign this to the JSON Response like this
jObj = new JSONObject(result);
jObj.getString("data");
I send some data to my server and get a response.
In case there was an error the response is a class instance:
{
errorCode (int),
errorMsg (String)
}
In a success case the response is an items array.
I have tried to run the following code and got an error:
code:
private void afterServerOfferResponse(final Gson gson,
String result) {
ServerErrorMessage serverErrorMessage = gson.fromJson(
result, ServerErrorMessage.class);
if (serverErrorMessage.errorCode == 0) {
Type collectionType = new TypeToken<ArrayList<Offer>>() {
}.getType();
mOffersList = gson.fromJson(result, collectionType);
mAdapter = new ImageAdapter(OffersListActivity.this,
mOffersList);
mListView.setAdapter(mAdapter);
error:
com.google.gson.JsonSyntaxException: java.lang.IllegalStateException: Expected BEGIN_OBJECT but was BEGIN_ARRAY at line 1 column 2
how would you check for an error case without changing the server response too much?
Add a try-catch block to handle the exception. Only when you try to parse the data, it will be validated if its valid JSON response or error.
First try to parse Array Class instance and if JSON exception , then parse with ServerErrorMessage class
Add like this, and handle the exception when Syntax Exception
try{
ServerErrorMessage serverErrorMessage = gson.fromJson(
result, ServerErrorMessage.class);
}catch (JsonSyntaxException e){
// handle the exception
}
catch (JsonIOException e){
// handle the exception
}
catch (JsonParseException e){
// handle the exception
}catch (IOException e){
// handle the exception
}
Another way is to use org.json.JSONObject like this
private boolean isValidJsonResponse(String responseString){
try {
new JSONObject(responseString);
return true;
} catch(JSONException e) {
return false;
}
}
in my android app I have an AsyncTask which downloads photos from my server. If I get an exception (mainly for connection time out) I show the user a message. My problem is that my code works MOST of the times, (meaning there are times when I interrupt the WiFi connection that I get an exception shown in my logcat but the message won't appear so I ended it up thinking that there might be an exception that I don't handle ) and I can't figure out the exact reason. I'll post the code run in my AsyncTask and the function that does the essential work. Hope you spot out something I'missing
#Override
protected String doInBackground(String... args) {
JSONParser jParser = new JSONParser();
JSONObject jsonObj = jParser.getJSONFromUrl(url);
Log.d("check1",url);
try {
list.addAll(processJsonData(jsonObj));
} catch (JSONException e) {
e.printStackTrace();
onDownloadFailed(this);
return "failed";
} catch (SocketException e) {
Log.e("Exception", e.getLocalizedMessage());
onDownloadFailed(this);
return "failed";
} catch (IOException e) {
Log.e("Exception", e.getLocalizedMessage());
onDownloadFailed(this);
return "failed";
}finally {
jsonObj=null;
}
return "done";
}
process JsonData is actually bigger that's the part for downloading the photos, the other part is about mapping string to an large Json File
private ArrayList<Monument> processJsonData(JSONObject jsonObj) throws IOException, SocketException, JSONException{
if(attachments!=null){
int lengthSize;
if(attachments.length()<3)
lengthSize=attachments.length();
else
lengthSize=3;
for(int j=0;j<lengthSize;++j){
JSONObject atta = attachments.getJSONObject(j);
JSONObject images = atta.optJSONObject(TAG_IMAGES);
if(images!=null){
JSONObject medium = images.getJSONObject(TAG_MEDIUM);
String url_image = medium.getString(TAG_URL_IMAGE);
String id = atta.getString("id");
String filename =title.replace(" ","")+id+".nomedia";
File destination = new File(MyApplication.getPhotoStorage() ,filename);
URL url = new URL (url_image);
InputStream is = url.openStream();
OutputStream os = new FileOutputStream(destination);
byte[] b = new byte[2048];
int length;
while ((length = is.read(b)) != -1) {
os.write(b, 0, length);
}
is.close();
os.close();
localPhotosUrl.add(destination.getAbsolutePath());
}
}
}
Maybe you could name the actual exception that is beeing thrown?
It might be a RuntimeException and therefore unchecked.
For further information about checked/unchecked exceptions see: Oracle Docs - Exceptions
The API for InteruptedException says the following;
Thrown when a thread is waiting, sleeping, or otherwise occupied, and
the thread is interrupted, either before or during the activity.
Occasionally a method may wish to test whether the current thread has
been interrupted, and if so, to immediately throw this exception.
As described in the comments of the question, cancelling your AsyncTask only after checking that it has finished should prevent this issue.
Alternatively (but I would recommend against it), you could catch the InteruptedException in the method that cancels your AsyncTask to define your custom catch behavior there. Using catch to work around program logic flaws should only really be a last resort after reconsidering the logical flow of your code.