I am trying to parse an error body of a retrofit enqueue. The log shows the response.errorBody as
"{"response":["Image height must not exceed image width. Try a different image."]}"
Here is my code:
call.enqueue(new Callback<EditBlogResponse>() {
#Override
public void onResponse(Call<EditBlogResponse> call, Response<EditBlogResponse> response) {
if(response.body() != null){
Log.d(TAG, "onEditResponse: " + response.body());
editBlogResponse.setValue(response.body().toString());
}else{
try {
Log.d(TAG, "onResponseError: " + response.errorBody().string());
JSONObject jsonObject = new JSONObject(response.errorBody().string());
JSONArray jsonArray = jsonObject.getJSONArray("response");
editBlogResponse.setValue(jsonArray.getString(0));
} catch (IOException e) {
e.printStackTrace();
} catch (JSONException e) {
e.printStackTrace();
}
}
}
#Override
public void onFailure(Call<EditBlogResponse> call, Throwable t) {
t.printStackTrace();
editBlogResponse.setValue("failure");
}
});
I receive a system error
W/System.err: org.json.JSONException: End of input at character 0 of
at org.json.JSONTokener.syntaxError(JSONTokener.java:460)
at org.json.JSONTokener.nextValue(JSONTokener.java:101)
at org.json.JSONObject.<init>(JSONObject.java:164)
at org.json.JSONObject.<init>(JSONObject.java:181)
at com.example.brandonblog.Repository.Repository$3.onResponse(Repository.java:176)
at retrofit2.DefaultCallAdapterFactory$ExecutorCallbackCall$1$1.run(DefaultCallAdapterFactory.java:83)
at android.os.Handler.handleCallback(Handler.java:883)
at android.os.Handler.dispatchMessage(Handler.java:100)
at android.os.Looper.loop(Looper.java:214)
at android.app.ActivityThread.main(ActivityThread.java:7356)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:492)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:930)
Any ideas on what I am doing wrong?
Well, in that case, your expected response is also inside the onResponse() block. you have to lookup into block for the 400 or 4xx status code like this:
if(response.code() != 200) {
Log.d(TAG, "onEditResponseCode: " + response.code());
Log.d(TAG, "onEditResponse: " + response.body());
editBlogResponse.setValue(response.body().toString());
} else {
Log.d(TAG, "onEditResponsecode: " + response.code());
Log.d(TAG, "onEditResponse: " + response.body().response.get(0));
//because your message is always at the 0th position of the 'response' list
// You don't need to use any JSONObject or JSONArray etc for these.
}
Try and let me know if it works.
Got it working, the problem was this line:
editBlogResponse.setValue(jsonArray.getString(0));
Instead of getString, it should be get():
editBlogResponse.setValue(array.get(0).toString());
Full working response:
public void onResponse(Call<EditBlogResponse> call, Response<EditBlogResponse> response) {
if(response.body() != null){
Log.d(TAG, "onEditResponse: " + response.body());
editBlogResponse.setValue(response.body().toString());
}else{
try {
JSONObject jObjError = new JSONObject (response.errorBody().string());
JSONArray array = jObjError.getJSONArray("response");
editBlogResponse.setValue(array.get(0).toString());
} catch (JSONException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}
}
Related
I'm trying to do something similar to the answer of this question
I'm using Volley rather than Retrofit, and have adapted my code accordingly. For me the callback handlers never actually fire, although the counDownLatch does timeout after the specified number of seconds. I suspect the handlers never fire because the countDownLatch.awaiting is using all the processing on the current thread. Or am I missing something else?
public void queryUmbrellaServer() {
ArrayList<String> identifiers = getHardwareIdentifiers(context);
VolleyLog.DEBUG = true;
CountDownLatch countDownLatch = new CountDownLatch(identifiers.size());
// creating a new variable for our request queue
final RequestQueue[] queue = {Volley.newRequestQueue(context)};
queue[0].start();
for (int i = 0; i < identifiers.size(); i++) {
String url = umbrellaServerUrl + identifiers.get(i) + "/";
Log.i(LOG_TAG, "Inside Loop " + url);
JsonObjectRequest jsonObjectRequest = new JsonObjectRequest(Request.Method.GET, url, null,
new Response.Listener<JSONObject>() {
#Override
public void onResponse(JSONObject response) {
try {
countDownLatch.countDown();
String serverName = response.getString("mdm_server_url");
String registrationUrl = response.getString("registration_url");
String isDeviceOwner = response.getString("device_owner");
Toast.makeText(context, "Retrieved server name from umbrella server: " + serverName, Toast.LENGTH_LONG).show();
setMdmInfo(serverName, registrationUrl, isDeviceOwner);
Log.i(LOG_TAG, "Successful response");
//queue[0].stop();
results.add(isDeviceOwner.toString());
} catch (JSONException e) {
e.printStackTrace();
Log.d(LOG_TAG, "Error in parsing response");
}
}
}, new Response.ErrorListener() {
#Override
public void onErrorResponse(VolleyError error) {
countDownLatch.countDown();
if(error.networkResponse.data!=null) {
String jsonString = new String(error.networkResponse.data);
//Log.d(LOG_TAG, jsonString);
try {
JSONObject jsonObject = new JSONObject(jsonString);
String msg = jsonObject.getString("message");
if (!msg.equals("Device not found")) {
Log.d(LOG_TAG, "Error in retrieving response from server");
//queue[0].stop();
results.add("false");
}
else {
Log.d(LOG_TAG, "No device found");
results.add("false");
}
} catch (JSONException e) {
e.printStackTrace();
Log.d(LOG_TAG, "Error in retrieving response from server");
//queue[0].stop();
results.add("UNSET");
}
}
else {
Log.d(LOG_TAG, "Error in retrieving response from server");
//queue[0].stop();
results.add("UNSET");
}
}
});
// Add the request to the RequestQueue.
queue[0].add(jsonObjectRequest);
}
try {
countDownLatch.await(1L * identifiers.size(), TimeUnit.SECONDS); // join thread with timeout of second for each item
} catch (InterruptedException e) {
e.printStackTrace();
}
Log.d(LOG_TAG,"outside loop" + results);
}
I expected the results arrayList should get populated before the countDownLatch countdown completes, but I haven't been able to get any results.
I declared a global JSONArray variable to return in okHttpCallback function but it returns null. I am getting data,But while returning it is null
JSONArray jsonArray; //Global in class
public JSONArray getJsonString(String link){
okHttpClient.newCall(request).enqueue(new Callback() {
#Override
public void onResponse(#NotNull Call call, #NotNull Response response) throws IOException {
if(response.isSuccessful()){
try {
jsonArray = new JSONArray(response.body().string());
}catch (JSONException e){
e.printStackTrace();
}
}else{
Log.d("ERROR", "onResponse: ERROR" + response.body().string());
}
}
});
return jsonArray; // Null Here
}
Actually the network call is taking place in another thread and you are returning jsonArray in main thread. You should return jsonArray only when you get response through okhttp.
You should do as follows :-
public void getJsonResponse(String link){
okHttpClient.newCall(request).enqueue(new Callback() {
#Override
public void onResponse(#NotNull Call call, #NotNull Response response) throws IOException {
if(response.isSuccessful()){
try {
jsonArray = new JSONArray(response.body().string());
getJsonString(jsonArray);
}catch (JSONException e){
e.printStackTrace();
}
}else{
Log.d("ERROR", "onResponse: ERROR" + response.body().string());
}
}
});
}
// somewhere in class
public JSONArray getJsonString(JSONArray jsonArr)
{
return jsonArr;
}
I want to know if the server is down or not when i do a request, basicly i am trying to do a simple register(it already works) but if put the nodeJS server down when i click the register it doesn't appear any error on my toast, i tried to follow some answers that i found but nothing works
Here is what i tried:
public void notifyError(String requestType,VolleyError error) {
String body;
if(error.networkResponse.data!=null) {
String statusCode = String.valueOf(error.networkResponse.statusCode);
try {
if (error instanceof NetworkError) {
Log.d("internet","nao tem internet ligada");
}
else if (error instanceof ServerError) {
Log.d("internet","The server could not be found. Please try again after some time!!");
}
body = new String(error.networkResponse.data,"UTF-8");
JSONObject jsonObj = new JSONObject(body);
Log.d("body",String.valueOf(jsonObj.get("message")));
showToast(String.valueOf(jsonObj.get("message")));
} catch (UnsupportedEncodingException e) {
showToast("You need to connect to the internet!");
} catch (JSONException e) {
Log.d("json:","problems decoding jsonObj");
}
}
For any question related to how i construct the volley example i followed this thread
The messages inside the NEtwork error and serverError never show, any tip?
remove the "if" condition, error.networkResponse.data return null.
public void notifyError(String requestType,VolleyError error) {
String body;
String statusCode = String.valueOf(error.networkResponse.statusCode);
try {
if (error instanceof NetworkError) {
Log.d("internet","nao tem internet ligada");
} else if (error instanceof ServerError) {
Log.d("internet","The server could not be found. Please try again after some time!!");
}
body = new String(String.valueOf(error.networkResponse.statusCode),"UTF-8");
JSONObject jsonObj = new JSONObject(body);
Log.d("body",String.valueOf(jsonObj.get("message")));
showToast(String.valueOf(jsonObj.get("message")));
} catch (UnsupportedEncodingException e) {
showToast("You need to connect to the internet!");
} catch (JSONException e) {
Log.d("json:","problems decoding jsonObj");
}
}
{
"status":"ok",
"cookie":"dr.steve|akscjn",
"cookie_name":"wordpress_logged_in",
"user": {
"id":330,
"username":"dr.steve",
"nicename":"steve",
"email":"steve#docdirect.com",
"url":"http:\/\/www.company.com",
"registered":"2016-12-15 22:21:05",
"displayname":"Dr.Steve",
"firstname":"Dr",
"lastname":"Steve",
"nickname":"steve",
"description":"Lorem ipsum",
"capabilities":"",
"avatar":null
}
}
I have this json response and i want the only id field from this json , I think there are two nested arrays but i am geting error
E/Error: Json parsing error: Value {"id":330,.........}at user of type org.json.JSONObject cannot be converted to JSONArray
this my code
if (jsonStr != null) {
try {
JSONArray ja = new JSONObject(jsonStr).getJSONArray("user");
JSONObject c = ja.getJSONObject(1);
String id = c.getString("id");
temp2 = id;
Log.v("id---->",temp2);
}
} catch (final JSONException e) {
Log.e("Error", "Json parsing error: " + e.getMessage());
runOnUiThread(new Runnable() {
#Override
public void run() {
Toast.makeText(getApplicationContext(),
"Json parsing error: " + e.getMessage(),
Toast.LENGTH_LONG)
.show();
}
});
}
} else {
Log.e("Error", "Couldn't get json from server.");
runOnUiThread(new Runnable() {
#Override
public void run() {
Toast.makeText(getApplicationContext(),
"Couldn't get json from server. Check LogCat for possible errors!",
Toast.LENGTH_LONG)
.show();
}
});
}
can anyone tell where i am making a mistake how would i get id field from this json ?
The user property is a concrete object not an array so try to read it as an object:
JSONObject user = new JSONObject(jsonStr).getJSONObject("user");
"user":{ is an object.
Arrays have square brackets. You have no arrays in your data
I am trying to make an application that is supposed to work on devices that doesn't have Play Services installed. Currently I'm on login, using webview. I have successfully received an authorization code here, & to retrive access token, I am using following snippet, (from https://developers.google.com/api-client-library/java/google-api-java-client/reference/1.20.0/com/google/api/client/googleapis/auth/oauth2/GoogleAuthorizationCodeTokenRequest)
Somehow, on GoogleTokenResponse , appplication crashes at .execute()... What I am supposed to change here?
#Override
public void onPageFinished(android.webkit.WebView view, String url) {
super.onPageFinished(view, url);
if (url.startsWith(OAuth2Client.REDIRECT_URI)) {
try {
if (url.indexOf("code=") != -1) {
String code = extractCodeFromUrl(url);
try {
GoogleTokenResponse response =
new GoogleAuthorizationCodeTokenRequest(new NetHttpTransport(), new JacksonFactory(),
OAuth2Client.CLIENT_ID, OAuth2Client.CLIENT_SECRET,
code, OAuth2Client.REDIRECT_URI)
.execute(); //debugging stops here!!
System.out.println("Access token: " + response.getAccessToken());
} catch (TokenResponseException e) {
if (e.getDetails() != null) {
System.err.println("Error: " + e.getDetails().getError());
if (e.getDetails().getErrorDescription() != null) {
System.err.println(e.getDetails().getErrorDescription());
}
if (e.getDetails().getErrorUri() != null) {
System.err.println(e.getDetails().getErrorUri());
}
} else {
System.err.println(e.getMessage());
}
}
} else if (url.indexOf("error=") != -1) {
OAuth2Client.ClearAccessToken(getApplicationContext());
}
} catch (IOException e) {
e.printStackTrace();
}
}
System.out.println("onPageFinished : " + url);
}