7

So I am using a JsonObjectRequest to send up a JsonObject to a rest call, but its returning a JsonArray rather then a JsonObject. Its giving me an error saying that it cannot parse the results from the JsonObjectRequest, but if I use JsonArrayRequest i cant send up a JsonObject in the body. How do I send up a JsonObject but get a JsonArray as a response?

        RequestQueue queue = Volley.newRequestQueue(this);
    JsonObjectRequest jsObjRequest = new JsonObjectRequest(Request.Method.POST,url,jsonBody,
            new Response.Listener<JSONObject>() {
                @Override
                public void onResponse(JSONObject response) {
                    String test = "";
                }
            },
            new Response.ErrorListener() {
                @Override
                public void onErrorResponse(VolleyError error) {

                }
            });
Sreehari
  • 5,621
  • 2
  • 25
  • 59
Pandamonium99
  • 174
  • 1
  • 10
  • 1
    Have you tried with `StringRequest` ? try it and check what String value getting in `onResponse ` – ρяσѕρєя K Feb 02 '16 at 06:33
  • I don't think there will be any problem in creating JsonArrayRequest and sending jsonarray as request body because request body always goes as a string. – Ankit Aggarwal Feb 02 '16 at 06:36
  • Can u share ur service? I think you are returning array from your service. – Noor Nawaz Feb 02 '16 at 06:37
  • This could be useful: https://developer.android.com/training/volley/request.html – M0CH1R0N Feb 02 '16 at 06:38
  • I cant use JsonArrayRequest because im sending up a JsonObject, i need to send a JsonObject up not a JsonArray, but i want to RECEIVE, a JsonArray. SendUp = JsonObject, Receive = JsonArray. – Pandamonium99 Feb 02 '16 at 06:42
  • can you upload your json here and try `StringRequest postRequest = new StringRequest(Request.Method.POST, url, new Response.Listener() {` may help you – Amit Basliyal Feb 02 '16 at 06:43
  • Nobody is stopping you from sending a jsonobject while using a jsonArrayRequest. 'josnArray' in 'jsonArrayRequest' only signifies that the output you get will be of type jsonArray. The json body you send is always a string so it doesn't matter whether your string is a jsonobject or a jsonarray – Ankit Aggarwal Feb 02 '16 at 06:46
  • the third parameter in the JsonArrayRequest is a String not a jsonObject, or a jsonArray. So whatever you are sending, will ultimately be converted to string. – Ankit Aggarwal Feb 02 '16 at 06:53
  • the decleration for JsonArrayRequest public JsonArrayRequest(int method, String url, JSONArray jsonRequest, Listener listener, ErrorListener errorListener) { super(method, url, (jsonRequest == null) ? null : jsonRequest.toString(), listener, errorListener); } Does indeed require a JsonArray rather then JsonObject to send? – Pandamonium99 Feb 02 '16 at 07:02
  • i don't know which method you are using but you can use this method to achieve what you want public JsonRequest(int method, String url, String requestBody, Listener listener, ErrorListener errorListener) {} taken this from official volley library – Ankit Aggarwal Feb 02 '16 at 09:14

3 Answers3

8

I faced this situation recently and realized that Volley doesn't offer any out of the box solution for this. You have create a custom response that takes in a json object request and returns an array. Once you create your own class you will be able to do something like this.

 CustomJsonRequest jsonObjectRequest = new CustomJsonRequest(Request.Method.POST, url, credentials, new Response.Listener<JSONArray>(){...}



package com.example.macintosh.klickcard.Helpers.Network;

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 org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;

import java.io.UnsupportedEncodingException;

/**
 * Created by yasinyaqoobi on 10/6/16.
 */

public class CustomJsonRequest<T> extends JsonRequest<JSONArray> {

    private JSONObject mRequestObject;
    private Response.Listener<JSONArray> mResponseListener;

    public CustomJsonRequest(int method, String url, JSONObject requestObject, Response.Listener<JSONArray> responseListener,  Response.ErrorListener errorListener) {
        super(method, url, (requestObject == null) ? null : requestObject.toString(), responseListener, errorListener);
        mRequestObject = requestObject;
        mResponseListener = responseListener;
    }

    @Override
    protected void deliverResponse(JSONArray response) {
        mResponseListener.onResponse(response);
    }

    @Override
    protected Response<JSONArray> parseNetworkResponse(NetworkResponse response) {
            try {
                String json = new String(response.data, HttpHeaderParser.parseCharset(response.headers));
                try {
                    return Response.success(new JSONArray(json),
                            HttpHeaderParser.parseCacheHeaders(response));
                } catch (JSONException e) {
                    return Response.error(new ParseError(e));
                }
            } catch (UnsupportedEncodingException e) {
                return Response.error(new ParseError(e));
            }
    }
}
Yasin Yaqoobi
  • 1,888
  • 3
  • 27
  • 38
6

i.The data your are attaching with the post request is fine. If you want to send a json object or json array , either of them is fine. The only thing you have to understand is.

When you send data to the server it will give you a response, in your case it is JSONArray. i.e your sending data (array or object) have nothing to do with the Request you are creating. you are simple attaching the data with the call.

you have to create a JsonArrayrequest to handle the server response.

string value = jsonbody.toString();
 JsonArrayRequest jsonArrayRequest = new JsonArrayRequest(Request.Method.POST,url,value,
            new Response.Listener<JSONArray>() {
                @Override 
                public void onResponse(JSONArray response) {
                    String test = "";
                } 
            }, 
            new Response.ErrorListener() {
                @Override 
                public void onErrorResponse(VolleyError error) {

                } 
            });  

If you are unsure of which response you will get from server(either Json object or Array), you can use StringRequest, which will process the response from server as string. which will also work in your case.

Marco
  • 1,073
  • 9
  • 22
HourGlass
  • 1,805
  • 1
  • 15
  • 29
1

Mine was the opposite, a JsonArrayRequest returning a JSONObject response.

My custom request, in Kotlin, was therefore as follows:

open class CustomJsonRequest(
    method: Int,
    url: String?,
    params: JSONArray,
    responseListener: Response.Listener<JSONObject>,
    listener: Response.ErrorListener?,
) :
    JsonRequest<JSONObject>(method, url, params.toString(), responseListener, listener) {

    override fun deliverResponse(response: JSONObject?) {
        super.deliverResponse(response)
    }

    override fun parseNetworkResponse(response: NetworkResponse): Response<JSONObject?>? {
        return try {
            val jsonString = String(response.data, Charset.forName(HttpHeaderParser.parseCharset(response.headers)))
            Response.success(JSONObject(jsonString), HttpHeaderParser.parseCacheHeaders(response))
        } catch (e: UnsupportedEncodingException) {
            Response.error(ParseError(e))
        } catch (je: JSONException) {
            Response.error(ParseError(je))
        }
    }
}

Then use it as follows:

val request: CustomJsonRequest =
                object : CustomJsonRequest(
                    Method.POST, url, you_JSONArray_request_body,
                    Response.Listener { response ->
                        // handle the JSONObject response
                    },
                    Response.ErrorListener { error ->
                        // handle the error response
                    }) {


                    // your request headers
                    override fun getHeaders(): Map<kotlin.String, kotlin.String>? {
                        return your_headers
                    }


                    // other overrides ...
                }
            
            // enqueue the request
            Volley.newRequestQueue(applicationContext).add(request)

:)

Makari Kevin
  • 111
  • 1
  • 4