How to get JSON error response in Volley onErrorResponse - android

I have an API call with below details
URL: http://pankajservers.in/api/v1/AuthenticateUser with Input params
below
EmailAddress and Password
if I type wrong credentials, I get below JSON response with Status Code : 403
{"Status":false,"Message":"Invalid Credentials. 5 attempts left.","Data":null}
Below is the Error Response Code.
new Response.ErrorListener()
{
#Override
public void onErrorResponse(VolleyError error)
{
if (null != error.networkResponse)
{
Log.d(TAG + ": ", "Error Response code: " + error.networkResponse.statusCode);
}
}
});
Is there any way to get JSON response in this code block?
I tried this post: Volley handle onErrorResponse
But it seems it never execute parseNetworkError

To print the Error on that block you just need to obtain the Response bytes:
NetworkResponse networkResponse = error.networkResponse;
if (networkResponse != null && networkResponse.data != null) {
String jsonError = new String(networkResponse.data);
// Print Error!
}

You can create custom request like this:
public class BaseRequest extends Request {
private static final String TAG = BaseRequest.class.getSimpleName();
private final Gson gson = new Gson();
private final Response.Listener listener;
public BaseRequest(String url, Response.Listener responseListener, Response.ErrorListener listener) {
super(Request.Method.GET, url, listener);
Log.e(TAG, "Requesting url : " + url);
this.listener = responseListener;
}
public BaseRequest(int method, String url, Response.Listener responseListener, Response.ErrorListener listener) {
super(method, url, listener);
Log.e(TAG, "Requesting url : " + url);
this.listener = responseListener;
}
#Override
public Response parseNetworkResponse(NetworkResponse response) {
try {
String json = null;
json = new String(
response.data,
HttpHeaderParser.parseCharset(response.headers));
JSONObject result = new JSONObject(json);
if (!result.getBoolean("Status"))
return Response.success(
result.get("Data"),
HttpHeaderParser.parseCacheHeaders(response));
else
return Response.error(new VolleyError(result.getString("Message")));
} catch (UnsupportedEncodingException e) {
return Response.error(new ParseError(e));
} catch (JsonSyntaxException e) {
return Response.error(new ParseError(e));
} catch (JSONException e) {
return Response.error(new ParseError(e));
}
}
#Override
protected VolleyError parseNetworkError(VolleyError volleyError) {
return volleyError;
}
#Override
protected void deliverResponse(Object response) {
listener.onResponse(response);
}
}
and make request:
BaseRequest baseRequest = new BaseRequest(Request.Method.POST, url, new Response.Listener() {
#Override
public void onResponse(Object response) {
}
}, new Response.ErrorListener() {
#Override
public void onErrorResponse(VolleyError error) {
Log.e(TAG, "Error : " + error.getMessage());
}
}) {
#Override
protected Map<String, String> getParams() throws AuthFailureError {
Map<String, String> params = new HashMap<>();
//Your parameters
return params;
}
};
queue.add(baseRequest);

You can cast an error response to a Json Object
JSONObject jsonObject = new JSONObject();
JsonObjectRequest JO = new JsonObjectRequest(Request.Method.POST,"URL String Here",jsonObject, new Response.Listener<JSONObject>() {
#Override
public void onResponse(JSONObject response) {
//Your Logic
}
}, new Response.ErrorListener() {
#Override
public void onErrorResponse(VolleyError error) {
try {
JSONObject JO = new JSONObject(error.toString());
}catch (JSONException e){
e.printStackTrace();
}
}
});

Related

VOLLEY ERROR : Unexpected response code 400

I am trying to send JSON using POST. But I am getting the following error.
Volley: NetworkUtility.shouldRetryException: Unexpected response code 400 for "URL"
I don't understand the issue. If I'm doing anything wrong in the below code, please let me know. Thank you.
private void postDataUsingVolley(String dev_id, String payload_raw) {
try {
RequestQueue requestQueue = Volley.newRequestQueue(this);
JSONObject params = new JSONObject();
params.put("dev_id", dev_id);
params.put("port", "1");
params.put("confirmed", "false");
params.put("payload_raw", payload_raw);
params.put("schedule", "replace");
final String mRequestBody = params.toString();
StringRequest stringRequest = new StringRequest(Request.Method.POST, DOWNLINK_URL, new Response.Listener<String>() {
#Override
public void onResponse(String response) {
Log.i("LOG_VOLLEY", response);
}
}, new Response.ErrorListener() {
#Override
public void onErrorResponse(VolleyError error) {
Log.e("LOG_VOLLEY", error.toString());
}
}) {
#Override
public String getBodyContentType() {
return "application/json; charset=utf-8";
}
#Override
public byte[] getBody() throws AuthFailureError {
try {
return mRequestBody == null ? null : mRequestBody.getBytes("utf-8");
} catch (UnsupportedEncodingException uee) {
VolleyLog.wtf("Unsupported Encoding while trying to get the bytes of %s using %s", mRequestBody, "utf-8");
return null;
}
}
#Override
protected Response<String> parseNetworkResponse(NetworkResponse response) {
String responseString = "";
if (response != null) {
responseString = String.valueOf(response.statusCode);
}
return Response.success(responseString, HttpHeaderParser.parseCacheHeaders(response));
}
};
requestQueue.add(stringRequest);
} catch (JSONException e) {
e.printStackTrace();
}
}
Instead of StringRequest make a JsonObjectRequest directly, put your data in a JSON object and send the request to the network.
Like this:-
private void postDataUsingVolley(String dev_id, String payload_raw) {
JSONObject params = new JSONObject();
try {
params.put("dev_id", dev_id);
params.put("port", "1");
params.put("confirmed", "false");
params.put("payload_raw", payload_raw);
params.put("schedule", "replace");
}
catch (JSONException e) {
e.printStackTrace();
}
JsonObjectRequest request=new JsonObjectRequest(Request.Method.POST, DOWNLINK_URL, params, new Response.Listener<JSONObject>() {
#Override
public void onResponse(JSONObject response) {
Log.d("Response", ""+response);
}
}, new Response.ErrorListener() {
#Override
public void onErrorResponse(VolleyError error) {
Log.e("Error", error.getMessage());
}
}) ;
RequestQueue requestQueue = Volley.newRequestQueue(this);
requestQueue.add(request);
}

custom error Response for volley

I have a Stringrequest in Android Studio and it's working correctly, I mean I get the response on onResponse method, now I want volley to return an error when the error key has true value. how can i do it?
this is my request:
StringRequest stringRequest = new StringRequest(Request.Method.POST, METHOD_ACCOUNT_OTP_REQUEST,
new Response.Listener<String>() {
#Override
public void onResponse(String response) {
Log.i("response", response);
try {
JSONObject jsonObject = new JSONObject(response);
startVerificationActivity(jsonObject.get("sender").toString());
} catch (JSONException e) {
e.printStackTrace();
Log.i("error", e.toString());
}
}
}, new Response.ErrorListener() {
#Override
public void onErrorResponse(VolleyError error) {
}
}){
#Override
protected Map<String, String> getParams() {
Map<String, String> params = new HashMap<String, String>();
params.put("mobilePhoneNumber", phoneNumber);
params.put("clientId", CLIENT_ID);
return params;
};
this is the answer of the server:
{"sender":"10008727","error":true}
all I want is to set volley to run onErrorResponse when error is true in the json.
You can create a new custom AppStringRequest class which inherits from StringRequest and handle the above usecase.
public class AppStringRequest extends StringRequest {
// ... constructor ...
#Override
protected Response<String> parseNetworkResponse(NetworkResponse response) {
// You will receive your response here in the response parameter.
// parse the response and check whether the response has "error":true
String parsed;
try {
parsed = new String(response.data, HttpHeaderParser.parseCharset(response.headers));
} catch (UnsupportedEncodingException e) {
parsed = new String(response.data);
}
// if it's an error, return Response.error(), otherwise, return Response.success()
try {
JSONObject resObj = new JSONObject(parsed);
boolean error = resObj.getBoolean("error");
if (error) {
return Response.error(new VolleyError());
} else {
return Response.success(parsed, HttpHeaderParser.parseCacheHeaders(response));
}
} catch (JSONException e) {
e.printStractTrace()
// your server response has some issues
}
return Response.error(new VolleyError("Error message")); // can send error message in the VolleyError
}
}
Then you have to use this AppStringRequest instead of the default StringRequest.
StringRequest stringRequest = new AppStringRequest(Request.Method.POST, METHOD_ACCOUNT_OTP_REQUEST,
... )
The error message will be available in the onErrorResponse:
#Override
public void onErrorResponse(VolleyError error) {
Log.i("Volley error", error.toString()); //the error message
}

Android Send POST of JSON raw body with volley

I have to send a post with voley but when i try to send raw body as requested, instead of a response a get this error
******com.android.volley.ServerError******: {"message":"No user account data for registration received."}
i tried the same in postman and it works perfect, how can i fix it in my code?
raw body that works in postman ->
{
"camp1": {
"value": "value"
},
"camp2": {
"value": "value2"
}
}
this is what it is in my code ->
public void requestRegistrationInfo(#NonNull final String camp1, #NonNull final String camp2,final Listener listener) {
RequestQueue requestQueue = Volley.newRequestQueue(context);
requestQueue.add(new JsonObjectRequest(
Request.Method.POST, URL,
new Response.Listener<JSONObject>() {
#Override
public void onResponse(JSONObject response) {
Log.v("IT WORK");
listener.onSuccess();
}
},
new Response.ErrorListener() {
#Override
public void onErrorResponse(VolleyError error) {
Log.e("******" + error.toString() + "******", getErrorMessage(error));
listener.onFailure();
}
})
{
#Override
protected Map<String,String> getParams() {
Map<String, String> map = new HashMap<>();
map.put("{camp1", "value");
map.put("camp2", "value");
return map;
}
#Override
public Map<String, String> getHeaders() throws AuthFailureError {
Map<String, String> map = new HashMap<>();
map.put("header1", "header1");
map.put("header2", "header2");
return map;
}
});
}
what can i do to send raw json correctly and don't show the error?
In normal case JSONObject request didn't hit the getParams() method , this method only for String request and passing key value pair data payload. If you want to pass a raw body with JSON data , first you have to format your data as server accepted.
In your case this is your data
{
"camp1":{
"value":"value1"
},
"camp2":{
"value2":"value2"
}
}
You have to convert your data to Server accepted JSON format like this
JSONObject jsonObject = new JSONObject();
jsonObject.put("value", "value1");
JSONObject jsonObject1 = new JSONObject();
jsonObject1.put("value2", "value2");
JSONObject jsonObject2 = new JSONObject();
jsonObject2.put("camp1", jsonObject);
jsonObject2.put("camp2",jsonObject1);
//jsonObject2 is the payload to server here you can use JsonObjectRequest
String url="your custom url";
JsonObjectRequest jsonObjectRequest = new JsonObjectRequest
(Request.Method.POST,url, jsonObject2, new com.android.volley.Response.Listener<JSONObject>() {
#Override
public void onResponse(JSONObject response) {
try {
//TODO: Handle your response here
}
catch (Exception e){
e.printStackTrace();
}
System.out.print(response);
}
}, new com.android.volley.Response.ErrorListener() {
#Override
public void onErrorResponse(VolleyError error) {
// TODO: Handle error
error.printStackTrace();
}
});
JsonObjectRequest will accept the payload as json in its constructor after the url parameter we will pass the data
This is tested Code try this:
private void multipartRequestWithVolly() {
String urll = "your_url";
progressDialog.show();
StringRequest request = new StringRequest(Request.Method.POST, urll, new Response.Listener<String>() {
#Override
public void onResponse(String response) {
progressDialog.dismiss();
if (!TextUtils.isEmpty(response)) {
Log.e(TAG, "onResponse: " + response);
textView.setText(response);
} else {
Log.e(TAG, "Response is null");
}
}
}, new Response.ErrorListener() {
#Override
public void onErrorResponse(VolleyError error) {
progressDialog.dismiss();
Log.e(TAG, "onErrorResponse: " + error.toString());
}
}) {
#Override
protected Map<String, String> getParams() throws AuthFailureError {
hashMap = new HashMap<>();
hashMap.put("OPERATIONNAME", "bplan");
hashMap.put("mcode", "298225816992");
hashMap.put("deviceid", "dfb462ac78317846");
hashMap.put("loginip", "192.168.1.101");
hashMap.put("operatorid", "AT");
hashMap.put("circleid", "19");
return hashMap;
}
};
AppController.getInstance().addToRequestQueue(request);
}
try {
RequestQueue requestQueue = Volley.newRequestQueue(this);
String URL = "http://...";
JSONObject jsonBody = new JSONObject();
jsonBody.put("Title", "Android Volley Demo");
jsonBody.put("Author", "BNK");
final String requestBody = jsonBody.toString();
StringRequest stringRequest = new StringRequest(Request.Method.POST, URL, new Response.Listener<String>() {
#Override
public void onResponse(String response) {
Log.i("VOLLEY", response);
}
}, new Response.ErrorListener() {
#Override
public void onErrorResponse(VolleyError error) {
Log.e("VOLLEY", error.toString());
}
}) {
#Override
public String getBodyContentType() {
return "application/json; charset=utf-8";
}
#Override
public byte[] getBody() throws AuthFailureError {
try {
return requestBody == null ? null : encodeParameters(requestBody , getParamsEncoding());
} catch (UnsupportedEncodingException uee) {
VolleyLog.wtf("Unsupported Encoding while trying to get the bytes of %s using %s", requestBody, "utf-8");
return null;
}
}
#Override
protected Response<String> parseNetworkResponse(NetworkResponse response) {
String responseString = "";
if (response != null) {
responseString = String.valueOf(response.statusCode);
// can get more details such as response.headers
}
return Response.success(responseString, HttpHeaderParser.parseCacheHeaders(response));
}
};
requestQueue.add(stringRequest);
} catch (JSONException e) {
e.printStackTrace();
}
Please check with the edited getBody()
#Override
public byte[] getBody() throws AuthFailureError {
try {
return requestBody == null ? null : encodeParameters(requestBody , getParamsEncoding());
} catch (UnsupportedEncodingException uee) {
VolleyLog.wtf("Unsupported Encoding while trying to get the bytes of %s using %s", requestBody, "utf-8");
return null;
}
}
If you calling any REST-API then note that that's payload always be in JSON format. therefor you can use an object body for payload like this way.
HashMap<String, String> params = new HashMap<String, String>();
params.put("username", input_loginId.getText().toString());
params.put("password", input_password.getText().toString());
and you can pass this on method like this way
JsonObjectRequest logInAPIRequest = new JsonObjectRequest(Request.Method.POST, YOUR-URL,
new JSONObject(params), new Response.Listener<JSONObject>() {
#Override
public void onResponse(JSONObject response) {
input_errorText.setText(response.toString());
}
}, new Response.ErrorListener() {
#Override
public void onErrorResponse(VolleyError error) {
input_errorText.setText("Error: " + error.getMessage());
}
});

Multipart request using volley returning null as response

Hi I am relatively new to android, I have used multipart request to upload an image to server using volley. The image is being uploaded correctly but I am getting the response as null. I checked on postman, I am strangely getting the correct response there.
MultipartRequest.java
public class MultipartRequest extends Request<JSONObject> {
private static final String FILE_PART_NAME = "user[avatar]";
private long cacheTimeToLive = 0;
private MultipartEntityBuilder mBuilder = MultipartEntityBuilder.create();
private final Response.Listener<JSONObject> mListener;
private final File mImageFile;
protected Map<String, String> headers;
public MultipartRequest(String url, File imageFile, Listener<JSONObject> listener, ErrorListener errorListener){
super(Method.PUT, url,errorListener);
mListener = listener;
mImageFile = imageFile;
buildMultipartEntity();
}
#Override
public Map<String, String> getHeaders() throws AuthFailureError {
Map<String, String> headers = super.getHeaders();
if (headers == null
|| headers.equals(Collections.emptyMap())) {
headers = new HashMap<String, String>();
}
headers.put("Accept", "application/json");
return headers;
}
private void buildMultipartEntity(){
mBuilder.addBinaryBody(FILE_PART_NAME, mImageFile, ContentType.create("image/jpeg"), mImageFile.getName());
mBuilder.setMode(HttpMultipartMode.BROWSER_COMPATIBLE);
mBuilder.setLaxMode().setBoundary("xx").setCharset(Charset.forName("UTF-8"));
}
#Override
public String getBodyContentType(){
String contentTypeHeader = mBuilder.build().getContentType().getValue();
return contentTypeHeader;
}
#Override
public byte[] getBody() throws AuthFailureError{
ByteArrayOutputStream bos = new ByteArrayOutputStream();
try {
mBuilder.build().writeTo(bos);
} catch (IOException e) {
VolleyLog.e("IOException writing to ByteArrayOutputStream bos, building the multipart request.");
}
return bos.toByteArray();
}
#Override
protected Response<JSONObject> parseNetworkResponse(NetworkResponse response) {
JSONObject result = null;
return Response.success(result, HttpHeaderParser.parseCacheHeaders(response));
}
#Override
protected void deliverResponse(JSONObject response) {
mListener.onResponse(response);
}
}
uploadImage method :-
private void uploadImage(final Bitmap bitmap){
String name = "DP_"+ userName +".jpeg";
try {
file=bitmapToFile(name,bitmap);
} catch (IOException e) {
e.printStackTrace();
}
MultipartRequest jsonRequest = new MultipartRequest( UPLOAD_URL,
file,
new Response.Listener<JSONObject>() {
#Override
public void onResponse(JSONObject response) {
Log.d(TAG,response.toString());
try {
// parseUserPhotoResponse(response);
Picasso.with(getApplicationContext())
.load(destination)
.placeholder(R.mipmap.placeholder)
.resize(avatarSize, avatarSize)
.centerCrop()
.transform(new CircleTransformation())
.into(ivUserProfilePhoto);
} catch (Exception e) {
e.printStackTrace();
}
}
},
new Response.ErrorListener() {
#Override
public void onErrorResponse(VolleyError volleyError) {
Log.d(TAG, "Error: " + volleyError.getMessage());
if(volleyError!=null)
{
try {
NetworkResponse networkResponse = volleyError.networkResponse;
if (networkResponse != null) {
String responseBody = new String(volleyError.networkResponse.data, "utf-8");
JSONObject jsonObject = new JSONObject(responseBody);
Log.d(TAG, "Response body" + responseBody.toString());
Log.d(TAG, jsonObject.toString());
if (jsonObject.getBoolean("error") == false) {
} else {
Toast.makeText(getApplicationContext(), "" + jsonObject.getString("message"), Toast.LENGTH_LONG).show();
}
}
} catch (JSONException e) {
//Handle a malformed json response
} catch (UnsupportedEncodingException error) {
}
}
}
})
;
//Creating a Request Queue
jsonRequest.setShouldCache(false);
MyApplication.getInstance().addToRequestQueue(jsonRequest, "UPLOAD_IMAGE");
}

How to get the JSONObject server response in Volley

protected JSONObject executeGet(String URL) throws CloudAppException {
JSONObject response = new JSONObject();
JsonObjectRequest req = new JsonObjectRequest(Request.Method.GET, URL, null,
new Response.Listener<JSONObject>() {
#Override
public void onResponse(JSONObject serverResponse) {
try {
response = serverResponse;
VolleyLog.v("Response:%n %s", serverResponse.toString(4));
} catch (JSONException e) {
e.printStackTrace();
}
}
}, new Response.ErrorListener() {
#Override
public void onErrorResponse(VolleyError error) {
VolleyLog.e("Error: ", error.getMessage());
}
});
RequestHandler.addToRequestQueue(req);
return response;
}
Ideally, I want to parse the response on my own, but I'm blanking on as to how to get the executeGet method to return the server response.
You need to extend the request class and in your custom request class override the parseNetworkResponse method and do your own parsing.
Here is a sample :
public class CustomRequest extends Request {
// the response listener
private Response.Listener listener;
public CustomRequest(int requestMethod, String url, Response.Listener responseListener, Response.ErrorListener errorListener) {
super(requestMethod, url, errorListener); // Call parent constructor
this.listener = responseListener;
}
// Same as JsonObjectRequest#parseNetworkResponse
#Override
protected Response parseNetworkResponse(NetworkResponse response) {
try {
String jsonString = new String(response.data, HttpHeaderParser.parseCharset(response.headers));
return Response.success(new JSONObject(jsonString),HttpHeaderParser.parseCacheHeaders(response));
} catch (UnsupportedEncodingException e) {
return Response.error(new ParseError(e));
} catch (JSONException je) {
return Response.error(new ParseError(je));
}
}
#Override
public int compareTo(Request other) {
return 0;
}
#Override
protected void deliverResponse(Object response) {
if (listener!=null)
listener.onResponse(response);
}
}

Categories

Resources