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
Related
I'm using JsonObjectRequest because the Api Response is in JSON Format but in some cases, the response can be just a String. So if the API returns a String, It will generate a Volley Parse Error. So I'm just wondering if there is any solution for handlings a string in JsonObjectRequest without having to use StringRequest or CustomRequest.
Here's my Code:
JsonObjectRequest request = new JsonObjectRequest(Request.Method.POST, url,null,
(Response.Listener<JSONObject>) response -> {
JSONObject jsonObject = response;
Map map = new Gson().fromJson(String.valueOf(jsonObject),HashMap.class);
},
new Response.ErrorListener() {
public void onErrorResponse(VolleyError error) {
try {
String responseBody = new String(error.networkResponse.data, "utf-8");
Toast.makeText(mContext, responseBody, Toast.LENGTH_LONG).show();
} catch (Exception e) {
Toast.makeText(mContext, "Something went wrong! ", Toast.LENGTH_SHORT).show();
}
}
}
) {
public byte[] getBody() {
return new JSONObject(params).toString().getBytes();
}
public String getBodyContentType() {
return "application/json";
}
};
Volley.newRequestQueue(mContext).add(request);
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 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
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.