I understand that POST requests using JsonArrayRequest are not available out of the box with Volley, but I saw this post here that talked about adding a constructor to handle this. Their implementation was this:
public JsonArrayRequest(int method, String url, JSONObject jsonRequest,
Listener<JSONArray> listener, ErrorListener errorListener) {
super(method, url, (jsonRequest == null) ? null : jsonRequest.toString(),
listener, errorListener);
}
How would I go about adding this as a constructor? The above question mentions placing it in the Volley Tool Library. I imported Volley as a .jar, so I'm not sure how to add a constructor like this, or if this is the best approach. Any help is much appreciated.
EDIT
I've created the following class with override and constructor as suggested. Here is the class:
public class PostJsonArrayRequest extends JsonArrayRequest {
#Override
protected Map<String, String> getParams() throws AuthFailureError {
HashMap<String, String> params = new HashMap<String, String>();
params.put("name", "value");
return params;
}
public PostJsonArrayRequest(int method, String url, JSONObject jsonRequest,
Listener<JSONArray> listener, ErrorListener errorListener) {
super(Method.POST, url, null, listener, errorListener);
}
}
On the line calling super I'm getting The constructor JsonArrayRequest(int, String, null, Response.Listener<JSONArray>, Response.ErrorListener) is undefined
How do I correct this?
Create a class and extend JsonArrayRequest then override
#Override
protected Map<String, String> getParams() throws AuthFailureError {
HashMap<String, String> params = new HashMap<String, String>();
params.put("name", "value");
return params;
}
and add a new constructor and in it call
super(Method.POST, url, null, listener, errorListener);
or use this class
public class PostJsonArrayRequest extends JsonRequest<JSONArray> {
/**
* Creates a new request.
* #param url URL to fetch the JSON from
* #param listener Listener to receive the JSON response
* #param errorListener Error listener, or null to ignore errors.
*/
public PostJsonArrayRequest(String url, Response.Listener<JSONArray> listener, Response.ErrorListener errorListener) {
super(Method.POST, url, null, listener, errorListener);
}
#Override
protected Map<String, String> getParams() throws AuthFailureError {
HashMap<String, String> params = new HashMap<String, String>();
params.put("name", "value");
return params;
}
#Override
protected Response<JSONArray> parseNetworkResponse(NetworkResponse response) {
try {
String jsonString =
new String(response.data, HttpHeaderParser.parseCharset(response.headers));
return Response.success(new JSONArray(jsonString),
HttpHeaderParser.parseCacheHeaders(response));
} catch (UnsupportedEncodingException e) {
return Response.error(new ParseError(e));
} catch (JSONException je) {
return Response.error(new ParseError(je));
}
}
}
Related
I Want to post something like this [1,2,14,15] using volley to my PHP file where there's a SQL to retreive data from database.
Here my volley :
Map<String, String> userParams = new HashMap<String, String>();
listParams.put(TAG_IDS, all_ids);
CustomRequest myREquest= new CustomRequest(Request.Method.POST, URL, listParams,
new Response.Listener<JSONObject>() {
#Override
public void onResponse(JSONObject response) {
And in my PHP file i'll use a SQL something like this :
$liste=$_POST['IDS'] ;
$val= array_map('intval', $liste);
$new_liste = implode("','", $val);
$query = "SELECT * table WHERE IDS IN('".$new_liste ."')";
Here my CustomRequest
public class CustomRequest extends Request<JSONObject> {
private Response.Listener<JSONObject> listener;
private Map<String, String> params;
public CustomRequest(String url, Map<String, String> params, Response.Listener<JSONObject> reponseListener,
Response.ErrorListener errorListener){
super(Method.GET, url, errorListener);
this.listener=reponseListener;
this.params= params;
}
public CustomRequest(int methode, String url, Map<String, String> params, Response.Listener<JSONObject> reponseListener,
Response.ErrorListener errorListener){
super(methode,url,errorListener);
this.listener = reponseListener;
this.params = params;
}
protected Map<String, String> getParams()
throws com.android.volley.AuthFailureError{
return params;
}
#Override
protected Response<JSONObject> 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
protected void deliverResponse(JSONObject response) {
listener.onResponse(response);
}
}
Please help.
You should iterate your all_ids and put all of them in Map which will be send to the server. For example:
#Override
protected Map<String, String> getParams() {
Map<String, String> params = new HashMap<>();
for(int i=0; i<all_ids.size(); i++) {
params.put(TAG_IDS + "[" + i + "]", all_ids.get(i).toString());
}
return params;
}
I am developing an Android app where I need to fetch results from a MySQL database in a remote server. I have written some PHP scripts to query the database and output the results in JSON format.
The problem is that the request fetches expected results only for the first time. When I send the same request with different POST params, it returns the first result all over again. I modified the PHP script to attach the POST param in the JSON result and tried logging the POST param. It is also the same first param.
If I uninstall the app from the device and re-install, again it returns the correct JSON only for the first time.
NOTE: When i run the same code with the same PHP scripts and same database on localhost (WAMPP), everything works perfect.
I tried using the Google Chrome extension Postman to check the output from the remote server, it worked as expected. So, I can confirm that the problem is with my app/code.
Here's my CustomJSONObjectRequest class :
public class CustomJSONObjectRequest extends Request<JSONObject> {
private Listener<JSONObject> listener;
private Map<String, String> params;
public CustomJSONObjectRequest(String url, Map<String, String> params,
Listener<JSONObject> reponseListener, ErrorListener errorListener) {
super(Method.GET, url, errorListener);
this.listener = reponseListener;
this.params = params;
}
public CustomJSONObjectRequest(int method, String url, Map<String, String> params,
Listener<JSONObject> reponseListener, ErrorListener errorListener) {
super(method, url, errorListener);
this.listener = reponseListener;
this.params = params;
}
protected Map<String, String> getParams()
throws com.android.volley.AuthFailureError {
return params;
};
#Override
protected Response<JSONObject> 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
protected void deliverResponse(JSONObject response) {
listener.onResponse(response);
}
}
And this is how I am sending the request :
String item_name = getIntent().getExtras().getString("item_name");
String url = getString(R.string.remote_server)+"fetch-item-list.php";
CustomJSONObjectRequest jsObjRequest = new CustomJSONObjectRequest(Request.Method.POST, url, null, new Response.Listener<JSONObject>() {
#Override
public void onResponse(JSONObject response) {
try {
Log.d("item name from intent extra", item_name); //intent extra
Log.d("response", response.toString()); //json response
Log.d("item name from response", response.getString("item_name")); //post parameter. This and the intent extra should be same
} catch (JSONException e) {
e.printStackTrace();
}
}
}, new Response.ErrorListener() {
#Override
public void onErrorResponse(VolleyError error) {
Toast.makeText(getApplicationContext(), error.toString(), Toast.LENGTH_SHORT).show();
}
}) {
#Override
protected Map<String, String> getParams() throws AuthFailureError {
Map<String, String> params = new HashMap<>();
params.put("item_name", item_name);
return params;
}
#Override
public Map<String, String> getHeaders() throws AuthFailureError {
Map<String, String> header = new HashMap<String, String>();
header.put("Content-Type", "application/json; charset=utf-8");
return header;
}
};
MyVolleySingleton.getInstance(getApplicationContext()).addToRequestQueue(jsObjRequest);
This is the logcat :
D/item name from intent extra: apple
D/Response: {"data":[{"item_discount":"0.00","item_price":"50.00","unique_id":"181................
D/item name from response: orange
I think I found the solution
Looks like the JSON response was getting cached, so the response for the first request got cached and the next requests were never sent to the server. The cached JSON response was returned for every other requests.
All I had to do was disable caching.
I added the line jsObjRequest.setShouldCache(false); before adding it to the request queue.
jsObjRequest.setShouldCache(false);
MyVolleySingleton.getInstance(getApplicationContext()).addToRequestQueue(jsObjRequest);
Thanks to this question.
But I still do not get it why it worked on localhost without this setting.
I have referred this
Example ,I am getting invalid token in response thus my authentication header works perfectly but something wrong in custom headers.
Custom volley request
public CustomRequest(String url, Map<String, String> params,
Listener<JSONObject> reponseListener, ErrorListener errorListener) {
super(Method.GET, url, errorListener);
this.listener = reponseListener;
this.params = params;
}
public CustomRequest(int method, String url, Map<String, String> params,
Listener<JSONObject> reponseListener, ErrorListener errorListener) {
super(method, url, errorListener);
this.listener = reponseListener;
this.params = params;
}
public CustomRequest(int method, String url, Map<String, String> params,
Listener<JSONObject> reponseListener, ErrorListener errorListener, Boolean head, String tok, String id) {
super(method, url, errorListener);
this.listener = reponseListener;
this.params = params;
headadd = head;
this.id = id;
this.token = tok;
}
protected Map<String, String> getParams()
throws com.android.volley.AuthFailureError {
return params;
}
adding custom and Authorization header
#Override
public Map<String, String> getHeaders() throws AuthFailureError {
Map<String, String> head = new HashMap<>();
head.put(
"Authorization",
String.format("Basic %s", Base64.encodeToString(
String.format("%s:%s", "xxxxxxx", "xxxxxxx").getBytes(), Base64.DEFAULT)));
if (headadd) {
head.put("token", token);
head.put("client_id", id);
}
return head;
}
#Override
protected Response<JSONObject> 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
protected void deliverResponse(JSONObject response) {
listener.onResponse(response);
}
#Override
public RetryPolicy getRetryPolicy() {
RetryPolicy retryPolicy = new DefaultRetryPolicy(
0,
DefaultRetryPolicy.DEFAULT_MAX_RETRIES,
DefaultRetryPolicy.DEFAULT_BACKOFF_MULT
);
return retryPolicy;
}
}
You are using the correct method. You definitely need to override getHeaders(). My guess is that your problem lies somewhere in here:
String.format("Basic %s", Base64.encodeToString(
String.format("%s:%s", "uictester", "?f!T!ziX}.,(").getBytes(), Base64.DEFAULT)));
Maybe you need to convert this to UTF-8?
Otherwise, you could pass in the headers map via constructor and see if that helps. It's probably a bit more flexible than hard-coding like that too.
It actually looks like you're passing in the params in CustomRequest and not using them?
getHeaders() method was taking spaces and symbols (quotes) while making requests i correct them and works fine for me.
Server is not accepting String parameters when making json object request (by post method) using volley, also in custom volley request it is required to pass a string Hash map in getParams() method i am having string as well as long values to be pass over there, Also tried by Uri class but there is also sting is required in appendQueryParameter(). i have used below links Link 1
Link 2 Link 3
Volley class
public class CustomRequest extends Request {
private Listener<JSONObject> listener;
private Map<String, String> params;
public CustomRequest(String url, Map<String, String> params,
Listener<JSONObject> reponseListener, ErrorListener errorListener) {
super(Method.GET, url, errorListener);
this.listener = reponseListener;
this.params = params;
}
public CustomRequest(int method, String url, Map<String, String> params,
Listener<JSONObject> reponseListener, ErrorListener errorListener) {
super(method, url, errorListener);
this.listener = reponseListener;
this.params = params;
}
protected Map<String, String> getParams()
throws com.android.volley.AuthFailureError {
return params;
}
#Override
protected Response<JSONObject> parseNetworkResponse(NetworkResponse response) {
try {
String jsonString = new String(response.data,
HttpHeaderParser.parseCharset(response.headers));
return Response.success(new JSONObject(jsonString),
HttpHeaderParser.parseCacheHeaders(response));
/* return Response.success(
gson.fromJson(json, clazz), HttpHeaderParser.parseCacheHeaders(response));*/
} catch (UnsupportedEncodingException e) {
return Response.error(new ParseError(e));
} catch (JSONException je) {
return Response.error(new ParseError(je));
}
}
#Override
public Map<String, String> getHeaders() throws AuthFailureError {
Map<String, String> headers = new HashMap<>();
String loginEncoded = new String(Base64.encode(("uictester:?f!T!ziX}.,(").getBytes(), Base64.DEFAULT));
headers.put("Authorization", "Basic " + loginEncoded);
return headers;
}
#Override
protected void deliverResponse(JSONObject response) {
// TODO Auto-generated method stub
listener.onResponse(response);
}
}
You first need to convert the long parameter to String using String.valueOf(long value) method and then put this param to the hashmap with its key. as:
params.put("key", String.valueOf(long value));
Android volley library is not accepting parameters from getParam() method.If it is given in query String then it works.I tried both GET and POST it doesn't works. But I want to give parameters POST Method.please check the code I have posted below.
RequestQueue queue = Volley.newRequestQueue(getApplicationContext());
String url = AppConstants.WEBSERVICE_URL
+ AppConstants.WEBSERVICE_URL_POST_COMMENT;
StringRequest getRequest = new StringRequest(Request.Method.GET, url,
new Response.Listener<String>() {
#Override
public void onResponse(String response) {
// response
Log.d("Response_postComment", response);
Intent intent = new Intent(getApplicationContext(),
ReviewActivity.class);
intent.putExtra("serviceId", servicePosition);
startActivity(intent);
}
}, new Response.ErrorListener() {
#Override
public void onErrorResponse(VolleyError error) {
// error
Log.d("Error.Response", error.toString());
}
}) {
#Override
public Map<String, String> getHeaders() throws AuthFailureError {
Map<String, String> pars = new HashMap<String, String>();
pars.put("Content-Type", "application/x-www-form-urlencoded");
return pars;
}
#Override
protected Map<String, String> getParams() throws AuthFailureError{
Map<String, String> params = new HashMap<String, String>();
params.put("rating", ratingBar.getRating() + "");
params.put("com_content", comments.getText() + "");
params.put("user_id", AppConstants.APP_LOGIN_USER_ID);
params.put("comm_post_ID", AppConstants.arrListServiceDetail
.get(servicePosition).getId() + "");
return params;
}
};
getRequest.setRetryPolicy(new DefaultRetryPolicy(500000,
DefaultRetryPolicy.DEFAULT_MAX_RETRIES,
DefaultRetryPolicy.DEFAULT_BACKOFF_MULT));
queue.add(getRequest);
getParam() method not working with GET request on volley.its working fine with POST methods.you have to set up complete URL with parameters.
I faced the same issue as you are facing now, but comes up with solution of making a custom request by making the core class Request as the super class of this request. In this i am passing params in constructor, then returning it to the getParams() overridden method as below:
public class RequestJson extends Request<JSONObject> {
private Listener<JSONObject> listener;
private Map<String, String> params;
public RequestJson(String url, Map<String, String> params,
Listener<JSONObject> reponseListener, ErrorListener errorListener) {
super(Method.GET, url, errorListener);
this.listener = reponseListener;
this.params = params;
}
public RequestJson(int method, String url, Map<String, String> params,
Listener<JSONObject> reponseListener, ErrorListener errorListener) {
super(method, url, errorListener);
this.listener = reponseListener;
this.params = params;
}
protected Map<String, String> getParams()
throws com.android.volley.AuthFailureError {
return params;
};
#Override
protected Response<JSONObject> parseNetworkResponse(NetworkResponse response) {
AppController.getInstance().checkSessionCookie(response.headers);
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
protected void deliverResponse(JSONObject response) {
// TODO Auto-generated method stub
listener.onResponse(response);
}
#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>();
}
AppController.getInstance().addSessionCookie(headers);
return headers;
}
}
Hope this will solve your problem.