Pandamonium99
Pandamonium99

Reputation: 184

Android Volley, JsonObjectRequest but receiving JsonArray

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) {

                }
            });

Upvotes: 7

Views: 7009

Answers (3)

Makari Kevin
Makari Kevin

Reputation: 131

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)

🥂 :)

Upvotes: 1

HourGlass
HourGlass

Reputation: 1830

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.

Upvotes: 6

Yasin Yaqoobi
Yasin Yaqoobi

Reputation: 2040

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));
            }
    }
}

Upvotes: 8

Related Questions