2

I need to make a request with a JSONObject as follows:

{
 'LangIDs': [1, 2],
 'GenreIDs': [4],
 'LowPrice': 0,
 'HighPrice': 999,
 'SearchTerms': [],
 'Pagination': {
 'PageNumber': 0,
 'PageLength': 10
 }
}

The expected response is a JSONArray. Using Volley, I can't make a JsonArrayRequest with a JSONObject parameter.

Before I made the request this way:

StringRequest jsonObjectRequest = new StringRequest(Request.Method.POST, url, new Response.Listener < String > () {
 @Override
 public void onResponse(String response) {
 JSONObject jsonObject;
 int id;
 String bookName;
 String Url;
 try {
 responseArray = new JSONArray(response);
 } catch (JSONException e) {
 }
 for (int i = 0; i < response.length(); i++) {
 try {
 jsonObject = responseArray.getJSONObject(i);
 id = jsonObject.getInt(Constants.KEY_ID);
 bookName = jsonObject.getString(Constants.KEY_BOOKNAME);
 Url = imgUrl + jsonObject.getString(Constants.KEY_IMG_URL);
 books.add(new Book(id, bookName, Url));
 } catch (JSONException e) {
 e.printStackTrace();
 }
 }
 mAdapter.updateGrid(books);
 Log.v("Response", response);
 }
}, new Response.ErrorListener() {@
 Override
 public void onErrorResponse(VolleyError error) {
 Log.e("Error:", error.getMessage());
 }
}) {@
 Override
 protected Map < String, String > getParams() throws AuthFailureError {
 HashMap < String, String > params = new HashMap < > ();
 String message = getArguments().getString(Constants.KEY_FILTER_VALUES);
 Log.v("FilterMessage", message);
 params.put(Constants.KEY_PAGENUMBER, String.valueOf(0));
 params.put(Constants.KEY_PAGELENGTH, String.valueOf(10));
 return params;
 }
};

But now it is JSONObject that contains JSONObject.

How now I can make this request using Volley?

Orkhan Alikhanov
10.2k4 gold badges50 silver badges66 bronze badges
asked Aug 30, 2016 at 19:24
0

3 Answers 3

15

I created a custom volley request that accepts a JSONObject as parameter.

CustomJsonArrayRequest.java

 public class CustomJsonArrayRequest extends JsonRequest<JSONArray> {
 /**
 * 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 CustomJsonArrayRequest(int method, String url, JSONObject jsonRequest,
 Listener<JSONArray> listener, ErrorListener errorListener) {
 super(method, url, (jsonRequest == null) ? null : jsonRequest.toString(), listener,
 errorListener);
 }
 @Override
 protected Response<JSONArray> parseNetworkResponse(NetworkResponse response) {
 try {
 String jsonString = new String(response.data,
 HttpHeaderParser.parseCharset(response.headers, PROTOCOL_CHARSET));
 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));
 }
 }
 }

How to use?

JSONObject body = new JSONObject();
// Your code, e.g. body.put(key, value);
CustomJsonArrayRequest req = new CustomJsonArrayRequest(Request.Method.POST, url, body, success, error);
OneCricketeer
193k20 gold badges147 silver badges277 bronze badges
answered Aug 31, 2016 at 7:06
Sign up to request clarification or add additional context in comments.

1 Comment

now would be interest to have: request JsonArray and receive a JSonObject.... It's so strange that Google does not cover mixed request/response :/
0

You can't extend JsonArrayRequest if your request doesn't send AND receive a JSONArray; same with JsonObjectRequest

For that you have to use StringRequest, and you should override getParams() to give it your JSONObject parameter.

StringRequest customRequest = new new StringRequest(Request.Method.POST, url, new Response.Listener<String>() {
 @Override
 protected Map<String, String> getParams() throws AuthFailureError {
 Map<String, String> requestInfo = new HashMap();
 //here add to your the request payload
 requestInfo.put("LowPrice", "0");
 return requestInfo;
 },
 @Override
 public void onResponse(String response) {
 //this code remains the same, 
 //you have to convert the String response to a JSONArray 
 }
 }, new Response.ErrorListener() {
 @Override
 public void onErrorResponse(VolleyError error) {
 Log.e("Error:",error.getMessage());
 }
 });
OneCricketeer
193k20 gold badges147 silver badges277 bronze badges
answered Aug 30, 2016 at 19:55

1 Comment

But I wrote almost the same code in question. Problem is that I must put in one of the key-value pairs the "Pagination" JSONObject as value.
-2

Use following class for passing json object as paramater:

public class VolleyJSonRequest {
 public void MakeJsonRequest(final String Tag, String url, final ArrayList<RequestModel> list, final ResponceLisnter responceLisnter, final String HeaderKey) {
 Map<String, String> params = new HashMap<String, String>();
 if (list.size() > 0) {
 for (int i = 0; i < list.size(); i++) {
 //MyLog.ShowLog(list.get(i).getKey(), list.get(i).getValue());
 params.put(list.get(i).getKey(), list.get(i).getValue());
 }
 }
 JSONObject obj = new JSONObject(params);
 JsonArrayRequest jsObjRequest = new JsonArrayRequest
 (Request.Method.POST, url, obj, new Response.Listener<JSONArray>() {
 @Override
 public void onResponse(JSONArray response) {
 try {
// Iterator x = response.keys();
// JSONArray jsonArray = new JSONArray();
//
// while (x.hasNext()){
// String key = (String) x.next();
// jsonArray.put(response.get(key));
// }
 responceLisnter.getResponce(response.toString(), Tag);
 } catch (JSONException e) {
 e.printStackTrace();
 }
 }
 }, new Response.ErrorListener() {
 @Override
 public void onErrorResponse(com.android.volley.VolleyError error) {
 // TODO Auto-generated method stub
 if (error instanceof TimeoutError || error instanceof NoConnectionError) {
 responceLisnter.getResponceError(VolleyError.TIMEOUT_ERROR, Tag);
 } else if (error instanceof AuthFailureError) {
 responceLisnter.getResponceError(VolleyError.AUTH_ERROR, Tag);
 } else if (error instanceof ServerError) {
 error.printStackTrace();
 responceLisnter.getResponceError(VolleyError.SERVER_ERROR, Tag);
 } else if (error instanceof NetworkError) {
 responceLisnter.getResponceError(VolleyError.NETWORK_ERROR, Tag);
 }
 }
 }) {
 /**
 * Passing some request headers
 * */
 @Override
 public Map<String, String> getHeaders() throws AuthFailureError {
 HashMap<String, String> headers = new HashMap<String, String>();
 headers.put("Content-Type", HeaderKey);
 return headers;
 }
 };
 ;
 TestVolleyJson.getInstance().getRequestQueue().add(jsObjRequest);
 jsObjRequest.setRetryPolicy(new DefaultRetryPolicy(50000, DefaultRetryPolicy.DEFAULT_MAX_RETRIES, DefaultRetryPolicy.DEFAULT_BACKOFF_MULT));
 }
}

In your Application class:

public class TestVolleyJson extends Application {
 private static TestVolleyJson mInstance;
 public static Context context;
 private RequestQueue mRequestQueue;
 public static synchronized TestVolleyJson getInstance() {
 return mInstance;
 }
 @Override
 public void onCreate() {
 super.onCreate();
 context = this;
 mInstance = this;
 mRequestQueue = Volley.newRequestQueue(this);
 }
 public RequestQueue getRequestQueue() {
 return mRequestQueue;
 }
}

Make a requestModel:

 public class RequestModel {
 String Key;
 String Value;
 public ArrayList<JSONObject> getJsonObjects() {
 return jsonObjects;
 }
 public void setJsonObjects(ArrayList<JSONObject> jsonObjects) {
 this.jsonObjects = jsonObjects;
 }
 ArrayList<JSONObject> jsonObjects;
 public RequestModel(String key, String value) {
 this.Key = key;
 this.Value = value;
 }
 public RequestModel(String key, ArrayList<JSONObject> jsonObjects) {
 this.Key = key;
 this.jsonObjects = jsonObjects;
 }
 public String getValue() {
 return Value;
 }
 public void setValue(String value) {
 Value = value;
 }
 public String getKey() {
 return Key;
 }
 public void setKey(String key) {
 Key = key;
 }
}

and in your activity:

 VolleyJSonRequest volleyJSonRequest = new VolleyJSonRequest();
 ArrayList<RequestModel> list = new ArrayList<>();
 list.add(new RequestModel("Param1", "abc"));
 list.add(new RequestModel("Param2", "xyz"));
 volleyJSonRequest.MakeJsonRequest("Tag", "URL", list, responceLisnter, "application/json; charset=utf-8");
}
ResponceLisnter responceLisnter = new ResponceLisnter() {
 @Override
 public void getResponce(String str, String Tag) throws JSONException {
 if (Tag.equalsIgnoreCase("Logintest")) {
 Log.e(Tag, " Response is" + str);
 }
 }
 @Override
 public void getResponceError(String errorStr, String Tag) {
 }
 };

Make a responselistener interface:

public interface ResponceLisnter {
 void getResponce(String str, String Tag) throws JSONException;
 void getResponceError(String errorStr, String Tag);
}

Hope it will work for you

answered Aug 11, 2017 at 13:41

5 Comments

dont forget to implement your activity with responselistener interface
Volley already has Response.Listener, so not sure why you need your own interfaces
@cricket_007 yeah u r right we can implement volleys listener but in my case i have some custom requirements so i have pasted my working code here only.
@cricket_007 here i need tag so that i can check which API is called and whose result is this if I have 3 to 4 API calling in same activity then how can I validate response
You'd have to use different listener objects for different responses. In any case, tags of numbers (like how Intents work), are slightly more performant than comparing strings

Your Answer

Draft saved
Draft discarded

Sign up or log in

Sign up using Google
Sign up using Email and Password

Post as a guest

Required, but never shown

Post as a guest

Required, but never shown

By clicking "Post Your Answer", you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.