I am making a volley request and trying to POST an integer, following this solution Send Int in HashMap with Volley my final code looks like this:
JSONArray jsonArray = new JSONArray();
JSONObject jsonObject = new JSONObject();
try{
jsonObject.put("store",storeId);
jsonObject.put("people", people);
jsonObject.put("date",reserveDate);
jsonObject.put("time", reserveTime);
jsonArray.put(jsonObject);
Log.i("jsonString", jsonObject.toString());
}catch(Exception e){
}
StringRequest stringRequest = new StringRequest(Request.Method.POST, domain + api,
new Response.Listener<String>() {
#Override
public void onResponse(String response) {
Log.e("Response", response);
return;
}
},
new Response.ErrorListener() {
#Override
public void onErrorResponse(VolleyError error) {
Log.e("Error.Response", error.toString());
String json = null;
NetworkResponse response = error.networkResponse;
if(response != null && response.data != null){
switch(response.statusCode){
case 400:
json = new String(response.data);
System.out.println(json);
//json = trimMessage(json, "message");
//if(json != null) displayMessage(json);
break;
}
//Additional cases
}
}
})
{
#Override
protected Map<String,String> getParams(){
Map<String,String> params = new HashMap<String, String>();
params.put("store",storeId);
params.put("people",String.valueOf(people));
params.put("date", "2017-01-04");
params.put("time", reserveTime);
Log.d("params", params.toString());
return params;
}
#Override
public Map<String, String> getHeaders() throws AuthFailureError {
HashMap<String, String> headers = new HashMap<>();
headers.put("Authorization", finalToken);
Log.d("headers", headers.toString());
return headers;
}
};
RequestQueue requestQueue = Volley.newRequestQueue(this);
requestQueue.add(stringRequest);
}
Here I want to POST "people" as an integer but the error message I get is that "people" is a string value, I had declared "people" as :
Integer people = Integer.parseInt(reserveNum);
where reserveNum is a number value from edittext. how do i make "peopel" in my request an integer?
UPDATE
error message is :
{"errors":[{"message":"Invalid type: string (expected integer)","params":{"type":"string","expected":"integer"},"code":0,"dataPath":"/people","schemaPath":"/properties/people/type",.....
I have figured the solution by changing Stringrequest to JSONObject reqeust. By doing so my request will be in a JSON format containing integers instead of strings.
JSONArray jsonArray = new JSONArray();
JSONObject jsonObject = new JSONObject();
try{
jsonObject.put("store",storeId);
jsonObject.put("people", people);
jsonObject.put("date",reserveDay);
jsonObject.put("time", reserveTime);
jsonArray.put(jsonObject);
Log.i("jsonString", jsonObject.toString());
}catch(Exception e){
}
JsonObjectRequest jsonObjectRequest = new JsonObjectRequest(Request.Method.POST, domain + api, jsonObject,
new Response.Listener<JSONObject>(){
#Override
public void onResponse(JSONObject response) {
Log.e("Response", response.toString());
try {
JSONArray arrData = response.getJSONArray("data");
parseData(arrData);
} catch (JSONException e) {
e.printStackTrace();
}
}
},
new Response.ErrorListener(){
#Override
public void onErrorResponse(VolleyError error) {
Log.e("Error.Response", error.toString());
String json = null;
NetworkResponse response = error.networkResponse;
if(response != null && response.data != null){
switch(response.statusCode){
case 400:
json = new String(response.data);
System.out.println(json);
break;
}
//Additional cases
}
}
})
{
#Override
public Map<String, String> getHeaders() throws AuthFailureError {
HashMap<String, String> headers = new HashMap<>();
headers.put("Authorization", finalToken);
Log.d("headers", headers.toString());
return headers;
}
};
RequestQueue requestQueue = Volley.newRequestQueue(this);
requestQueue.add(jsonObjectRequest);
}
try the following code replacing above code:
JSONArray jsonArray = new JSONArray();
JSONObject jsonObject = new JSONObject();
try{
jsonObject.put("store",storeId);
//people is a integer
jsonObject.put("people", people);
jsonObject.put("date",reserveDate);
jsonObject.put("time", reserveTime);
jsonArray.put(jsonObject);
Log.i("jsonString", jsonObject.toString());
}catch(Exception e){
}
JsonObjectRequest stringRequest = new JsonObjectRequest(Request.Method.POST,domain + api, jsonObject,
new Response.Listener<JSONObject>() {
#Override
public void onResponse(String response) {
Log.e("Response", response);
return;
}
},
new Response.ErrorListener() {
#Override
public void onErrorResponse(VolleyError error) {
Log.e("Error.Response", error.toString());
String json = null;
NetworkResponse response = error.networkResponse;
if(response != null && response.data != null){
switch(response.statusCode){
case 400:
json = new String(response.data);
System.out.println(json);
//json = trimMessage(json, "message");
//if(json != null) displayMessage(json);
break;
}
//Additional cases
}
}
})
{
#Override
protected Map<String,String> getParams(){
Map<String,String> params = new HashMap<String, String>();
params.put("store",storeId);
params.put("people",String.valueOf(people));
params.put("date", "2017-01-04");
params.put("time", reserveTime);
Log.d("params", params.toString());
return params;
}
#Override
public Map<String, String> getHeaders() throws AuthFailureError {
HashMap<String, String> headers = new HashMap<>();
headers.put("Authorization", finalToken);
Log.d("headers", headers.toString());
return headers;
}
};
RequestQueue requestQueue = Volley.newRequestQueue(this);
requestQueue.add(stringRequest);
}
Very simple, when parameter data type is integer, then convert the integer to string like this
#Override
protected Map<String, String> getParams() throws AuthFailureError {
int number = 999;
Map<String, String> params = new HashMap<>();
params.put("key", Integer.toString(number));
return params;
}
Related
I have an API that takes a JSONArray as params and it gives a JSONObject as a response. The API is working fine but giving an error
com.android.volley.ParseError: org.json.JSONException: End of input at character 0 of
at com.android.volley.toolbox.JsonArrayRequest.parseNetworkResponse
as I receive the response.
JsonArrayRequest volleyRequest= new JsonArrayRequest(Request.Method.POST, url,
params, res -> {
try {
Log.d("TAG", "PostApiMethod: "+res);
} catch (JSONException e) {
Log.e("TAG", "PostApiMethod: ", e);
}
}, error -> {
Log.e(TAG, "PostApiMethod: ", error);
}
}) {
#Override
public String getBodyContentType() {
return "application/x-www-form-urlencoded; charset=UTF-8";
}
};
VolleySingleton.getInstance(context).addToRequestQueue(volleyRequest);
Is there any way to do this while using Volley.
you can use StringRequest and convert JSONArray to String as parameters and get result as String and map string to JSONObject like this code
JSONArray jsonBody=new JSONArray();
try {
/// add jSONObject inside JSONArray as example
JSONObject jsonObject=new JSONObject();
jsonObject.put("id",1);
jsonObject.put("name","test");
jsonBody.put(jsonObject);
} catch (Exception e) {
e.printStackTrace();
}
final String requestBody = jsonBody.toString();
StringRequest request = new StringRequest(Request.Method.POST, URL, new Response.Listener<String>() {
#Override
public void onResponse(String response) {
textView.setText(response.toString());
try {
JSONObject object=new JSONObject(response);
// do every thing using json object
} catch (JSONException e) {
e.printStackTrace();
}
}
}, new Response.ErrorListener() {
#Override
public void onErrorResponse(VolleyError error) {
Log.d("error",error.toString());
}
}){
#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
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));
}
};
I recommended using retrofit library instead of Volley
I am trying to send a POST request with Volley in Android Studio. However, I would like to set some headers and a body. How can I do this?
In this case, the headers are id and key. Where should I add the body? I have tried to follow the numerous questions about these that are written in StackOverflow. However, it still seems like the headers and the body is not properly sent.
try {
RequestQueue requestQueue = Volley.newRequestQueue(this);
String URL = "https://url.of.the.server";
JSONObject jsonBody = new JSONObject();
jsonBody.put("Content-Type", "application/json");
jsonBody.put("id", "oneapp.app.com");
jsonBody.put("key", "fgs7902nskagdjs");
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 : 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() throws AuthFailureError {
Map<String, String> params = new HashMap<String, String>();
params.put("Content-Type", "application/json");
params.put("id", "oneapp.app.com");
params.put("key", "fgs7902nskagdjs");
return params;
}
#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));
}
};
Log.d("string", stringRequest.toString());
requestQueue.add(stringRequest);
} catch (JSONException e) {
e.printStackTrace();
}
Thank you very much for your help.
You are correctly setting the headers, you could try this
try {
RequestQueue requestQueue = Volley.newRequestQueue(this);
String URL = "https://url.of.the.server";
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 {
// request body goes here
JSONObject jsonBody = new JSONObject();
jsonBody.put("attribute1", "value1");
String requestBody = jsonBody.toString();
return 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() throws AuthFailureError {
Map<String, String> params = new HashMap<String, String>();
params.put("Content-Type", "application/json");
params.put("id", "oneapp.app.com");
params.put("key", "fgs7902nskagdjs");
return params;
}
#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));
}
};
Log.d("string", stringRequest.toString());
requestQueue.add(stringRequest);
} catch (JSONException e) {
e.printStackTrace();
}
For example, if request body is
{
name: "name1",
email: "email1"
}
getBody method would be
#Override
public byte[] getBody() throws AuthFailureError {
JSONObject jsonBody = new JSONObject();
jsonBody.put("name", "name1");
jsonBody.put("email", "email1");
String requestBody = jsonBody.toString();
return requestBody.getBytes("utf-8");
}
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.
Trying to send arraylist to server but it seems the format does not correct.
My params in StringRequest
#Override
protected Map<String, String> getParams() {
Map<String, String> params = new HashMap<>();
params.put("source", "en");
params.put("target", "zh");
JSONArray jsonArray = new JSONArray();
jsonArray.put("hello world");
params.put("stringArray", jsonArray.toString());
return params;
}
My server response
{"result":[],"source":"en","target":"zh","arrayString":"[\"hello world\"]"}
arrayString does not make sense to me because "[\"hello world\"]" is just a string, not a array of string. I expect the arrayString should be something like this "arrayString":[\"hello world\"]
Any suggestions?
EDIT
Tried to use JsonObjectRequest.
Map<String, Object> params = new HashMap();
params.put("source", "en");
params.put("target", "zh");
params.put("stringArray", Arrays.asList("hello world"));
JSONObject parameters = new JSONObject(params);
JsonObjectRequest jsonRequest = new JsonObjectRequest(Request.Method.POST, requestString, parameters, new Response.Listener<JSONObject>() {
#Override
public void onResponse(JSONObject response) {
//TODO: handle success
Log.d("successful", response.toString());
}
}, new Response.ErrorListener() {
#Override
public void onErrorResponse(VolleyError error) {
error.printStackTrace();
//TODO: handle failure
}
});
Volley.newRequestQueue(getActivity()).add(jsonRequest);
Server response
successful: {"result":null,"source":null,"target":null,"arrayString":null}
Php code
<?php
$source = $_POST['source'];
$target = $_POST['target'];
$arrayString = $_POST['stringArray'];
echo json_encode(array('result'=>$results,'source'=>$source,'target'=>$target,'arrayString'=>$arrayString));
?>
Edit 2
If I use JSONObject with its put method and JSONArray as well, I still get the null results
JSONObject parameters = new JSONObject();
try {
parameters.put("source", "en");
parameters.put("target", "zh");
JSONArray jsonArray = new JSONArray();
jsonArray.put("hello world");
parameters.put("stringArray", jsonArray);
} catch (JSONException e) {
e.printStackTrace();
}
Log.d("JSONParams", parameters.toString());
JsonObjectRequest jsonRequest = new JsonObjectRequest(Request.Method.POST, requestString, parameters, new Response.Listener<JSONObject>() {
#Override
public void onResponse(JSONObject response) {
Log.d("successful", response.toString());
}
}, new Response.ErrorListener() {
#Override
public void onErrorResponse(VolleyError error) {
error.printStackTrace();
}
});
Print and Server Response
JSONParams: {"source":"en","target":"zh","stringArray":["hello world"]}
successful: {"result":null,"source":null,"target":null,"arrayString":null}
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.