Related
I would like to send a new JsonObjectRequest request:
I want to receive JSON data (response from server): OK
I want to send JSON formatted data with this request to the server
JsonObjectRequest request = new JsonObjectRequest(
Request.Method.POST, "myurl.com", null,
new Response.Listener<JSONObject>() {
#Override
public void onResponse(JSONObject response) {
//...
}
},
new Response.ErrorListener() {
#Override
public void onErrorResponse(VolleyError error) {
//...
}
})
{
#Override
protected Map<String,String> getParams() {
// something to do here ??
return params;
}
#Override
public Map<String, String> getHeaders() throws AuthFailureError {
// something to do here ??
return params;
}
};
P.S. I use GSON library in my project too.
JsonObjectRequest actually accepts JSONObject as body.
From this blog article,
final String url = "some/url";
final JSONObject jsonBody = new JSONObject("{\"type\":\"example\"}");
new JsonObjectRequest(url, jsonBody, new Response.Listener<JSONObject>() { ... });
Here is the source code and JavaDoc (#param jsonRequest):
/**
* Creates a new request.
* #param method the HTTP method to use
* #param url URL to fetch the JSON from
* #param jsonRequest A {#link JSONObject} to post with the request. Null is allowed and
* indicates no parameters will be posted along with request.
* #param listener Listener to receive the JSON response
* #param errorListener Error listener, or null to ignore errors.
*/
public JsonObjectRequest(int method, String url, JSONObject jsonRequest,
Listener<JSONObject> listener, ErrorListener errorListener) {
super(method, url, (jsonRequest == null) ? null : jsonRequest.toString(), listener,
errorListener);
}
I know that this thread is quite old, but I had this problem and I came up with a cool solution which can be very useful to many because it corrects/extended the Volley library on many aspects.
I spotted some not supported-out-of-box Volley features:
This JSONObjectRequest is not perfect: you have to expect a JSON at the end (see the Response.Listener<JSONObject>).
What about Empty Responses (just with a 200 status)?
What do I do if I want directly my POJO from the ResponseListener?
I more or less compiled a lot of solutions in a big generic class in order to have a solution for all the problem I quoted.
/**
* Created by laurentmeyer on 25/07/15.
*/
public class GenericRequest<T> extends JsonRequest<T> {
private final Gson gson = new Gson();
private final Class<T> clazz;
private final Map<String, String> headers;
// Used for request which do not return anything from the server
private boolean muteRequest = false;
/**
* Basically, this is the constructor which is called by the others.
* It allows you to send an object of type A to the server and expect a JSON representing a object of type B.
* The problem with the #JsonObjectRequest is that you expect a JSON at the end.
* We can do better than that, we can directly receive our POJO.
* That's what this class does.
*
* #param method: HTTP Method
* #param classtype: Classtype to parse the JSON coming from the server
* #param url: url to be called
* #param requestBody: The body being sent
* #param listener: Listener of the request
* #param errorListener: Error handler of the request
* #param headers: Added headers
*/
private GenericRequest(int method, Class<T> classtype, String url, String requestBody,
Response.Listener<T> listener, Response.ErrorListener errorListener, Map<String, String> headers) {
super(method, url, requestBody, listener,
errorListener);
clazz = classtype;
this.headers = headers;
configureRequest();
}
/**
* Method to be called if you want to send some objects to your server via body in JSON of the request (with headers and not muted)
*
* #param method: HTTP Method
* #param url: URL to be called
* #param classtype: Classtype to parse the JSON returned from the server
* #param toBeSent: Object which will be transformed in JSON via Gson and sent to the server
* #param listener: Listener of the request
* #param errorListener: Error handler of the request
* #param headers: Added headers
*/
public GenericRequest(int method, String url, Class<T> classtype, Object toBeSent,
Response.Listener<T> listener, Response.ErrorListener errorListener, Map<String, String> headers) {
this(method, classtype, url, new Gson().toJson(toBeSent), listener,
errorListener, headers);
}
/**
* Method to be called if you want to send some objects to your server via body in JSON of the request (without header and not muted)
*
* #param method: HTTP Method
* #param url: URL to be called
* #param classtype: Classtype to parse the JSON returned from the server
* #param toBeSent: Object which will be transformed in JSON via Gson and sent to the server
* #param listener: Listener of the request
* #param errorListener: Error handler of the request
*/
public GenericRequest(int method, String url, Class<T> classtype, Object toBeSent,
Response.Listener<T> listener, Response.ErrorListener errorListener) {
this(method, classtype, url, new Gson().toJson(toBeSent), listener,
errorListener, new HashMap<String, String>());
}
/**
* Method to be called if you want to send something to the server but not with a JSON, just with a defined String (without header and not muted)
*
* #param method: HTTP Method
* #param url: URL to be called
* #param classtype: Classtype to parse the JSON returned from the server
* #param requestBody: String to be sent to the server
* #param listener: Listener of the request
* #param errorListener: Error handler of the request
*/
public GenericRequest(int method, String url, Class<T> classtype, String requestBody,
Response.Listener<T> listener, Response.ErrorListener errorListener) {
this(method, classtype, url, requestBody, listener,
errorListener, new HashMap<String, String>());
}
/**
* Method to be called if you want to GET something from the server and receive the POJO directly after the call (no JSON). (Without header)
*
* #param url: URL to be called
* #param classtype: Classtype to parse the JSON returned from the server
* #param listener: Listener of the request
* #param errorListener: Error handler of the request
*/
public GenericRequest(String url, Class<T> classtype, Response.Listener<T> listener, Response.ErrorListener errorListener) {
this(Request.Method.GET, url, classtype, "", listener, errorListener);
}
/**
* Method to be called if you want to GET something from the server and receive the POJO directly after the call (no JSON). (With headers)
*
* #param url: URL to be called
* #param classtype: Classtype to parse the JSON returned from the server
* #param listener: Listener of the request
* #param errorListener: Error handler of the request
* #param headers: Added headers
*/
public GenericRequest(String url, Class<T> classtype, Response.Listener<T> listener, Response.ErrorListener errorListener, Map<String, String> headers) {
this(Request.Method.GET, classtype, url, "", listener, errorListener, headers);
}
/**
* Method to be called if you want to send some objects to your server via body in JSON of the request (with headers and muted)
*
* #param method: HTTP Method
* #param url: URL to be called
* #param classtype: Classtype to parse the JSON returned from the server
* #param toBeSent: Object which will be transformed in JSON via Gson and sent to the server
* #param listener: Listener of the request
* #param errorListener: Error handler of the request
* #param headers: Added headers
* #param mute: Muted (put it to true, to make sense)
*/
public GenericRequest(int method, String url, Class<T> classtype, Object toBeSent,
Response.Listener<T> listener, Response.ErrorListener errorListener, Map<String, String> headers, boolean mute) {
this(method, classtype, url, new Gson().toJson(toBeSent), listener,
errorListener, headers);
this.muteRequest = mute;
}
/**
* Method to be called if you want to send some objects to your server via body in JSON of the request (without header and muted)
*
* #param method: HTTP Method
* #param url: URL to be called
* #param classtype: Classtype to parse the JSON returned from the server
* #param toBeSent: Object which will be transformed in JSON via Gson and sent to the server
* #param listener: Listener of the request
* #param errorListener: Error handler of the request
* #param mute: Muted (put it to true, to make sense)
*/
public GenericRequest(int method, String url, Class<T> classtype, Object toBeSent,
Response.Listener<T> listener, Response.ErrorListener errorListener, boolean mute) {
this(method, classtype, url, new Gson().toJson(toBeSent), listener,
errorListener, new HashMap<String, String>());
this.muteRequest = mute;
}
/**
* Method to be called if you want to send something to the server but not with a JSON, just with a defined String (without header and not muted)
*
* #param method: HTTP Method
* #param url: URL to be called
* #param classtype: Classtype to parse the JSON returned from the server
* #param requestBody: String to be sent to the server
* #param listener: Listener of the request
* #param errorListener: Error handler of the request
* #param mute: Muted (put it to true, to make sense)
*/
public GenericRequest(int method, String url, Class<T> classtype, String requestBody,
Response.Listener<T> listener, Response.ErrorListener errorListener, boolean mute) {
this(method, classtype, url, requestBody, listener,
errorListener, new HashMap<String, String>());
this.muteRequest = mute;
}
#Override
protected Response<T> parseNetworkResponse(NetworkResponse response) {
// The magic of the mute request happens here
if (muteRequest) {
if (response.statusCode >= 200 && response.statusCode <= 299) {
// If the status is correct, we return a success but with a null object, because the server didn't return anything
return Response.success(null, HttpHeaderParser.parseCacheHeaders(response));
}
} else {
try {
// If it's not muted; we just need to create our POJO from the returned JSON and handle correctly the errors
String json = new String(response.data, HttpHeaderParser.parseCharset(response.headers));
T parsedObject = gson.fromJson(json, clazz);
return Response.success(parsedObject, HttpHeaderParser.parseCacheHeaders(response));
} catch (UnsupportedEncodingException e) {
return Response.error(new ParseError(e));
} catch (JsonSyntaxException e) {
return Response.error(new ParseError(e));
}
}
return null;
}
#Override
public Map<String, String> getHeaders() throws AuthFailureError {
return headers != null ? headers : super.getHeaders();
}
private void configureRequest() {
// Set retry policy
// Add headers, for auth for example
// ...
}
}
It could seem a bit overkill but it's pretty cool to have all these constructors because you have all the cases:
(The main constructor wasn't meant to be used directly although it's, of course, possible).
Request with response parsed to POJO / Headers manually set / POJO to Send
Request with response parsed to POJO / POJO to Send
Request with response parsed to POJO / String to Send
Request with response parsed to POJO (GET)
Request with response parsed to POJO (GET) / Headers manually set
Request with no response (200 - Empty Body) / Headers manually set / POJO to Send
Request with no response (200 - Empty Body) / POJO to Send
Request with no response (200 - Empty Body) / String to Send
Of course, in order that it works, you have to have Google's GSON Lib; just add:
compile 'com.google.code.gson:gson:x.y.z'
to your dependencies (current version is 2.3.1).
final String URL = "/volley/resource/12";
// Post params to be sent to the server
HashMap<String, String> params = new HashMap<String, String>();
params.put("token", "AbCdEfGh123456");
JsonObjectRequest req = new JsonObjectRequest(URL, new JSONObject(params),
new Response.Listener<JSONObject>() {
#Override
public void onResponse(JSONObject response) {
try {
VolleyLog.v("Response:%n %s", response.toString(4));
} catch (JSONException e) {
e.printStackTrace();
}
}
}, new Response.ErrorListener() {
#Override
public void onErrorResponse(VolleyError error) {
VolleyLog.e("Error: ", error.getMessage());
}
});
// add the request object to the queue to be executed
ApplicationController.getInstance().addToRequestQueue(req);
refer
final String url = "some/url";
instead of:
final JSONObject jsonBody = "{\"type\":\"example\"}";
you can use:
JSONObject jsonBody = new JSONObject();
try {
jsonBody.put("type", "my type");
} catch (JSONException e) {
e.printStackTrace();
}
new JsonObjectRequest(url, jsonBody, new Response.Listener<JSONObject>() { ... });
You can also send data by overriding getBody() method of JsonObjectRequest class. As shown below.
#Override
public byte[] getBody()
{
JSONObject jsonObject = new JSONObject();
String body = null;
try
{
jsonObject.put("username", "user123");
jsonObject.put("password", "Pass123");
body = jsonObject.toString();
} catch (JSONException e)
{
// TODO Auto-generated catch block
e.printStackTrace();
}
try
{
return body.toString().getBytes("utf-8");
} catch (UnsupportedEncodingException e)
{
// TODO Auto-generated catch block
e.printStackTrace();
}
return null;
}
final Map<String,String> params = new HashMap<String,String>();
params.put("email", customer.getEmail());
params.put("password", customer.getPassword());
String url = Constants.BASE_URL+"login";
doWebRequestPost(url, params);
public void doWebRequestPost(String url, final Map<String,String> json){
getmDialogListener().showDialog();
StringRequest post = new StringRequest(Request.Method.POST, url, new Response.Listener<String>() {
#Override
public void onResponse(String response) {
try {
getmDialogListener().dismissDialog();
response....
} catch (Exception e) {
e.printStackTrace();
}
}
}, new Response.ErrorListener() {
#Override
public void onErrorResponse(VolleyError error) {
Log.d(App.TAG,error.toString());
getmDialogListener().dismissDialog();
}
}){
#Override
protected Map<String, String> getParams() throws AuthFailureError {
Map<String,String> map = json;
return map;
}
};
App.getInstance().getRequestQueue().add(post);
}
protected Map<String, String> getParams() {
Map<String, String> params = new HashMap<String, String>();
JSONObject JObj = new JSONObject();
try {
JObj.put("Id","1");
JObj.put("Name", "abc");
} catch (Exception e) {
e.printStackTrace();
}
params.put("params", JObj.toString());
// Map.Entry<String,String>
Log.d("Parameter", params.toString());
return params;
}
I would like to send a new JsonObjectRequest request:
I want to receive JSON data (response from server): OK
I want to send JSON formatted data with this request to the server
JsonObjectRequest request = new JsonObjectRequest(
Request.Method.POST, "myurl.com", null,
new Response.Listener<JSONObject>() {
#Override
public void onResponse(JSONObject response) {
//...
}
},
new Response.ErrorListener() {
#Override
public void onErrorResponse(VolleyError error) {
//...
}
})
{
#Override
protected Map<String,String> getParams() {
// something to do here ??
return params;
}
#Override
public Map<String, String> getHeaders() throws AuthFailureError {
// something to do here ??
return params;
}
};
P.S. I use GSON library in my project too.
JsonObjectRequest actually accepts JSONObject as body.
From this blog article,
final String url = "some/url";
final JSONObject jsonBody = new JSONObject("{\"type\":\"example\"}");
new JsonObjectRequest(url, jsonBody, new Response.Listener<JSONObject>() { ... });
Here is the source code and JavaDoc (#param jsonRequest):
/**
* Creates a new request.
* #param method the HTTP method to use
* #param url URL to fetch the JSON from
* #param jsonRequest A {#link JSONObject} to post with the request. Null is allowed and
* indicates no parameters will be posted along with request.
* #param listener Listener to receive the JSON response
* #param errorListener Error listener, or null to ignore errors.
*/
public JsonObjectRequest(int method, String url, JSONObject jsonRequest,
Listener<JSONObject> listener, ErrorListener errorListener) {
super(method, url, (jsonRequest == null) ? null : jsonRequest.toString(), listener,
errorListener);
}
I know that this thread is quite old, but I had this problem and I came up with a cool solution which can be very useful to many because it corrects/extended the Volley library on many aspects.
I spotted some not supported-out-of-box Volley features:
This JSONObjectRequest is not perfect: you have to expect a JSON at the end (see the Response.Listener<JSONObject>).
What about Empty Responses (just with a 200 status)?
What do I do if I want directly my POJO from the ResponseListener?
I more or less compiled a lot of solutions in a big generic class in order to have a solution for all the problem I quoted.
/**
* Created by laurentmeyer on 25/07/15.
*/
public class GenericRequest<T> extends JsonRequest<T> {
private final Gson gson = new Gson();
private final Class<T> clazz;
private final Map<String, String> headers;
// Used for request which do not return anything from the server
private boolean muteRequest = false;
/**
* Basically, this is the constructor which is called by the others.
* It allows you to send an object of type A to the server and expect a JSON representing a object of type B.
* The problem with the #JsonObjectRequest is that you expect a JSON at the end.
* We can do better than that, we can directly receive our POJO.
* That's what this class does.
*
* #param method: HTTP Method
* #param classtype: Classtype to parse the JSON coming from the server
* #param url: url to be called
* #param requestBody: The body being sent
* #param listener: Listener of the request
* #param errorListener: Error handler of the request
* #param headers: Added headers
*/
private GenericRequest(int method, Class<T> classtype, String url, String requestBody,
Response.Listener<T> listener, Response.ErrorListener errorListener, Map<String, String> headers) {
super(method, url, requestBody, listener,
errorListener);
clazz = classtype;
this.headers = headers;
configureRequest();
}
/**
* Method to be called if you want to send some objects to your server via body in JSON of the request (with headers and not muted)
*
* #param method: HTTP Method
* #param url: URL to be called
* #param classtype: Classtype to parse the JSON returned from the server
* #param toBeSent: Object which will be transformed in JSON via Gson and sent to the server
* #param listener: Listener of the request
* #param errorListener: Error handler of the request
* #param headers: Added headers
*/
public GenericRequest(int method, String url, Class<T> classtype, Object toBeSent,
Response.Listener<T> listener, Response.ErrorListener errorListener, Map<String, String> headers) {
this(method, classtype, url, new Gson().toJson(toBeSent), listener,
errorListener, headers);
}
/**
* Method to be called if you want to send some objects to your server via body in JSON of the request (without header and not muted)
*
* #param method: HTTP Method
* #param url: URL to be called
* #param classtype: Classtype to parse the JSON returned from the server
* #param toBeSent: Object which will be transformed in JSON via Gson and sent to the server
* #param listener: Listener of the request
* #param errorListener: Error handler of the request
*/
public GenericRequest(int method, String url, Class<T> classtype, Object toBeSent,
Response.Listener<T> listener, Response.ErrorListener errorListener) {
this(method, classtype, url, new Gson().toJson(toBeSent), listener,
errorListener, new HashMap<String, String>());
}
/**
* Method to be called if you want to send something to the server but not with a JSON, just with a defined String (without header and not muted)
*
* #param method: HTTP Method
* #param url: URL to be called
* #param classtype: Classtype to parse the JSON returned from the server
* #param requestBody: String to be sent to the server
* #param listener: Listener of the request
* #param errorListener: Error handler of the request
*/
public GenericRequest(int method, String url, Class<T> classtype, String requestBody,
Response.Listener<T> listener, Response.ErrorListener errorListener) {
this(method, classtype, url, requestBody, listener,
errorListener, new HashMap<String, String>());
}
/**
* Method to be called if you want to GET something from the server and receive the POJO directly after the call (no JSON). (Without header)
*
* #param url: URL to be called
* #param classtype: Classtype to parse the JSON returned from the server
* #param listener: Listener of the request
* #param errorListener: Error handler of the request
*/
public GenericRequest(String url, Class<T> classtype, Response.Listener<T> listener, Response.ErrorListener errorListener) {
this(Request.Method.GET, url, classtype, "", listener, errorListener);
}
/**
* Method to be called if you want to GET something from the server and receive the POJO directly after the call (no JSON). (With headers)
*
* #param url: URL to be called
* #param classtype: Classtype to parse the JSON returned from the server
* #param listener: Listener of the request
* #param errorListener: Error handler of the request
* #param headers: Added headers
*/
public GenericRequest(String url, Class<T> classtype, Response.Listener<T> listener, Response.ErrorListener errorListener, Map<String, String> headers) {
this(Request.Method.GET, classtype, url, "", listener, errorListener, headers);
}
/**
* Method to be called if you want to send some objects to your server via body in JSON of the request (with headers and muted)
*
* #param method: HTTP Method
* #param url: URL to be called
* #param classtype: Classtype to parse the JSON returned from the server
* #param toBeSent: Object which will be transformed in JSON via Gson and sent to the server
* #param listener: Listener of the request
* #param errorListener: Error handler of the request
* #param headers: Added headers
* #param mute: Muted (put it to true, to make sense)
*/
public GenericRequest(int method, String url, Class<T> classtype, Object toBeSent,
Response.Listener<T> listener, Response.ErrorListener errorListener, Map<String, String> headers, boolean mute) {
this(method, classtype, url, new Gson().toJson(toBeSent), listener,
errorListener, headers);
this.muteRequest = mute;
}
/**
* Method to be called if you want to send some objects to your server via body in JSON of the request (without header and muted)
*
* #param method: HTTP Method
* #param url: URL to be called
* #param classtype: Classtype to parse the JSON returned from the server
* #param toBeSent: Object which will be transformed in JSON via Gson and sent to the server
* #param listener: Listener of the request
* #param errorListener: Error handler of the request
* #param mute: Muted (put it to true, to make sense)
*/
public GenericRequest(int method, String url, Class<T> classtype, Object toBeSent,
Response.Listener<T> listener, Response.ErrorListener errorListener, boolean mute) {
this(method, classtype, url, new Gson().toJson(toBeSent), listener,
errorListener, new HashMap<String, String>());
this.muteRequest = mute;
}
/**
* Method to be called if you want to send something to the server but not with a JSON, just with a defined String (without header and not muted)
*
* #param method: HTTP Method
* #param url: URL to be called
* #param classtype: Classtype to parse the JSON returned from the server
* #param requestBody: String to be sent to the server
* #param listener: Listener of the request
* #param errorListener: Error handler of the request
* #param mute: Muted (put it to true, to make sense)
*/
public GenericRequest(int method, String url, Class<T> classtype, String requestBody,
Response.Listener<T> listener, Response.ErrorListener errorListener, boolean mute) {
this(method, classtype, url, requestBody, listener,
errorListener, new HashMap<String, String>());
this.muteRequest = mute;
}
#Override
protected Response<T> parseNetworkResponse(NetworkResponse response) {
// The magic of the mute request happens here
if (muteRequest) {
if (response.statusCode >= 200 && response.statusCode <= 299) {
// If the status is correct, we return a success but with a null object, because the server didn't return anything
return Response.success(null, HttpHeaderParser.parseCacheHeaders(response));
}
} else {
try {
// If it's not muted; we just need to create our POJO from the returned JSON and handle correctly the errors
String json = new String(response.data, HttpHeaderParser.parseCharset(response.headers));
T parsedObject = gson.fromJson(json, clazz);
return Response.success(parsedObject, HttpHeaderParser.parseCacheHeaders(response));
} catch (UnsupportedEncodingException e) {
return Response.error(new ParseError(e));
} catch (JsonSyntaxException e) {
return Response.error(new ParseError(e));
}
}
return null;
}
#Override
public Map<String, String> getHeaders() throws AuthFailureError {
return headers != null ? headers : super.getHeaders();
}
private void configureRequest() {
// Set retry policy
// Add headers, for auth for example
// ...
}
}
It could seem a bit overkill but it's pretty cool to have all these constructors because you have all the cases:
(The main constructor wasn't meant to be used directly although it's, of course, possible).
Request with response parsed to POJO / Headers manually set / POJO to Send
Request with response parsed to POJO / POJO to Send
Request with response parsed to POJO / String to Send
Request with response parsed to POJO (GET)
Request with response parsed to POJO (GET) / Headers manually set
Request with no response (200 - Empty Body) / Headers manually set / POJO to Send
Request with no response (200 - Empty Body) / POJO to Send
Request with no response (200 - Empty Body) / String to Send
Of course, in order that it works, you have to have Google's GSON Lib; just add:
compile 'com.google.code.gson:gson:x.y.z'
to your dependencies (current version is 2.3.1).
final String URL = "/volley/resource/12";
// Post params to be sent to the server
HashMap<String, String> params = new HashMap<String, String>();
params.put("token", "AbCdEfGh123456");
JsonObjectRequest req = new JsonObjectRequest(URL, new JSONObject(params),
new Response.Listener<JSONObject>() {
#Override
public void onResponse(JSONObject response) {
try {
VolleyLog.v("Response:%n %s", response.toString(4));
} catch (JSONException e) {
e.printStackTrace();
}
}
}, new Response.ErrorListener() {
#Override
public void onErrorResponse(VolleyError error) {
VolleyLog.e("Error: ", error.getMessage());
}
});
// add the request object to the queue to be executed
ApplicationController.getInstance().addToRequestQueue(req);
refer
final String url = "some/url";
instead of:
final JSONObject jsonBody = "{\"type\":\"example\"}";
you can use:
JSONObject jsonBody = new JSONObject();
try {
jsonBody.put("type", "my type");
} catch (JSONException e) {
e.printStackTrace();
}
new JsonObjectRequest(url, jsonBody, new Response.Listener<JSONObject>() { ... });
You can also send data by overriding getBody() method of JsonObjectRequest class. As shown below.
#Override
public byte[] getBody()
{
JSONObject jsonObject = new JSONObject();
String body = null;
try
{
jsonObject.put("username", "user123");
jsonObject.put("password", "Pass123");
body = jsonObject.toString();
} catch (JSONException e)
{
// TODO Auto-generated catch block
e.printStackTrace();
}
try
{
return body.toString().getBytes("utf-8");
} catch (UnsupportedEncodingException e)
{
// TODO Auto-generated catch block
e.printStackTrace();
}
return null;
}
final Map<String,String> params = new HashMap<String,String>();
params.put("email", customer.getEmail());
params.put("password", customer.getPassword());
String url = Constants.BASE_URL+"login";
doWebRequestPost(url, params);
public void doWebRequestPost(String url, final Map<String,String> json){
getmDialogListener().showDialog();
StringRequest post = new StringRequest(Request.Method.POST, url, new Response.Listener<String>() {
#Override
public void onResponse(String response) {
try {
getmDialogListener().dismissDialog();
response....
} catch (Exception e) {
e.printStackTrace();
}
}
}, new Response.ErrorListener() {
#Override
public void onErrorResponse(VolleyError error) {
Log.d(App.TAG,error.toString());
getmDialogListener().dismissDialog();
}
}){
#Override
protected Map<String, String> getParams() throws AuthFailureError {
Map<String,String> map = json;
return map;
}
};
App.getInstance().getRequestQueue().add(post);
}
protected Map<String, String> getParams() {
Map<String, String> params = new HashMap<String, String>();
JSONObject JObj = new JSONObject();
try {
JObj.put("Id","1");
JObj.put("Name", "abc");
} catch (Exception e) {
e.printStackTrace();
}
params.put("params", JObj.toString());
// Map.Entry<String,String>
Log.d("Parameter", params.toString());
return params;
}
I have a Django script running on the server that creates session variables for every request sent to the server. The script returns a specific value based on the previous stored session variables.
When I tested the script on the browser, the session on Django worked as per the requirement.
However, while using Volley to send the same request, the script considers every request as a new request without taking previous session variables into consideration.
StringRequest stringRequest = new StringRequest(Request.Method.GET,Send_URL,
new Response.Listener<String>() {
#Override
public void onResponse(String response) {
Response(response);
}
}, new Response.ErrorListener() {
#Override
public void onErrorResponse(VolleyError error) {
}
});
requestQueue.add(stringRequest);
}
RequestQueue defined globally and context assigned in the onCreate() method
P.S I rechecked by requesting from the browser and it works. So there are no issues on the Django End.
Thanks!
Volley does not support Cookie by default. you should override StringRequest class as below shown:
public class StringRequest extends com.android.volley.toolbox.StringRequest {
private final Map<String, String> _params;
/**
* #param method
* #param url
* #param params
* A {#link HashMap} to post with the request. Null is allowed
* and indicates no parameters will be posted along with request.
* #param listener
* #param errorListener
*/
public StringRequest(int method, String url, Map<String, String> params, Listener<String> listener,
ErrorListener errorListener) {
super(method, url, listener, errorListener);
_params = params;
}
#Override
protected Map<String, String> getParams() {
return _params;
}
/* (non-Javadoc)
* #see com.android.volley.toolbox.StringRequest#parseNetworkResponse(com.android.volley.NetworkResponse)
*/
#Override
protected Response<String> parseNetworkResponse(NetworkResponse response) {
// since we don't know which of the two underlying network vehicles
// will Volley use, we have to handle and store session cookies manually
MyApp.get().checkSessionCookie(response.headers);
return super.parseNetworkResponse(response);
}
/* (non-Javadoc)
* #see com.android.volley.Request#getHeaders()
*/
#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>();
}
MyApp.get().addSessionCookie(headers);
return headers;
}
}
and your application class:
public class MyApp extends Application {
private static final String SET_COOKIE_KEY = "Set-Cookie";
private static final String COOKIE_KEY = "Cookie";
private static final String SESSION_COOKIE = "sessionid";
private static MyApp _instance;
private RequestQueue _requestQueue;
private SharedPreferences _preferences;
public static MyApp get() {
return _instance;
}
#Override
public void onCreate() {
super.onCreate();
_instance = this;
_preferences = PreferenceManager.getDefaultSharedPreferences(this);
_requestQueue = Volley.newRequestQueue(this);
}
public RequestQueue getRequestQueue() {
return _requestQueue;
}
/**
* Checks the response headers for session cookie and saves it
* if it finds it.
* #param headers Response Headers.
*/
public final void checkSessionCookie(Map<String, String> headers) {
if (headers.containsKey(SET_COOKIE_KEY)
&& headers.get(SET_COOKIE_KEY).startsWith(SESSION_COOKIE)) {
String cookie = headers.get(SET_COOKIE_KEY);
if (cookie.length() > 0) {
String[] splitCookie = cookie.split(";");
String[] splitSessionId = splitCookie[0].split("=");
cookie = splitSessionId[1];
Editor prefEditor = _preferences.edit();
prefEditor.putString(SESSION_COOKIE, cookie);
prefEditor.commit();
}
}
}
/**
* Adds session cookie to headers if exists.
* #param headers
*/
public final void addSessionCookie(Map<String, String> headers) {
String sessionId = _preferences.getString(SESSION_COOKIE, "");
if (sessionId.length() > 0) {
StringBuilder builder = new StringBuilder();
builder.append(SESSION_COOKIE);
builder.append("=");
builder.append(sessionId);
if (headers.containsKey(COOKIE_KEY)) {
builder.append("; ");
builder.append(headers.get(COOKIE_KEY));
}
headers.put(COOKIE_KEY, builder.toString());
}
}
}
also You can check this link for more ...
I had the same problem using volley library in other scripting language, You need to go through about volley library here ..
Additionally volley store the cache values by default,so your code did not work second time (that means return the same values)
so you can try HttpURLConnection default method to use this type of server actions.
Thanks hope its help!!!
I'm making an Android App that integrates with the Facebook API and uses a REST API, so I'm using Volley. However, I'm trying to issue a GET request for a JSON Array, and have to include the Facebook Authorization token in order to access the server. Most of the questions I've seen on this are relatively old, and it seems like Volley now provides support to pass in request params (from the volley github page):
/**
* Creates a new request.
* #param method the HTTP method to use
* #param url URL to fetch the JSON from
* #param jsonRequest A {#link JSONArray} to post with the request. Null is allowed and
* indicates no parameters will be posted along with request.
* #param listener Listener to receive the JSON response
* #param errorListener Error listener, or null to ignore errors.
*/
public JsonArrayRequest(int method, String url, JSONArray jsonRequest,
Listener<JSONArray> listener, ErrorListener errorListener) {
super(method, url, (jsonRequest == null) ? null : jsonRequest.toString(), listener,
errorListener);
}
But when I make and issue a JsonArrayRequest, I get a com.android.volley.AuthFailureError. Here is my code, does anyone know what I'm doing wrong?
#Override
protected void onCreate(Bundle savedInstanceState) {
System.out.println("Yo im here");
JSONObject requestParams = new JSONObject();
JSONArray paramArray = new JSONArray();
try {
requestParams.put("Authorization", "JWT (Facebook auth token)");
paramArray.put(requestParams);
} catch (JSONException e) {
e.printStackTrace();
}
System.out.println(paramArray.toString());
RequestQueue queue = Volley.newRequestQueue(this);
JsonArrayRequest request = new JsonArrayRequest(Request.Method.GET,
GET_MAP_MICS,
paramArray,
new Response.Listener<JSONArray>() {
#Override
public void onResponse(JSONArray micArray) {
try {
for (int i = 0; i < micArray.length(); i++) {
JSONObject jsonobject = micArray.getJSONObject(i);
int micId = jsonobject.getInt("micId");
String status = jsonobject.getString("status");
System.out.println("Good so far!");
double venLat = jsonobject.getDouble("venueLat");
double venLong = jsonobject.getDouble("venueLat");
System.out.println("got here, check it: " + venLat);
}
}catch (JSONException e) {
e.printStackTrace();
}
}
}, new Response.ErrorListener() {
#Override
public void onErrorResponse(VolleyError e) {
System.out.println(e);
}
});
GET method don't take parameters only POSTwill
in your case your passing Headers as body for GET method you have pass headers
JsonObjectRequest request = new JsonObjectRequest(url, (JSONObject) null, new Response.Listener<JSONObject>() {
#Override
public void onResponse(JSONObject jsonObject) {
}
}, new Response.ErrorListener() {
#Override
public void onErrorResponse(VolleyError volleyError) {
}
}) {
#Override
public Map<String, String> getHeaders() throws AuthFailureError {
Map<String, String> map = new HashMap<>();
/*Add your headers here*/
return super.getHeaders();
}
};
final possibility there is two same class name will be there in your project for example any lib your using also using volley lib this happens once for me
I have the following json response
{
"tag": [
{
"listing_count": 5,
"listings": [
{
"source": "source1",
"data": {
"image": "image1",
"name": "name1"
},
"name": "name1"
}
]
},
{
"listing_count": 5,
"listings": [
{
"source": "source2",
"data": {
"image": "imag2",
"name": "name2"
},
"name": "name2"
}
]
}
]
}
I have created the following classes for GSON request. How do I make the GSON request and store the values for the response using a volley request.
What should the GSON request be like?
public class TagList {
ArrayList<Tag> tags;
public static class Tag {
int listing_count;
ArrayList<Listings> listings;
public int getListing_count() {
return listing_count;
}
public void setListing_count(int listing_count) {
this.listing_count = listing_count;
}
public ArrayList<Listings> getListings() {
return listings;
}
public void setListings(ArrayList<Listings> listings) {
this.listings = listings;
}
}
public static class Listings {
String source;
Data data;
String name;
public String getSource() {
return source;
}
public void setSource(String source) {
this.source = source;
}
public Data getData() {
return data;
}
public void setData(Data data) {
this.data = data;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}
public static class Data {
String image;
String name;
public String getImage() {
return image;
}
public void setImage(String image) {
this.image = image;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}
Just create a GsonRequest Class as follows (taken from Android Developer Docs)
public class GsonRequest<T> extends Request<T> {
private final Gson gson = new Gson();
private final Class<T> clazz;
private final Map<String, String> headers;
private final Listener<T> listener;
/**
* Make a GET request and return a parsed object from JSON.
*
* #param url URL of the request to make
* #param clazz Relevant class object, for Gson's reflection
* #param headers Map of request headers
*/
public GsonRequest(String url, Class<T> clazz, Map<String, String> headers,
Listener<T> listener, ErrorListener errorListener) {
super(Method.GET, url, errorListener);
this.clazz = clazz;
this.headers = headers;
this.listener = listener;
}
#Override
public Map<String, String> getHeaders() throws AuthFailureError {
return headers != null ? headers : super.getHeaders();
}
#Override
protected void deliverResponse(T response) {
listener.onResponse(response);
}
#Override
protected Response<T> parseNetworkResponse(NetworkResponse response) {
try {
String json = new String(
response.data,
HttpHeaderParser.parseCharset(response.headers));
return Response.success(
gson.fromJson(json, clazz),
HttpHeaderParser.parseCacheHeaders(response));
} catch (UnsupportedEncodingException e) {
return Response.error(new ParseError(e));
} catch (JsonSyntaxException e) {
return Response.error(new ParseError(e));
}
}
}
Now in your class file (Activity) just call the this class as follows:
RequestQueue queue = MyVolley.getRequestQueue();
GsonRequest<MyClass> myReq = new GsonRequest<MyClass>(Method.GET,
"http://JSONURL/",
TagList.class,
createMyReqSuccessListener(),
createMyReqErrorListener());
queue.add(myReq);
We also need to create two methods -
createMyReqSuccessListener() - receive the response from GsonRequest
createMyReqErrorListener() - to handle any error
as follows:
private Response.Listener<MyClass> createMyReqSuccessListener() {
return new Response.Listener<MyClass>() {
#Override
public void onResponse(MyClass response) {
// Do whatever you want to do with response;
// Like response.tags.getListing_count(); etc. etc.
}
};
}
and
private Response.ErrorListener createMyReqErrorListener() {
return new Response.ErrorListener() {
#Override
public void onErrorResponse(VolleyError error) {
// Do whatever you want to do with error.getMessage();
}
};
}
I hope it will make some sense.
Here some useful code snippets.
GsonRequest for GET petitions:
import com.android.volley.NetworkResponse;
import com.android.volley.ParseError;
import com.android.volley.Request;
import com.android.volley.Response;
import com.android.volley.toolbox.HttpHeaderParser;
import com.google.gson.Gson;
import com.google.gson.JsonSyntaxException;
import java.io.UnsupportedEncodingException;
import java.lang.reflect.Type;
/**
* Convert a JsonElement into a list of objects or an object with Google Gson.
*
* The JsonElement is the response object for a {#link com.android.volley.Request.Method} GET call.
*
* #author https://plus.google.com/+PabloCostaTirado/about
*/
public class GsonGetRequest<T> extends Request<T>
{
private final Gson gson;
private final Type type;
private final Response.Listener<T> listener;
/**
* Make a GET request and return a parsed object from JSON.
*
* #param url URL of the request to make
* #param type is the type of the object to be returned
* #param listener is the listener for the right answer
* #param errorListener is the listener for the wrong answer
*/
public GsonGetRequest
(String url, Type type, Gson gson,
Response.Listener<T> listener, Response.ErrorListener errorListener)
{
super(Method.GET, url, errorListener);
this.gson = gson;
this.type = type;
this.listener = listener;
}
#Override
protected void deliverResponse(T response)
{
listener.onResponse(response);
}
#Override
protected Response<T> parseNetworkResponse(NetworkResponse response)
{
try
{
String json = new String(response.data, HttpHeaderParser.parseCharset(response.headers));
return (Response<T>) Response.success
(
gson.fromJson(json, type),
HttpHeaderParser.parseCacheHeaders(response)
);
}
catch (UnsupportedEncodingException e)
{
return Response.error(new ParseError(e));
}
catch (JsonSyntaxException e)
{
return Response.error(new ParseError(e));
}
}
}
GsonRequest for POST petitions:
import com.android.volley.NetworkResponse;
import com.android.volley.ParseError;
import com.android.volley.Response;
import com.android.volley.toolbox.HttpHeaderParser;
import com.android.volley.toolbox.JsonRequest;
import com.google.gson.Gson;
import com.google.gson.JsonSyntaxException;
import java.io.UnsupportedEncodingException;
import java.lang.reflect.Type;
/**
* Convert a JsonElement into a list of objects or an object with Google Gson.
*
* The JsonElement is the response object for a {#link com.android.volley.Request.Method} POST call.
*
* #author https://plus.google.com/+PabloCostaTirado/about
*/
public class GsonPostRequest<T> extends JsonRequest<T>
{
private final Gson gson;
private final Type type;
private final Response.Listener<T> listener;
/**
* Make a GET request and return a parsed object from JSON.
*
* #param url URL of the request to make
* #param type is the type of the object to be returned
* #param listener is the listener for the right answer
* #param errorListener is the listener for the wrong answer
*/
public GsonPostRequest
(String url, String body, Type type, Gson gson,
Response.Listener<T> listener, Response.ErrorListener errorListener)
{
super(Method.POST, url, body, listener, errorListener);
this.gson = gson;
this.type = type;
this.listener = listener;
}
#Override
protected void deliverResponse(T response)
{
listener.onResponse(response);
}
#Override
protected Response<T> parseNetworkResponse(NetworkResponse response)
{
try
{
String json = new String(response.data, HttpHeaderParser.parseCharset(response.headers));
return (Response<T>) Response.success
(
gson.fromJson(json, type),
HttpHeaderParser.parseCacheHeaders(response)
);
}
catch (UnsupportedEncodingException e)
{
return Response.error(new ParseError(e));
}
catch (JsonSyntaxException e)
{
return Response.error(new ParseError(e));
}
}
}
This is how you use it for JSON objects:
/**
* Returns a dummy object
*
* #param listener is the listener for the correct answer
* #param errorListener is the listener for the error response
*
* #return #return {#link com.sottocorp.sotti.okhttpvolleygsonsample.api.GsonGetRequest}
*/
public static GsonGetRequest<DummyObject> getDummyObject
(
Response.Listener<DummyObject> listener,
Response.ErrorListener errorListener
)
{
final String url = "http://www.mocky.io/v2/55973508b0e9e4a71a02f05f";
final Gson gson = new GsonBuilder()
.registerTypeAdapter(DummyObject.class, new DummyObjectDeserializer())
.create();
return new GsonGetRequest<>
(
url,
new TypeToken<DummyObject>() {}.getType(),
gson,
listener,
errorListener
);
}
This is how you use it for JSON arrays:
/**
* Returns a dummy object's array
*
* #param listener is the listener for the correct answer
* #param errorListener is the listener for the error response
*
* #return {#link com.sottocorp.sotti.okhttpvolleygsonsample.api.GsonGetRequest}
*/
public static GsonGetRequest<ArrayList<DummyObject>> getDummyObjectArray
(
Response.Listener<ArrayList<DummyObject>> listener,
Response.ErrorListener errorListener
)
{
final String url = "http://www.mocky.io/v2/5597d86a6344715505576725";
final Gson gson = new GsonBuilder()
.registerTypeAdapter(DummyObject.class, new DummyObjectDeserializer())
.create();
return new GsonGetRequest<>
(
url,
new TypeToken<ArrayList<DummyObject>>() {}.getType(),
gson,
listener,
errorListener
);
}
This is how you use it for POST calls:
/**
* An example call (not used in this example app) to demonstrate how to do a Volley POST call
* and parse the response with Gson.
*
* #param listener is the listener for the success response
* #param errorListener is the listener for the error response
*
* #return {#link com.sottocorp.sotti.okhttpvolleygsonsample.api.GsonPostRequest}
*/
public static GsonPostRequest getDummyObjectArrayWithPost
(
Response.Listener<DummyObject> listener,
Response.ErrorListener errorListener
)
{
final String url = "http://PostApiEndpoint";
final Gson gson = new GsonBuilder()
.registerTypeAdapter(DummyObject.class, new DummyObjectDeserializer())
.create();
final JsonObject jsonObject = new JsonObject();
jsonObject.addProperty("name", "Ficus");
jsonObject.addProperty("surname", "Kirkpatrick");
final JsonArray squareGuys = new JsonArray();
final JsonObject dev1 = new JsonObject();
final JsonObject dev2 = new JsonObject();
dev1.addProperty("name", "Jake Wharton");
dev2.addProperty("name", "Jesse Wilson");
squareGuys.add(dev1);
squareGuys.add(dev2);
jsonObject.add("squareGuys", squareGuys);
return new GsonPostRequest<>
(
url,
jsonObject.toString(),
new TypeToken<DummyObject>()
{
}.getType(),
gson,
listener,
errorListener
);
}
}
All the code is taken from here, and you have a blog post about how to use OkHttp, Volley and Gson here.
I just made a custom json request which is based on Jackson library instead of Gson.
One thing I want to point out (it took my many hours to figure out...): if you want to support POST Json parameter as well, you should extend from JsonRequest instead of Request. Otherwise your Json request body will be url-encoded, on the server side you cannot convert it back to java object.
Here is my json request class, which is based on Jackson and supports Json parameter and header:
public class JacksonRequest<ResponseType> extends JsonRequest<ResponseType> {
private final ObjectMapper objectMapper = new ObjectMapper();
private final Class<ResponseType> responseClass;
private final Map<String, String> headers;
private String requestBody = null;
private static final String PROTOCOL_CHARSET = "utf-8";
/**
* POST method without header
*/
public JacksonRequest(String url,
Object parameterObject,
Class<ResponseType> responseClass,
Response.Listener<ResponseType> listener,
Response.ErrorListener errorListener) {
this(Method.POST, url, null, parameterObject, responseClass, listener, errorListener);
}
/**
* #param method see also com.android.volley.Request.Method
*/
public JacksonRequest(int method,
String url,
Map<String, String> headers,
Object parameterObject,
Class<ResponseType> responseClass,
Response.Listener<ResponseType> listener,
Response.ErrorListener errorListener) {
super(method, url, null, listener, errorListener);
if (parameterObject != null)
try {
this.requestBody = objectMapper.writeValueAsString(parameterObject);
} catch (JsonProcessingException e) {
e.printStackTrace();
}
this.headers = headers;
this.responseClass = responseClass;
}
#Override
public Map<String, String> getHeaders() throws AuthFailureError {
return headers != null ? headers : super.getHeaders();
}
#Override
protected Response<ResponseType> parseNetworkResponse(NetworkResponse response) {
try {
String json = new String(response.data, HttpHeaderParser.parseCharset(response.headers));
ResponseType result = objectMapper.readValue(json, responseClass);
return Response.success(result, HttpHeaderParser.parseCacheHeaders(response));
} catch (UnsupportedEncodingException e) {
return Response.error(new ParseError(e));
} catch (JsonMappingException e) {
return Response.error(new ParseError(e));
} catch (JsonParseException e) {
return Response.error(new ParseError(e));
} catch (IOException e) {
return Response.error(new ParseError(e));
}
}
/**
* Cannot call objectMapper.writeValueAsString() before super constructor, so override the same getBody() here.
*/
#Override
public byte[] getBody() {
try {
return requestBody == null ? null : requestBody.getBytes(PROTOCOL_CHARSET);
} catch (UnsupportedEncodingException uee) {
VolleyLog.wtf("Unsupported Encoding while trying to get the bytes of %s using %s",
requestBody, PROTOCOL_CHARSET);
return null;
}
}
}