Volley JsonObjectRequest Post parameters no longer work
Asked Answered
B

15

40

I am trying to send POST parameters in a Volley JsonObjectRequest. Initially, it was working for me by following what the official code says to do of passing a JSONObject containing the parameters in the constructor of the JsonObjectRequest. Then all of a sudden it stopped working and I haven't made any changes to the code that was previously working. The server no longer recognizes that any POST parameters are being sent. Here is my code:

RequestQueue queue = Volley.newRequestQueue(this);
String url ="http://myserveraddress";

// POST parameters
Map<String, String> params = new HashMap<String, String>();
params.put("tag", "test");

JSONObject jsonObj = new JSONObject(params);

// Request a json response from the provided URL
JsonObjectRequest jsonObjRequest = new JsonObjectRequest
        (Request.Method.POST, url, jsonObj, new Response.Listener<JSONObject>()
        {
            @Override
            public void onResponse(JSONObject response)
            {
                Toast.makeText(getApplicationContext(), response.toString(), Toast.LENGTH_SHORT).show();
            }
        },
        new Response.ErrorListener()
        {
            @Override
            public void onErrorResponse(VolleyError error)
            {
                Toast.makeText(getApplicationContext(), error.toString(), Toast.LENGTH_SHORT).show();
            }
        });

// Add the request to the RequestQueue.
queue.add(jsonObjRequest);

Here is the simple tester PHP code on the server:

$response = array("tag" => $_POST["tag"]);
echo json_encode($response);

The response I get is {"tag":null}
Yesterday, it worked fine and was responding with {"tag":"test"}
I haven't changed a single thing, but today it is no longer working.

In the Volley source code constructor javadoc it says that you can pass a JSONObject in the constructor to send post parameters at "@param jsonRequest": https://android.googlesource.com/platform/frameworks/volley/+/master/src/main/java/com/android/volley/toolbox/JsonObjectRequest.java

/**
 * 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.

I have read other posts with similar questions, but the solutions haven't worked for me:

Volley JsonObjectRequest Post request not working

Volley Post JsonObjectRequest ignoring parameters while using getHeader and getParams

Volley not sending a post request with parameters.

I've tried setting the JSONObject in the JsonObjectRequest constructor to null, then overriding and setting the parameters in the "getParams()", "getBody()", and "getPostParams()" methods, but none of those overrides has worked for me. Another suggestion was to use an additional helper class that basically creates a custom request, but that fix is a bit too complex for my needs. If it comes down to it I will do anything to make it work, but I am hoping that there is a simple reason as to why my code was working, and then just stopped, and also a simple solution.

Bilabiate answered 4/4, 2015 at 5:12 Comment(4)
Did you found any solution ?Sonics
@Sonics Yes, I did find a simple solution. It didn't fix the problem with JsonObjectRequest and I just abandoned JsonObjectRequest entirely as the solution was to use Volley's StringRequest instead. View my answer below to see what I did.Bilabiate
Check this link #19838320.Modestomodesty
#34367935 can anybody solve it ?Coursing
B
44

I ended up using Volley's StringRequest instead, because I was using too much valuable time trying to make JsonObjectRequest work.

RequestQueue queue = Volley.newRequestQueue(this);
String url ="http://myserveraddress";

StringRequest strRequest = new StringRequest(Request.Method.POST, url,
                new Response.Listener<String>()
                {
                    @Override
                    public void onResponse(String response)
                    {
                        Toast.makeText(getApplicationContext(), response, Toast.LENGTH_SHORT).show();
                    }
                },
                new Response.ErrorListener()
                {
                    @Override
                    public void onErrorResponse(VolleyError error)
                    {
                        Toast.makeText(getApplicationContext(), error.toString(), Toast.LENGTH_SHORT).show();
                    }
                })
        {
            @Override
            protected Map<String, String> getParams()
            {
                Map<String, String> params = new HashMap<String, String>();
                params.put("tag", "test");
                return params;
            }
        };

queue.add(strRequest);

This worked for me. Its just as simple as JsonObjectRequest, but uses a String instead.

Bilabiate answered 24/7, 2015 at 14:48 Comment(8)
it's getting a error response on android 5.1.1 , although working on android 4.2Coursing
its getting error BasicNetwork.performRequest: Unexpected response code 500 forKuban
@Joshua C. This saved my after hours of endless searching. Any idea why JSONObjectRequest doesn't work?Eccrinology
@sidiabale like yourself and Joshua C. I wanted to use JSONObjectRequest to take advantage of the implicit JSON parsing. Incredibly, if one uses this class-type, the POST'ed parameters are sent in JSON format. Typically one does not have control over what format a server uses for POSTing. So without being able to customize this behavior, JSONObjectRequest is pretty much useless.Glossator
This works well, but what if you want to send a JSONArray of objects?Octodecillion
is this method make the post formatted in json? and have headers Content-Type: application/json?Donetsk
Similarly, you can find another answer here: #41517897Spent
if the backend is expecting a jsonobject, sending it a string is going to blow up in your face... this is a hack not a solution.Safelight
W
58

You just have to make a JSONObject from your HashMap of parameters:

String url = "https://www.youraddress.com/";

Map<String, String> params = new HashMap();
params.put("first_param", 1);
params.put("second_param", 2);

JSONObject parameters = new JSONObject(params);

JsonObjectRequest jsonRequest = new JsonObjectRequest(Request.Method.POST, url, parameters, new Response.Listener<JSONObject>() {
    @Override
    public void onResponse(JSONObject response) {
        //TODO: handle success
    }
}, new Response.ErrorListener() {
    @Override
    public void onErrorResponse(VolleyError error) {
        error.printStackTrace();
        //TODO: handle failure
    }
});

Volley.newRequestQueue(this).add(jsonRequest);
Wenwenceslaus answered 11/11, 2015 at 22:9 Comment(3)
Correct. That's exactly what I did. Please look at the example code I posted. It worked at first, but suddenly stopped working. However, I have been using StringRequest as my solution and haven't had any problems since.Bilabiate
I have a doubt, where is the method name here?Arther
There is no method here, so you're not going to see any method name :p It's just some code that you can put in your own method ;)Wenwenceslaus
B
44

I ended up using Volley's StringRequest instead, because I was using too much valuable time trying to make JsonObjectRequest work.

RequestQueue queue = Volley.newRequestQueue(this);
String url ="http://myserveraddress";

StringRequest strRequest = new StringRequest(Request.Method.POST, url,
                new Response.Listener<String>()
                {
                    @Override
                    public void onResponse(String response)
                    {
                        Toast.makeText(getApplicationContext(), response, Toast.LENGTH_SHORT).show();
                    }
                },
                new Response.ErrorListener()
                {
                    @Override
                    public void onErrorResponse(VolleyError error)
                    {
                        Toast.makeText(getApplicationContext(), error.toString(), Toast.LENGTH_SHORT).show();
                    }
                })
        {
            @Override
            protected Map<String, String> getParams()
            {
                Map<String, String> params = new HashMap<String, String>();
                params.put("tag", "test");
                return params;
            }
        };

queue.add(strRequest);

This worked for me. Its just as simple as JsonObjectRequest, but uses a String instead.

Bilabiate answered 24/7, 2015 at 14:48 Comment(8)
it's getting a error response on android 5.1.1 , although working on android 4.2Coursing
its getting error BasicNetwork.performRequest: Unexpected response code 500 forKuban
@Joshua C. This saved my after hours of endless searching. Any idea why JSONObjectRequest doesn't work?Eccrinology
@sidiabale like yourself and Joshua C. I wanted to use JSONObjectRequest to take advantage of the implicit JSON parsing. Incredibly, if one uses this class-type, the POST'ed parameters are sent in JSON format. Typically one does not have control over what format a server uses for POSTing. So without being able to customize this behavior, JSONObjectRequest is pretty much useless.Glossator
This works well, but what if you want to send a JSONArray of objects?Octodecillion
is this method make the post formatted in json? and have headers Content-Type: application/json?Donetsk
Similarly, you can find another answer here: #41517897Spent
if the backend is expecting a jsonobject, sending it a string is going to blow up in your face... this is a hack not a solution.Safelight
S
19

I had a similar problem, but I found out that the problem was not on the client side, but in the server side. When you send a JsonObject, you need to get the POST object like this (in the server side):

In PHP:

$json = json_decode(file_get_contents('php://input'), true);
Shawna answered 15/4, 2016 at 14:35 Comment(5)
Fixed my problem (even though I found it somewhere else)Both
Thanks. I think this is the answer to OPs question.Bankruptcy
Thanks. Unfortunately this is the true answer, there is nothing to do with JSONObjectRequestTheorem
Can you please explain this? Do you have an example code in php?Nude
Should it be in place of the isset function in php?Nude
B
10

You can use StringRequest to do the same things you can wtih JsonObjectRequest, while still beeing able to easily send POST parameters. The only thing you have to do is to create a JsonObject out of the request String you get, and from there you can continue as if it were JsonObjectRequest.

StringRequest stringRequest = new StringRequest(Request.Method.POST, url, new Response.Listener<String>() {
                    @Override
                    public void onResponse(String response) {
                        try {
                            //Creating JsonObject from response String
                            JSONObject jsonObject= new JSONObject(response.toString());
                            //extracting json array from response string
                            JSONArray jsonArray = jsonObject.getJSONArray("arrname");
                            JSONObject jsonRow = jsonArray.getJSONObject(0);
                            //get value from jsonRow
                            String resultStr = jsonRow.getString("result");
                        } catch (JSONException e) {

                        }

                    }
                }, new Response.ErrorListener() {
                    @Override
                    public void onErrorResponse(VolleyError error) {

                    }
                }){
                    @Override
                    protected Map<String, String> getParams() throws AuthFailureError {
                        Map<String,String> parameters = new HashMap<String,String>();
                        parameters.put("parameter",param);

                        return parameters;
                    }

                };
                requestQueue.add(stringRequest);
Border answered 7/12, 2015 at 22:24 Comment(0)
W
3

Use CustomJsonObjectRequest helper class mentioned here.

and implement like this -

CustomJsonObjectRequest request = new CustomJsonObjectRequest(Method.POST, URL, null, new Response.Listener<JSONObject>() {
    @Override
    public void onResponse(JSONObject response) {
        Toast.makeText(getActivity(), response.toString(), Toast.LENGTH_SHORT).show();
    }
}, new Response.ErrorListener() {
    @Override
    public void onErrorResponse(VolleyError error) {
        Toast.makeText(getActivity(), "Error.", Toast.LENGTH_SHORT).show();
    }
}) {
    @Override
    protected Map<String, String> getParams() throws AuthFailureError {
        Map<String, String> params = new HashMap<String, String>();
        params.put("id", id);
        params.put("password", password);
        return params;
    }
};
VolleySingleton.getInstance().addToRequestQueue(request);
Whitney answered 22/4, 2015 at 8:16 Comment(1)
Yeah, but so why JsonObjectRequest use JSON also to create the body of the HTTP POST request? And should a server decode always that body to search for an optional JSON content, given that the body is usually send in plain text? Confusing...Giddings
G
3

Using the JSONObject object to send parameters means the parameters will be in JSON format in the HTTP POST request body :

Map<String, String> params = new HashMap<String, String>();
params.put("tag", "test");
params.put("tag2", "test2");
JSONObject jsonObj = new JSONObject(params);

Will create this JSON object and insert it into the body of the HTTP POST request:

{"tag":"test","tag2":"test2"}

Then the server must decode the JSON to understand these POST parameters.

But normally HTTP POST paramaters are write in the body like:

tag=test&tag2=test2

But NOW here the question is why Volley is set in this manner?

A server reading a HTTP POST method should by standard always try to read parameters also in JSON (other than in plain text) and so a server that does not accomplish is a bad server?

Or instead a HTTP POST body with parameters in JSON is not what normally a server want?

Giddings answered 9/6, 2016 at 9:4 Comment(0)
O
2

Might help someone and save you some time thinking. I had a similar issue, the server code was looking for the Content-Type header. It was doing it this way:

if($request->headers->content_type == 'application/json' ){ //Parse JSON... }

But Volley was sending the header like this:

'application/json; charset?utf-8'

Changing the server code to this did the trick:

if( strpos($request->headers->content_type, 'application/json') ){ //Parse JSON... 
Ommiad answered 21/6, 2016 at 20:48 Comment(0)
C
2

I had similar problem. But I found out that the problem was not on the server side, but the problem is about cache. You have to clear your RequestQueue Cache.

RequestQueue requestQueue1 = Volley.newRequestQueue(context);
requestQueue1.getCache().clear();
Convex answered 7/1, 2017 at 12:25 Comment(1)
Turns out this happens when you POST/GET to the same resource with the default caching implementation, since it uses the url as its keys. See https://mcmap.net/q/393446/-android-volley-caching-with-different-post-requestsAzevedo
I
2

You can do it this way:

CustomRequest request = new CustomRequest(Request.Method.POST, url, null, new Response.Listener<JSONObject>() {

        @Override
        public void onResponse(JSONObject response) {
           // Toast.makeText(SignActivity.this, response.toString(), Toast.LENGTH_SHORT).show();

            Log.d("response",""+response.toString());

            String status =  response.optString("StatusMessage");
            String actionstatus = response.optString("ActionStatus");
            Toast.makeText(SignActivity.this, ""+status, Toast.LENGTH_SHORT).show();
            if(actionstatus.equals("Success"))
            {
                Intent i = new Intent(SignActivity.this, LoginActivity.class);
                startActivity(i);
                finish();
            }
            dismissProgress();

        }
    }, new Response.ErrorListener() {
        @Override
        public void onErrorResponse(VolleyError error) {
            Toast.makeText(SignActivity.this, "Error."+error.toString(), Toast.LENGTH_SHORT).show();
            Log.d("response",""+error.toString());
            dismissProgress();
        }
    }) {
        @Override
        public String getBodyContentType() {
            return "application/x-www-form-urlencoded; charset=UTF-8";
        }

        @Override
        protected Map<String, String> getParams() throws AuthFailureError {
            Map<String, String> params = new HashMap<String, String>();
            params.put("Email", emailval);
            params.put("PassWord", passwordval);
            params.put("FirstName", firstnameval);
            params.put("LastName", lastnameval);
            params.put("Phone", phoneval);
            return params;
        }

    };
    AppSingleton.getInstance(SignActivity.this.getApplicationContext()).addToRequestQueue(request, REQUEST_TAG);

as per CustomRequest below link Volley JsonObjectRequest Post request not working

Imperfection answered 27/5, 2017 at 17:34 Comment(0)
C
2

It does work.
I parsed json object response using this:- works like a charm.

String  tag_string_req = "string_req";
        Map<String, String> params = new HashMap<String, String>();
        params.put("user_id","CMD0005");

        JSONObject jsonObj = new JSONObject(params);
String url="" //your link
        JsonObjectRequest jsonObjReq = new JsonObjectRequest(Request.Method.POST,
                url, jsonObj, new Response.Listener<JSONObject>() {

            @Override
            public void onResponse(JSONObject response) {
                Log.d("responce", response.toString());

                try {
                    // Parsing json object response
                    // response will be a json object
                    String userbalance = response.getString("userbalance");
Log.d("userbalance",userbalance);
                    String walletbalance = response.getString("walletbalance");
                    Log.d("walletbalance",walletbalance);

                } catch (JSONException e) {
                    e.printStackTrace();
                    Toast.makeText(getApplicationContext(),
                            "Error: " + e.getMessage(),
                            Toast.LENGTH_LONG).show();
                }

            }
        }, new Response.ErrorListener() {

            @Override
            public void onErrorResponse(VolleyError error) {
                Toast.makeText(getApplicationContext(),
                        error.getMessage(), Toast.LENGTH_SHORT).show();

            }
        });

        AppControllerVolley.getInstance().addToRequestQueue(jsonObjReq, tag_string_req);
Chlamydeous answered 11/8, 2017 at 19:46 Comment(0)
R
1

It worked for me can try this for calling with Volley for Json type request and response .

  public void callLogin(String sMethodToCall, String sUserId, String sPass) {
            RequestQueue requestQueue = Volley.newRequestQueue(getApplicationContext());

            JsonObjectRequest jsonObjectRequest = new JsonObjectRequest(
                    Request.Method.POST, ConstantValues.ROOT_URL_LOCAL + sMethodToCall.toString().trim(), addJsonParams(sUserId, sPass),
    //                JsonObjectRequest jsonObjectRequest = new JsonObjectRequest(Request.Method.POST, url, object,
                    new Response.Listener<JSONObject>() {
                        @Override
                        public void onResponse(JSONObject response) {
                            Log.d("onResponse", response.toString());
                            Toast.makeText(VolleyMethods.this, response.toString(), Toast.LENGTH_LONG).show(); // Test

                            parseResponse(response);
    //                        msgResponse.setText(response.toString());
    //                        hideProgressDialog();
                        }
                    },
                    new Response.ErrorListener() {

                        @Override
                        public void onErrorResponse(VolleyError error) {
                            VolleyLog.d("onErrorResponse", "Error: " + error.getMessage());
                            Toast.makeText(VolleyMethods.this, error.toString(), Toast.LENGTH_LONG).show();
    //                hideProgressDialog();
                        }
                    }) {

                /**
                 * Passing some request headers
                 */
                @Override
                public Map<String, String> getHeaders() throws AuthFailureError {
                    HashMap<String, String> headers = new HashMap<String, String>();
                    headers.put("Content-Type", "application/json; charset=utf-8");
                    return headers;
                }


            };

            requestQueue.add(jsonObjectRequest);
        }

        public JSONObject addJsonParams(String sUserId, String sPass) {
            JSONObject jsonobject = new JSONObject();
            try {
    //            {"id":,"login":"secretary","password":"password"}

                ///***//
                Log.d("addJsonParams", "addJsonParams");

    //            JSONObject jsonobject = new JSONObject();

    //            JSONObject jsonobject_one = new JSONObject();
    //
    //            jsonobject_one.put("type", "event_and_offer");
    //            jsonobject_one.put("devicetype", "I");
    //
    //            JSONObject jsonobject_TWO = new JSONObject();
    //            jsonobject_TWO.put("value", "event");
    //            JSONObject jsonobject = new JSONObject();
    //
    //            jsonobject.put("requestinfo", jsonobject_TWO);
    //            jsonobject.put("request", jsonobject_one);

                jsonobject.put("id", "");
                jsonobject.put("login", sUserId); // sUserId
                jsonobject.put("password", sPass); // sPass


    //            js.put("data", jsonobject.toString());

            } catch (JSONException e) {
                e.printStackTrace();
            }

            return jsonobject;
        }

        public void parseResponse(JSONObject response) {

            Boolean bIsSuccess = false; // Write according to your logic this is demo.
            try {
                JSONObject jObject = new JSONObject(String.valueOf(response));
                bIsSuccess = jObject.getBoolean("success");


            } catch (JSONException e) {
                e.printStackTrace();
                Toast.makeText(VolleyMethods.this, "" + e.toString(), Toast.LENGTH_LONG).show(); // Test
            }

        }
Recede answered 3/5, 2020 at 17:52 Comment(0)
S
1

Hope am not too late to the party: The issue is from the server side. If you are using PHP add the following lines at the top of your php api file (after includes)

$inputJSON = file_get_contents('php://input');
if(get_magic_quotes_gpc())
{
    $param = stripslashes($inputJSON);
}
else
{
    $param = $inputJSON;
}

$input = json_decode($param, TRUE);

Then to retrieve your values

$tag= $input['tag'];
Syverson answered 22/7, 2021 at 13:11 Comment(0)
E
1

Use GET in place of POST for using JsonObjectRequest

Engage answered 21/6, 2022 at 8:43 Comment(0)
S
1
VolleySingleton.getInstance()
                .add(new StringRequest(Request.Method.POST, urlToTest, new Response.Listener<String>() {
                         @Override
                         public void onResponse(String response) {
                             // do stuff...
                         }
                     }, new Response.ErrorListener() {
                         @Override
                         public void onErrorResponse(VolleyError error) {
                             // exception
                         }
                     }) {
                         @Override
                         public String getBodyContentType() {
                             return "application/x-www-form-urlencoded; charset=UTF-8";
                         }

                         @Override
                         protected Map<String, String> getParams() {
                             return ServerApi.getRequiredParamsRequest(context);
                         }

                     }
                );
Splitting answered 22/7, 2022 at 1:32 Comment(0)
G
-1

...Initially, it was working for me ....Then all of a sudden it stopped working and I haven't made any changes to the code

if you haven't made any changes to a previously working code then I suggest checking other parameters such as URL , as the IP address may change if you are using your own Computer as a server!

Gouache answered 18/7, 2017 at 12:45 Comment(1)
Please try to format your questions better. For instance use quotes.Superhuman

© 2022 - 2024 — McMap. All rights reserved.