This example is for sending a Custom Request in Volley. If you are new to Volley and want to learn how to send a simple GET, POST request in Volley read this

I always have preferred Volley library over Retrofit for sending network requests in an Android Application mostly because of its cache handling and request prioritization. But many Retrofit users argue that one of the biggest advantage with Retrofit is that it automatically parses the json/xml response not knowing that the same could be done with Volley. You already know that Volley provides inbuilt support which will gives us response in any of these three formats

String

JSONObject

JSONArray

Now using a custom request with the help of Gson you can directly receive response in the form of POJO- Java Objects

Custom Request Volley Example :

For this example let us consider OpenWeatherMap API. It is weather forecast API which sends city wise weather details in JSON format

JSON format of the response

{ "coord" : { "lon" : -0.13 , "lat" : 51.51 } , "weather" : [ { "id" : 522 , "main" : "Rain" , "description" : "heavy intensity shower rain" , "icon" : "09d" } ] , "base" : "stations" , "main" : { "temp" : 289.51 , "pressure" : 1008 , "humidity" : 68 , "temp_min" : 287.15 , "temp_max" : 291.15 } , "visibility" : 10000 , "wind" : { "speed" : 4.6 , "deg" : 200 } , "clouds" : { "all" : 76 } , "dt" : 1500713400 , "sys" : { "type" : 1 , "id" : 5091 , "message" : 0.0077 , "country" : "GB" , "sunrise" : 1500696632 , "sunset" : 1500753755 } , "id" : 2643743 , "name" : "London" , "cod" : 200 }

Step -1

First you need to add the dependencies. Not just volley but you even need to add Gson library

compile 'com.android.volley:volley:1.0.0' compile 'com.google.code.gson:gson:2.2.4'

Step-2:

Create Java Objects for your response as per Gson guidelines.(Basically the java object here is which you want as reponse instead of the JSON) .The most simple way of doing that is available here. You just need to paste the response and it will automatically convert it into POJO files which you can download.

If your response has multiple json objects then multiple files will be created. As in the above response we have multiple JSON objects in the response, then pasting it will lead to creation of multiple POJOs. For the above json response 7 Java Objects were created.

Cloud.java

Coord.java

Main.java

Example.java

Sys.java

Weather.java

Wind.java

Only one of them represents the response, rest represent json objects which are a part of the response .I have named the response java object as Example.java

Step -3

First you need to create a Single Volley RequestQueue as we did in this example.

(Read it if you want to have a look at a complete working example of sending GET and POST request in volley)

/* Extend the Application class to create your own application class. */ public class MyApplication extends Application { //Declare a private RequestQueue variable private RequestQueue requestQueue; private static MyApplication mInstance; public void onCreate() { super.onCreate(); mInstance=this; } public static synchronized MyApplication getInstance() { return mInstance; } /** Create a getRequestQueue() method to return the instance of RequestQueue.This kind of implementation ensures that the variable is instantiated only once and the same instance is used throughout the application **/ public RequestQueue getRequestQueue() { if (requestQueue==null) requestQueue= Volley.newRequestQueue(getApplicationContext()); return requestQueue; } /* Method to add the Request to the the single instance of RequestQueue created above.Setting a tag to every request helps in grouping them. Tags act as identifier for requests and can be used while cancelling them */ public void addToRequestQueue(Request request,String tag) { request.setTag(tag); getRequestQueue().add(request); } /** Cancel all the requests matching with the given tag **/ public void cancelAllRequests(String tag) { getRequestQueue().cancelAll(tag); } }

Now comes the most important part- creating a custom request. All the inbuilt volley requests implement the Request class. So creating a custom request would require you to do the same. The code snippet below is self explanatory of how to implement a custom request

/** Create a class which extend the Volley Request<T> class **/ public class MyCustomRequest extends Request { private Response.Listener listener; /** Declare a gson variable which will be used to convert the json response to POJO **/ private Gson gson; /** Declare a Class variable. This Class will represent the POJO.Basically this variable will hold the instance of the java object which you want as response **/ private Class responseClass; /** Constructer for your custom class @param Request Method- GET,POST @param Request URL @param Java Object which you want as response @param Response listener to notify success response @param Error listener to notify error response **/ public MyCustomRequest(int method, String url,Class responseClass, Response.Listener listener, Response.ErrorListener errorListener) { super(method, url, errorListener); gson = new Gson(); this.listener=listener; this.responseClass=responseClass; } /** This method needs to be implemented to parse the raw network response and return an appropriate response type.This method will be called from a worker thread. The response will not be delivered if you return null. @param Network Response- Response payload as byte[],headers and status code **/ @Override protected Response parseNetworkResponse(NetworkResponse response) { try { /** First you will have to convert the NetworkResponse into a jsonstring. Then that json string can be converted into the required java object using gson **/ String jsonString = new String(response.data, HttpHeaderParser.parseCharset(response.headers, "utf-8")); return Response.success(gson.fromJson(jsonString,responseClass), HttpHeaderParser.parseCacheHeaders(response)); } catch (UnsupportedEncodingException e) { e.printStackTrace(); return Response.error(new ParseError(e)); } } /** This is called on the main thread with the object you returned in parseNetworkResponse(). You should be invoking your callback interface from here **/ @Override protected void deliverResponse(Object response) { listener.onResponse(response); } }

Step-4:

Now you just need to send the request with the custom class you created just now. Implementation will be same as that of an JsonObjectRequest or StringRequest. But instead of a JSON or string in response you will receive the Java object specified in the constructer

String url="http://api.openweathermap.org/data/2.5/weather?q=London&mode=json&appid=<your api key>;"; MyCustomRequest myCustomRequest=new MyCustomRequest(Request.Method.GET, url,Example.class, new Response.Listener<Example>() { @Override public void onResponse(Example example) { //Success Callback. } }, new Response.ErrorListener() { @Override public void onErrorResponse(VolleyError response) { //Failure callback Toast.makeText(MainActivity.this,"Error Encountered",Toast.LENGTH_SHORT).show(); } }); //Adding the request to a request queue MyApplication.getInstance().addToRequestQueue(myCustomRequest,"tag");