Android Volley, JsonObjectRequest but receiving JsonArray
Asked Answered
B

3

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

                }
            });
Brunelle answered 2/2, 2016 at 6:30 Comment(10)
Have you tried with StringRequest ? try it and check what String value getting in onResponse Zipah
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.Falchion
Can u share ur service? I think you are returning array from your service.Parlay
This could be useful: developer.android.com/training/volley/request.htmlAnthracosilicosis
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.Brunelle
can you upload your json here and try StringRequest postRequest = new StringRequest(Request.Method.POST, url, new Response.Listener<String>() { may help youInterior
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 jsonarrayFalchion
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.Falchion
the decleration for JsonArrayRequest public JsonArrayRequest(int method, String url, JSONArray jsonRequest, Listener<JSONArray> listener, ErrorListener errorListener) { super(method, url, (jsonRequest == null) ? null : jsonRequest.toString(), listener, errorListener); } Does indeed require a JsonArray rather then JsonObject to send?Brunelle
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<T> listener, ErrorListener errorListener) {} taken this from official volley libraryFalchion
E
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));
            }
    }
}
Ethbun answered 6/10, 2016 at 18:7 Comment(0)
T
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.

Tradeswoman answered 2/2, 2016 at 9:54 Comment(0)
C
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)

🥂 :)

Consensus answered 17/1, 2021 at 12:45 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.