I am trying to Post Json to my restful API with volley but it doesn't work. So far i have tested my web service by sending a json payload through the Advance rest client app on chrome and it returns a json response.... but when i try it with Volley it returns onErrorResponse. Please can someone tell me how to solve this problem, thanks in advance.
Json payLoad:
{"country":"isreal","mobile":"009988778"}
Code
private void processLogin() {
showProgressDialog();
JsonObjectRequest jsonObjReq = new JsonObjectRequest(Method.POST,
Const.LOGIN_URL, null, new Response.Listener<JSONObject>() {
#Override
public void onResponse(JSONObject response) {
Log.i("JSON response", "JSON Posting" + response.toString());
hideProgessDialog();
}
}, new Response.ErrorListener() {
#Override
public void onErrorResponse(VolleyError volleyError) {
VolleyLog.d(ERROR_TAG, "Error: " + volleyError.getMessage());
hideProgessDialog();
}
}){
#Override
public Map<String, String> getHeaders() throws AuthFailureError {
HashMap<String, String> headers = new HashMap<String, String>();
headers.put("Content-Type", "application/json");
return headers;
}
#Override
protected Map<String, String> getParams(){
String country_value = country.getSelectedItem().toString();
String mobile_value = mobile.getText().toString();
Map<String, String> params = new HashMap<>();
params.put("country",country_value);
params.put("mobile", mobile_value);
return params;
}
};
AppController.getInstance().addToRequestQueue(jsonObjReq, login_tag);
}
What you are doing is, you are trying to send a JSON as a part of Headers which won't work.
This is what you need -
JsonObjectRequest jsonObjReq = new JsonObjectRequest(Method.POST,
Const.LOGIN_URL, **->YOUJSONOBJECTHERE<-**, new Response.Listener<JSONObject>() {
#Override
public void onResponse(JSONObject response) {
Log.i("JSON response", "JSON Posting" + response.toString());
hideProgessDialog();
}
}, new Response.ErrorListener() {
#Override
public void onErrorResponse(VolleyError volleyError) {
VolleyLog.d(ERROR_TAG, "Error: " + volleyError.getMessage());
hideProgessDialog();
}
});
You need to send JSONObject as a part of request not as a part of request headers. Try it out and let me, if it fixes the issue else we troubleshoot it.
And as you already using JSONObjectRequest, you niether need to set the content type nor override getParams() until or unless you need to send some extra information in your header like AgentType, tokens etc.
Convert object to json string.
Override getBody of Volley request
object
Override getBodyContentType to set as json
Gson gson = new Gson();
final String json = gson.toJson(loginDTO);
GsonRequest<EmailLoginRestResponse> jsObjRequest = new GsonRequest<EmailLoginRestResponse>(
Request.Method.POST, url,
EmailLoginRestResponse.class, null,
this.createLoginRequestSuccessListener(),
this.createLoginErrorListener()){
#Override
public byte[] getBody() throws AuthFailureError {
return json.getBytes();
}
#Override
public String getBodyContentType() {
return "application/json; charset=" + this.getParamsEncoding();
}
};
jsObjRequest.setShouldCache(false);
this.mRequestQueue.add(jsObjRequest);
GsonRequest.java
https://github.com/ogrebgr/android_volley_examples/blob/master/src/com/github/volley_examples/toolbox/GsonRequest.java
Related
I am trying to upload data to my web app using a REST API. I need to send an image with other parameters as multipart data. I have the method below based on some posts that I have viewed on here. When the request is submitted it fails and from the server logs it looks like it is not reading the parameters and failing with the ID.
I am confused as how to structure the request using Volley. If I send the equivalent using Insomnia as shown below then it is successful. I have replicated using the same bearer token.
private void uploadPicture() {
progressDialog = new ProgressDialog(CameraActivity.this);
progressDialog.setMessage("Uploading, please wait...");
progressDialog.show();
Log.d("URL", URL + PICNS);
//converting image to base64 string
ByteArrayOutputStream baos = new ByteArrayOutputStream();
Bitmap compressedImg = getResizedBitmap(imageBitmap,600);
compressedImg.compress(Bitmap.CompressFormat.PNG, 100, baos);
byte[] imageBytes = baos.toByteArray();
final String imageString = Base64.encodeToString(imageBytes, Base64.DEFAULT);
Log.d("TOKEN", token);
//sending image to server
JsonObjectRequest request = new JsonObjectRequest(Request.Method.POST,URL + PICNS,null, new Response.Listener<JSONObject>(){
#Override
public void onResponse(JSONObject response) {
progressDialog.dismiss();
Log.d("RESPONSE", response.toString());
}
},new Response.ErrorListener(){
#Override
public void onErrorResponse(VolleyError volleyError) {
Log.d("Error", volleyError.toString());
Toast.makeText(CameraActivity.this, "Some error occurred -> "+volleyError, Toast.LENGTH_LONG).show();;
}
}) {
//adding parameters to send
#Override
protected Map<String, String> getParams() throws AuthFailureError {
Map<String, String> parameters = new HashMap<String, String>();
parameters.put("route_id","1");
parameters.put("lat","52.395728");
parameters.put("lng","-1.992031");
parameters.put("description", " ");
parameters.put("caption", "Wow Uploaded This");
parameters.put("picture", imageString);
return parameters;
}
#Override
public Map<String, String> getHeaders() throws AuthFailureError {
Map<String, String> headers = new HashMap<>();
headers.put("Authorization", "Bearer " + token);
return headers;
}
};
RequestQueue rQueue = Volley.newRequestQueue(CameraActivity.this);
rQueue.add(request);
}
I used the library from here to get send the multipart request and it seems to be working for me.
I need to make an api request which.
Two headers :
Accept
Authorization
Five body params.
Number
Make
Model
Description
Plates
Through postman everything works great.
But when i try through android app i can't get through.
Note: Login through the same host works great so the setup its not the problem i think my main problem is in api call.
public void add(View view) {
RequestQueue queue = Volley.newRequestQueue(this);
String URL = "http://10.0.2.2:8000/api/trucks";
StringRequest request = new StringRequest(Request.Method.POST, URL,
new Response.Listener<String>() {
#Override
public void onResponse(String response) {
try {
JSONObject jsonObj = new JSONObject(response);
// parse response
} catch (JSONException e) {
e.printStackTrace();
}
}
},
new Response.ErrorListener() {
#Override
public void onErrorResponse(VolleyError error) {
NetworkResponse response = error.networkResponse;
String errorMsg = "";
if (response != null && response.data != null) {
String errorString = new String(response.data);
}
}
}
) {
#Override
public Map<String, String> getHeaders() {
HashMap<String, String> headers = new HashMap<>();
headers.put("Accept", "application/json");
headers.put("Authorization", "Bearer " + myToken);
return headers;
}
#Override
protected Map<String, String> getParams() {
Map<String, String> params = new HashMap<String, String>();
TextInputEditText number = findViewById(R.id.textInputEditTextNumber);
TextInputEditText make = findViewById(R.id.textInputEditTextMake);
TextInputEditText model = findViewById(R.id.textInputEditTextModel);
TextInputEditText description = findViewById(R.id.textInputEditTextDescription);
TextInputEditText plates = findViewById(R.id.textInputEditTextPlates);
params.put("number", number.getText().toString());
params.put("make", make.getText().toString());
params.put("model", model.getText().toString());
params.put("description", description.getText().toString());
params.put("plates", plates.getText().toString());
return params;
}
};
queue.add(request);
}
Edit: by Solution #1.
public void add(View view) throws JSONException {
RequestQueue queue = Volley.newRequestQueue(this);
TextInputEditText number = findViewById(R.id.textInputEditTextNumber);
TextInputEditText make = findViewById(R.id.textInputEditTextMake);
TextInputEditText model = findViewById(R.id.textInputEditTextModel);
TextInputEditText description = findViewById(R.id.textInputEditTextDescription);
TextInputEditText plates = findViewById(R.id.textInputEditTextPlates);
JSONObject jsonObject = new JSONObject();
jsonObject.put("Number", number.getText().toString());
jsonObject.put("Make", make.getText().toString());
jsonObject.put("Model", model.getText().toString());
jsonObject.put("Description", description.getText().toString());
jsonObject.put("Plates", plates.getText().toString());
final String requestBody = jsonObject.toString();
JsonObjectRequest jsonRequest = new JsonObjectRequest(Request.Method.POST, "http://10.0.2.2:8000/api/trucks", jsonObject,
new Response.Listener<JSONObject>() {
#Override
public void onResponse(JSONObject response) {
//now handle the response
Toast.makeText(truck_add.this, response.toString(), Toast.LENGTH_SHORT).show();
}
}, new Response.ErrorListener() {
#Override
public void onErrorResponse(VolleyError error) {
//handle the error
Toast.makeText(truck_add.this, "An error occurred", Toast.LENGTH_SHORT).show();
error.printStackTrace();
}
}) { //this is the part, that adds the header to the request
#Override
public Map<String, String> getHeaders() {
Map<String, String> params = new HashMap<String, String>();
params.put("Accept", "application/json");
params.put("Authorization", myToken);
return params;
}
};
queue.add(jsonRequest);
}
Postman :
When you want to pass the data through the body, you need to create a json object before string request.
try this way,
1. create a string url for request.
2. create json object for body data and pass data to it. Like,
JSONObject jsonObject= new JSONObject();
jsonObject.put("Number", address.getNumber());
jsonObject.put("Make", address.getMake());
jsonObject.put("Model", address.getModel());
jsonObject.put("Description", address.getDescription());
jsonObject.put("Plates", address.getPlates());
final String requestBody=jsonObject.toString();
3. After this, apply stringRequest.
4. Now, add below lines before header method and after error method.
#Override
public String getBodyContentType() {
return "application/json; charset=utf-8";
}
#Override
public byte[] getBody() throws AuthFailureError {
try {
return requestBody == null ? null : requestBody.getBytes("utf-8");
} catch (UnsupportedEncodingException uee) {
VolleyLog.wtf("Unsupported Encoding while trying to get the bytes of %s using %s", requestBody, "utf-8");
return null;
}
5. In your getHeaders() method, use Content-Type for "application/json" and for Authorization you must use only token without (Bearer).
Done.
public void add(View view) throws JSONException {
String URL = "http://10.0.2.2:8000/api/trucks";
//removed views initialization from here.
//you need to initialize views in oncreate() / oncreateView() method.
/*first create json object in here.
then set keys as per required body format with values
*/
JSONObject jsonObject = new JSONObject();
jsonObject.put("Number", number.getText().toString());
jsonObject.put("Make", make.getText().toString());
jsonObject.put("Model", model.getText().toString());
jsonObject.put("Description", description.getText().toString());
jsonObject.put("Plates", plates.getText().toString());
final String requestBody = jsonObject.toString();
RequestQueue queue = Volley.newRequestQueue(this);
StringRequest request = new StringRequest(Request.Method.POST, URL,
new Response.Listener<String>() {
#Override
public void onResponse(String response) {
try {
JSONObject jsonObj = new JSONObject(response);
// parse response
} catch (JSONException e) {
e.printStackTrace();
}
}
},
new Response.ErrorListener() {
#Override
public void onErrorResponse(VolleyError error) {
NetworkResponse response = error.networkResponse;
String errorMsg = "";
if (response != null && response.data != null) {
String errorString = new String(response.data);
}
}
}
) { //this is the part, that adds the header to the request
//this is where you need to add the body related methods
#Override
public String getBodyContentType() {
return "application/json; charset=utf-8";
}
#Override
public byte[] getBody() throws AuthFailureError {
try {
return requestBody == null ? null : requestBody.getBytes("utf-8");
} catch (UnsupportedEncodingException uee) {
VolleyLog.wtf("Unsupported Encoding while trying to get the bytes of %s
using %s", requestBody, "utf-8");
return null;
}
#Override
public Map<String, String> getHeaders() {
Map<String, String> params = new HashMap<String, String>();
params.put("Content-Type", "application/json");
params.put("Authorization", myToken);
return params;
}
};
queue.add(jsonRequest);
}
Put Log in every method to check which method being executed and for possible error
If there is an error after this, then post error from logcat and we will solve it quickly.
i have googled and looked into other SO articles. but none helped. Please help me identify what is the problem. What i did was i want to change from StringRequest to JsonObjectRequest
I am getting this error:
com.android.volley.ParseError: org.json.JSONException: End of input at character 0 of
MY CODE
RequestQueue queue = Volley.newRequestQueue(this);
String url = "http://"+employee.get_ip_address()+"/NextrackAndroid/authenticate.php";
Log.d("TAG", "URL : "+ url);
JSONObject obj = new JSONObject();
try {
obj.put("id", id.toString());
obj.put("deviceID", deviceID.toString());
Log.d("TAG", obj.toString());
} catch (JSONException e) {
e.printStackTrace();
}
JsonObjectRequest jsObjRequest = new JsonObjectRequest(Request.Method.POST,url,obj,
new Response.Listener<JSONObject>() {
#Override
public void onResponse(JSONObject response) {
Log.d("TAG", "onResponse : " + response);
}
},
new Response.ErrorListener() {
#Override
public void onErrorResponse(VolleyError error) {
Log.d("TAG", "onErrorResponse : " + error.toString());
error.printStackTrace();
}
}){
/** Passing some request headers* */
#Override
public Map getHeaders() throws AuthFailureError {
HashMap headers = new HashMap();
headers.put("Content-Type", "application/json");
return headers;
}
};
queue.add(jsObjRequest);
com.android.volley.ParseError: org.json.JSONException: End of input at character 0 of
This is not your side issue.
This issue persist when your response is not a JSONObject. So your code can not handle it. Because you have taken JsonObjectRequest as response handler.
To overcome this issue.
Check its response on Postman or ask from Web Service developer.
You will find the response of Web-Service is not perfect JSON.
Then ask Web-Service developer to fix this issue.
Or change your JsonObjectRequest to StringRequest if response is not JSON from server side.
I'm using Volley Android for POST some data to a Restful Api endpoint, using postman it works great body data in raw and application/json e.g:
{
"operation": "someaction",
"key": "pk_test_fssdfsdfjkhkjsdhf84334",
"token": "tk_test_432332sdxxaJJJJHHHshhsas",
"ssids":[[{
"mac":"34:15:13:d4:59:f1" //<--this is important here, it's mac addr
}]] //<-- yup, with double double [[ ... ]]
}
It works using POSTMAN and returns
The issue starts when I use volley in the code below:
public void getBleeCardData(Response.Listener<String> response, final String ssidsdata, final ProgressDialog pd)throws JSONException {
String url = "https://www......com/api/something.do";
JSONObject jsonBody = new JSONObject();
jsonBody.put("operation", "something");
jsonBody.put("key", "pk_try_oqiwFHFKjkj4XMrh");
jsonBody.put("token", "tk_tkn_erwweelWgH4olfk2");
jsonBody.put("ssids", ssidsdata.toLowerCase());
final String mRequestBody = jsonBody.toString();
RequestQueue queue = Volley.newRequestQueue(context);
StringRequest postRequest = new StringRequest(Request.Method.POST, url,new Response.Listener<String>() {
#Override
public void onResponse(String response) {
Log.d("Response", response);
}
},
new Response.ErrorListener() {
#Override
public void onErrorResponse(VolleyError error) {
Log.d("ERROR", "error => " + error.toString());
}
}
) {
#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
public String getBodyContentType() {
return "application/x-www-form-urlencoded; charset=UTF-8";
}
};
queue.add(postRequest.setRetryPolicy(new DefaultRetryPolicy(30000,
DefaultRetryPolicy.DEFAULT_MAX_RETRIES,
DefaultRetryPolicy.DEFAULT_BACKOFF_MULT))); }
I need help with the encoding, using Volley the data sent like:
{"operation":"dataMachines","key":"pk_test_6pRNAHGGoqiwFHFKjkj4XMrh","token":"tk_test_ZQokik736473jklWgH4olfk2","ssids":"[[{\"mac\":\"34:15:13:d4:59:f1\"}]]"}
Why is sending this node like "ssids":"[[{\"mac\":\"34:15:13:d4:59:f1\"}]]"}like this?, What about the "\", some special encoding to remove it?
Is possible change the encoding to prevent those "\"?
Create a JsonObjectRequest
JSONObject jsonBody = new JSONObject();
jsonBody.put("operation", "something");
jsonBody.put("key", "pk_try_oqiwFHFKjkj4XMrh");
jsonBody.put("token", "tk_tkn_erwweelWgH4olfk2");
jsonBody.put("ssids", ssidsdata.toLowerCase());
JsonObjectRequest jobReq = new JsonObjectRequest(Request.Method.POST, url, jsonBody,
new Response.Listener<JSONObject>() {
#Override
public void onResponse(JSONObject jsonObject) {
//Log.d("Responses", jsonObject.toString());
}
},
new Response.ErrorListener() {
#Override
public void onErrorResponse(VolleyError volleyError) {
//Log.e("responses", volleyError.toString());
}
});
if you are sending JSONArray then instead of JsonObjectRequest use JsonArrayRequest
JSONObject obmacAdd=new JSONObject();
JSONArray array=new JSONArray();
obmacAdd.put("mac","34:15:13:d4:59:f1");
array.put(obmacAdd.toString());
now
jsonBody.put("ssids", array.toString());
According to the android code,the below expects a string,while you are parsing an object:
jsonBody.put("ssids", ssidsdata.toLowerCase());
You could make the ssid seperately then add it in the json body like this:
JSONObject ssid= new JSONObject();
ssid.put("mac":"34:15:13:d4:59:f1");
ssid.put("key2","Value2");
The add the ssid object into your Json object to send:
JSONObject jsonBody = new JSONObject();
jsonBody.put("operation", "something");
jsonBody.put("key", "pk_try_oqiwFHFKjkj4XMrh");
jsonBody.put("token", "tk_tkn_erwweelWgH4olfk2");
jsonBody.put("ssids", ssid);
As well explaned here: Pass an object containing key value pairs, as a value to a hashmap in Java/Android
I'm attempting to do a PUT in x-www-form-urlencoded to a drupal table with Volley from my Android app. I'm try to send a 'type' and 'value', in the params and I get a 500 error. A basic StringRequest returns 404.
Here's my latest code. I've only found one or two entries that touch on the Volley Put. Any help would be appreciated. Have a great day.
private void postTestAnswerResult(String id, String answerResult) {
StringRequest req = null;
requestQueue = Volley.newRequestQueue(this);
final String baseURL = "http://blah.blah.com/api/answer/";
String URL = baseURL + id;
// Post params to be sent to the server
HashMap<String, String> params = new HashMap<String, String>();
params.put("Content-Type","application/x-www-form-urlencoded");
params.put("type", answerResult);
req = new StringRequest(Request.Method.PUT, URL,
new Response.Listener<String>() {
#Override
public void onResponse(String response) {
VolleyLog.v("Response:%n %s", response.toString());
}
},
new Response.ErrorListener() {
#Override
public void onErrorResponse(VolleyError volleyError) {
try {
String responseBody = new String(
volleyError.networkResponse.data, "utf-8");
JSONObject jsonObject = new JSONObject(responseBody);
} catch (JSONException e) {
// Handle a malformed json response
} catch (UnsupportedEncodingException error) {
}
}
}
);
requestQueue.add(req);
}
In case you are still having problems with this, as #Meier points out in a comment above, you are not using the params variable, or rather you aren't using it correctly. The data doesn't get sent to the server, and the server is probably expecting the data resulting in the 500 error.
You need to override the getParams method of the StringRequest call in order to send the data. So, the following would be closer to getting the job done:
private void postTestAnswerResult(String id, String answerResult) {
StringRequest req = null;
requestQueue = Volley.newRequestQueue(this);
final String baseURL = "http://blah.blah.com/api/answer/";
String URL = baseURL + id;
req = new StringRequest(Request.Method.PUT, URL,
new Response.Listener<String>() {
#Override
public void onResponse(String response) {
VolleyLog.v("Response:%n %s", response.toString());
}
},
new Response.ErrorListener() {
#Override
public void onErrorResponse(VolleyError volleyError) {
try {
String responseBody = new String(
volleyError.networkResponse.data, "utf-8");
JSONObject jsonObject = new JSONObject(responseBody);
} catch (JSONException e) {
// Handle a malformed json response
} catch (UnsupportedEncodingException error) {
}
}
}
) {
#Override
protected Map<String, String> getParams()
{
HashMap<String, String> params = new HashMap<String, String>();
// params.put("Content-Type","application/x-www-form-urlencoded"); This shouldn't be here. This is a HTTP header. If you want to specify header you should also override getHeaders.
params.put("type", answerResult);
return params;
}
};
requestQueue.add(req);
Browser don't ignore 500 errors. They very often show up as ugly messages in the browser window.