Volley JSONException: End of input at character 0 of
Asked Answered
B

7

24

I've seen others come across this problem, but none of the posts have been able to assist me. I'm attempting to use Volley for my REST call library, and when I'm attempting to use a Put call with a JSON Object as a parameter, I'm getting error with: org.json.JSONException: End of input at character 0 of.

Here is the code:

protected void updateClientDeviceStatus(Activity activity, final int status) {
    JSONObject jsonParams = new JSONObject();
    try {
        jsonParams.put("statusId", String.valueOf(status));
    } catch (JSONException e1) {
        e1.printStackTrace();
    }
    Log.i(LOG_TAG, "json: " + jsonParams.toString());

    String url = Constants.API_URL + "client/device/" + getDeviceId();
    // Request a response from the provided URL.
    JsonObjectRequest request = new JsonObjectRequest
            (Request.Method.PUT, url, jsonParams, new Response.Listener<JSONObject>() {

                @Override
                public void onResponse(JSONObject response) {
                    Log.i(LOG_TAG, "updated client status");
                    Log.i(LOG_TAG, "response: " + response.toString());
                }
            }, new Response.ErrorListener() {

                @Override
                public void onErrorResponse(VolleyError error) {
                    Log.i(LOG_TAG, "error with: " + error.getMessage());
                    if (error.networkResponse != null)
                        Log.i(LOG_TAG, "status code: " + error.networkResponse.statusCode);


                }
            }) {

        @Override
        public Map<String, String> getHeaders() throws AuthFailureError {
            Map<String, String>  params = new HashMap<String, String>();
            params.put("User-Agent", getUserAgent());
            params.put("X-BC-API", getKey());

            return params;
        }

        @Override
        public String getBodyContentType() {
            return "application/json";
        }
    };

    request.setRetryPolicy(new DefaultRetryPolicy(20000, 3, DefaultRetryPolicy.DEFAULT_BACKOFF_MULT));
    MySingleton.getInstance(activity).addToRequestQueue(request);
    }
}

The jsonParams log displays:

json: {"statusId":"1"}

Is there another setting that I'm missing? It appears that the request can't parse the JSON Object. I even tried creating a HashMap and then using that to create a JSON Object, but I still get the same result.

Boehike answered 19/8, 2015 at 19:50 Comment(3)
This error is from your server side. Since the response from the server is not being send in the proper json format. Ensure if the api is working properly using the PostMan or any other API testing environment.Turnip
Try using Request.Method.POSTScriptwriter
The response is empty. The JSON exception is called if the string that is returned in the response is empty. An empty string can't be turned into a JSON object - well it could be null but the library decided to throw an exception instead. If you are not getting a response back at all, you can simply use StringRequest.Tillford
I
54

I also have encountered this issue.

It's not necessarily true that this is because a problem on your server side - it simply means that the response of the JsonObjectRequest is empty.

It could very well be that the server should be sending you content, and the fact that its response is empty is a bug. If, however, this is how the server is supposed to behave, then to solve this issue, you will need to change how JsonObjectRequest parses its response, meaning creating a subclass of JsonObjectRequest, and overriding the parseNetworkResponse to the example below.

    @Override
    protected Response<JSONObject> parseNetworkResponse(NetworkResponse response) {
        try {
            String jsonString = new String(response.data,
                    HttpHeaderParser.parseCharset(response.headers, PROTOCOL_CHARSET));

            JSONObject result = null;

            if (jsonString != null && jsonString.length() > 0)
                 result = new JSONObject(jsonString);

            return Response.success(result,
                    HttpHeaderParser.parseCacheHeaders(response));
        } catch (UnsupportedEncodingException e) {
            return Response.error(new ParseError(e));
        } catch (JSONException je) {
            return Response.error(new ParseError(je));
        }
    } 

Keep in mind that with this fix, and in the event of an empty response from the server, the request callback will return a null reference in place of the JSONObject.

Impulsion answered 19/8, 2015 at 20:47 Comment(6)
Thank you. That did the trick. Saved me many hours of headachesBoehike
I think we can override this method right inside this request without subclass.Kordofanian
that's called an anonymous subclass :)Impulsion
imcomplete answer i would say or copied, Its better if u post appropriate code to be used .Midbrain
@quicklearner - definitely not copied (as I said, I encountered this issue too, and this is how I solved it). Also, about 25 other people disagree with your "incomplete" assessment. Appropriate code was posted. If you provided some information regarding what you felt was missing, perhaps I could provide more information.Impulsion
@quicklearner I don't understand... this method is overridden inside JsonObjectRequest (as stated) to handle cases where the response arrives empty. then you can use this request normally without worrying about exceptions when the response is empty.Impulsion
H
2

Might not make sense but nothing else worked for me but adding a content-type header

mHeaders.put("Content-Type", "application/json");
Hamartia answered 9/2, 2017 at 22:3 Comment(2)
I've been struggling with this for hours! Thank you so much you saved my life!Treenatreenail
mHeaders.put("Accept", "application/json") has solved my problem.Resa
P
0

In my case it was simply the request I was sending(POST) was not correct. I cross-checked my fields and noted that there was a mismatch, which the server was expecting to get thus the error->end of input at character 0 of...

Phlegm answered 7/5, 2018 at 6:2 Comment(0)
P
0

I had the same problem, I fixed it by creating a custom JsonObjectRequest that can catch a null or empty response :

public class CustomJsonObjectRequest extends JsonObjectRequest {

public CustomJsonObjectRequest(int method, String url, JSONObject jsonRequest, Response.Listener<JSONObject> listener, Response.ErrorListener errorListener) {
    super(method, url, jsonRequest, listener, errorListener);
}

public CustomJsonObjectRequest(String url, JSONObject jsonRequest, Response.Listener<JSONObject> listener, Response.ErrorListener errorListener) {
    super(url, jsonRequest, listener, errorListener);
}

@Override
protected Response<JSONObject> parseNetworkResponse(NetworkResponse response) {
    try {
        String jsonString = new String(response.data,
                HttpHeaderParser.parseCharset(response.headers));

        JSONObject result = null;

        if (jsonString != null && jsonString.length() > 0)
            result = new JSONObject(jsonString);

        return Response.success(result,
                HttpHeaderParser.parseCacheHeaders(response));
    } catch (UnsupportedEncodingException e) {
        return Response.error(new ParseError(e));
    } catch (JSONException je) {
        return Response.error(new ParseError(je));
    }
}

Then just replace the default JsonObjectRequest by this one !

Pani answered 10/9, 2018 at 9:1 Comment(0)
L
0

You need to check if the server response is not empty. Maybe it could be a emtply String "".

        if (response.success()) {
            if (response.getData() == null) {
                return null;
            } else if (response.getData().length() <= 0){
                return null;
            }

           // Do Processing
            try {
Landed answered 17/8, 2020 at 13:42 Comment(0)
A
0

I have faced the same problem, there was just a small silly mistake that happened.

instead of

val jsonObject = JSONObject(response.body()?.string())

should be

val jsonObject = JSONObject(response.body()!!.string())
Alamode answered 10/9, 2021 at 7:15 Comment(0)
A
0

If you need this in kotlin this...

private fun deleteRequestWithToken(token: String, path: String, responseListener: Response.Listener<JSONObject?>, errorListener: Response.ErrorListener): JsonObjectRequest? {
        return object : JsonObjectRequest(Request.Method.DELETE, path, null, responseListener, errorListener) {
            @Throws(AuthFailureError::class)
            override fun getHeaders(): Map<String, String> {
                val headers = HashMap<String, String>()
                headers["Authorization"] = "Bearer $token"
                return headers
            }
            override fun parseNetworkResponse(response: NetworkResponse): Response<JSONObject>{
                try{
                    val jsonString = String(
                        response.data,
                        Charset.forName(HttpHeaderParser.parseCharset(response.headers))
                    )
                    var result: JSONObject? = null
                    if (jsonString != null && jsonString.length > 0) result = JSONObject(jsonString)
                    return Response.success<JSONObject?>(
                        result,
                        HttpHeaderParser.parseCacheHeaders(response)
                    )
                } catch (e: UnsupportedEncodingException)
                {
                    return Response.error(ParseError(e))
                } catch (je: JSONException)
                {
                    return Response.error(ParseError(je))
                }

            }
        }
    }
Aldos answered 26/10, 2023 at 3:1 Comment(1)
Your answer could be improved with additional supporting information. Please edit to add further details, such as citations or documentation, so that others can confirm that your answer is correct. You can find more information on how to write good answers in the help center.Gravel

© 2022 - 2024 — McMap. All rights reserved.