83

I am using android Volley for making a request. So I use this code. I don't understand one thing. I check in my server that params is always null. I consider that getParams() not working. What should I do to solve this issue.

 RequestQueue queue = MyVolley.getRequestQueue();
        JsonObjectRequest jsObjRequest = new JsonObjectRequest(Request.Method.POST,SPHERE_URL,null,
                new Response.Listener<JSONObject>() {
                    @Override
                    public void onResponse(JSONObject response) {
                        System.out.println(response);
                        hideProgressDialog();
                    }
                },
                new Response.ErrorListener() {
                    @Override
                    public void onErrorResponse(VolleyError error) {
                      hideProgressDialog();
                    }
                }) {
            protected Map<String, String> getParams() throws AuthFailureError {
                Map<String, String> params = new HashMap<String, String>();
                params.put("id","1");
                params.put("name", "myname");
                return params;
            };
        };
        queue.add(jsObjRequest);
Thein
  • 3,940
  • 2
  • 30
  • 34
pmb
  • 2,327
  • 3
  • 30
  • 47
  • 5
    Thx for you question. I also got trouble with JsonObjectRequest. So, I just use normal StringRequest.Then it worked. It seem volley bug. May I know how you solved that ? – Thein Dec 28 '13 at 08:57
  • Yes of course. you have to create your CustomJsonObjectRequest like in here http://stackoverflow.com/questions/19837820/volley-jsonobjectrequest-post-request-not-working – pmb Dec 29 '13 at 07:01
  • 1
    because the 3rd parameter to your constructor is null. – njzk2 Jun 04 '14 at 14:14
  • @njzk2: I think pmb is trying to send a POST request with url encoded parameters, not a JSON body, which is what the third argument is for. LOG_TAG's answer seems the most ap: a custom class that accepts parameters and still allows for a JSON response. – twelve17 Aug 11 '14 at 15:44

9 Answers9

137

try to use this helper class

import java.io.UnsupportedEncodingException;
import java.util.Map;    
import org.json.JSONException;
import org.json.JSONObject;    
import com.android.volley.NetworkResponse;
import com.android.volley.ParseError;
import com.android.volley.Request;
import com.android.volley.Response;
import com.android.volley.Response.ErrorListener;
import com.android.volley.Response.Listener;
import com.android.volley.toolbox.HttpHeaderParser;

public class CustomRequest extends Request<JSONObject> {

    private Listener<JSONObject> listener;
    private Map<String, String> params;

    public CustomRequest(String url, Map<String, String> params,
            Listener<JSONObject> reponseListener, ErrorListener errorListener) {
        super(Method.GET, url, errorListener);
        this.listener = reponseListener;
        this.params = params;
    }

    public CustomRequest(int method, String url, Map<String, String> params,
            Listener<JSONObject> reponseListener, ErrorListener errorListener) {
        super(method, url, errorListener);
        this.listener = reponseListener;
        this.params = params;
    }

    protected Map<String, String> getParams()
            throws com.android.volley.AuthFailureError {
        return params;
    };

    @Override
    protected Response<JSONObject> parseNetworkResponse(NetworkResponse response) {
        try {
            String jsonString = new String(response.data,
                    HttpHeaderParser.parseCharset(response.headers));
            return Response.success(new JSONObject(jsonString),
                    HttpHeaderParser.parseCacheHeaders(response));
        } catch (UnsupportedEncodingException e) {
            return Response.error(new ParseError(e));
        } catch (JSONException je) {
            return Response.error(new ParseError(je));
        }
    }

    @Override
    protected void deliverResponse(JSONObject response) {
        // TODO Auto-generated method stub
        listener.onResponse(response);
    }
}

In activity/fragment do use this

RequestQueue requestQueue = Volley.newRequestQueue(getActivity());
CustomRequest jsObjRequest = new CustomRequest(Method.POST, url, params, this.createRequestSuccessListener(), this.createRequestErrorListener());

requestQueue.add(jsObjRequest);
David Passmore
  • 6,089
  • 4
  • 46
  • 70
LOG_TAG
  • 19,894
  • 12
  • 72
  • 105
  • 1
    Thx it works ! Why override getParams() in JsonObjectRequest is not worked ? Is it Volley bug ? – Thein Dec 28 '13 at 09:26
  • Its work for me, but how and why. what's wrong with getParems mehthod. – Ashish Dwivedi May 05 '14 at 08:05
  • Wow! works like a charm..Thanks you saved my day..Is there any way to report this bug to google so that other developers dont waste their time on this? – Bala Vishnu May 11 '14 at 08:35
  • 1
    this is not a bug, the getParams() doesn't invoke because JsonObjectRequest extended [JsonRequest](https://android.googlesource.com/platform/frameworks/volley/+/master/src/com/android/volley/toolbox/JsonRequest.java) which invoke getBody() directly to encoding the constructor second parameter(call requestBody) as contentType, that's why it ignore your getParam() method. – VinceStyling Jun 25 '14 at 07:25
  • 1
    @LOG_TAG what is this.createRequestSuccessListener(), this.createRequestErrorListener()); I dont understand it please explain. – ik024 Sep 22 '14 at 04:47
  • 2
    @Droider Those are methods that create the proper response handling objects. Most likely they are made to be individual methods for purposes of readability. You could just as well create the objects in place with the `new` keyword, but depending on the size of the code for those objects it may be difficult to read at a glance. – jnfjnjtj Oct 21 '14 at 19:29
  • How to use headers with post method? – Ashok Kateshiya Nov 18 '14 at 04:08
  • 1
    @user2455320 look at this http://stackoverflow.com/questions/24022554/android-volley-post-request-header-not-changing – LOG_TAG Nov 18 '14 at 04:45
  • but it's not working in my case.can I post my code? I have used both headers and parameters. – Ashok Kateshiya Nov 18 '14 at 04:53
  • @user2455320 create new question, before that test your REST api in any of the REST client plugin. – LOG_TAG Nov 18 '14 at 05:14
  • 2
    i was having a lot of issues, and this working nice :D thanks – Javier Dec 04 '14 at 18:45
  • How to pass JsonArray as params to request ? – pathe.kiran Jun 03 '15 at 07:08
  • @pathe.kiran I'm sending array as string by array.toString() and backend dev responsibility to parse that one :) – LOG_TAG Jun 04 '15 at 03:35
  • ok. how i can cancel all request that are in volley queue Before processing my new requests? – pathe.kiran Jun 04 '15 at 06:21
  • use this http://stackoverflow.com/questions/16774667/cancel-all-volley-requests-android & http://arnab.ch/blog/2013/08/asynchronous-http-requests-in-android-using-volley/ – LOG_TAG Jun 04 '15 at 11:25
  • WORKS WITH android:configChanges="keyboardHidden|orientation|screenSize", (in my case) your are awesome man pfff +100 likes –  Jun 19 '15 at 09:09
  • @LOG_TAG this.createRequestSuccessListener(), this.createRequestErrorListener()); cannot be resolved in my activity how can i fix that please. Thank you – Mostafa Addam Sep 16 '15 at 12:37
  • @MostafaAddam you should implement that Listener Ref: http://www.michenux.net/android-volley-and-gson-tutorial-797.html – LOG_TAG Sep 18 '15 at 05:21
  • 1
    This custom class worked for me. Spend the whole day, tried to do without using this Custom class but of no use. I tried posting parameters in constructor, via getParams method, even i tried overriding getHeader method, but all in vain. At last this method was only the savior. Dont think much and use this custom class. It worked fine with Jsonarray as well. – Raghav Sharma Sep 19 '15 at 13:21
  • @LOG_TAG What about the `this.creatSuccessfulRequestListener` ? – Sauron Nov 05 '15 at 00:01
  • @LOG_TAG how to get response data in the RequestSuccessListener? – GNIUS Jan 06 '16 at 13:23
  • @GNIUS http://arnab.ch/blog/2013/08/asynchronous-http-requests-in-android-using-volley/ – LOG_TAG Jan 07 '16 at 07:09
  • @LOG_TAG I still can't get into my onresponse methode. (no response) http://pastebin.com/x2cMTTdX do you see the problem? thank you – GNIUS Jan 07 '16 at 13:40
  • what are "params" in helper? how do you create them in Activity? – user2254532 Jan 14 '16 at 14:07
  • @user2254532 while creating the request you going to use those params! example if you want to call a post rest api call we need to set that params (username password etc) in the activity http://stackoverflow.com/questions/16626032/volley-post-get-parameters – LOG_TAG Jan 15 '16 at 03:44
  • @LOG_TAG possible to add JSONObject mparams instead of Map params? – Aerrow Mar 10 '16 at 09:25
  • @Aerrow try http://stackoverflow.com/questions/32437727/pass-a-jsonobject-in-volley-as-post-parameter – LOG_TAG Mar 11 '16 at 16:25
  • @LOG_TAG need help http://stackoverflow.com/questions/37481228/post-method-using-volley-not-working – Aditya Vyas-Lakhan May 27 '16 at 11:00
  • and what if you want to add json body ?? – user4292106 Nov 16 '16 at 10:12
  • 1
    And what about if I want to send a header with the auth token? @LOG_TAG – Jordi Vicens Dec 29 '17 at 16:48
  • 1
    @JordiVicens I have moved to AndroidFastnetworking and retrofit libs considering LTS and I recommend you to use latest custom volley lib if you really want to use Volley -->https://android-arsenal.com/search?q=volley hope this helps you – LOG_TAG Jan 01 '18 at 10:17
  • Its working but when i add multiple headers using getHeaders() method its not working :( –  Jul 05 '18 at 07:22
32

You can create a custom JsonObjectRequest and override the getParams method, or you can provide them in the constructor as a JSONObject to be put in the body of the request.

Like this (I edited your code):

JSONObject obj = new JSONObject();
obj.put("id", "1");
obj.put("name", "myname");

RequestQueue queue = MyVolley.getRequestQueue();
JsonObjectRequest jsObjRequest = new JsonObjectRequest(Request.Method.POST,SPHERE_URL,obj,
    new Response.Listener<JSONObject>() {
        @Override
        public void onResponse(JSONObject response) {
             System.out.println(response);
             hideProgressDialog();
        }
    },
    new Response.ErrorListener() {
        @Override
        public void onErrorResponse(VolleyError error) {
             hideProgressDialog();
        }
    });
queue.add(jsObjRequest);
Reejesh
  • 1,745
  • 2
  • 6
  • 15
Itai Hanski
  • 8,540
  • 5
  • 45
  • 65
  • nice and fast ! but if you need x-www-urlencoded is it done by volley? – Poutrathor Nov 07 '13 at 14:55
  • I'm not sure, but you can easily test it. – Itai Hanski Nov 07 '13 at 15:02
  • Are you sure about that getParams not being called? At the contrary the code shows it is called by getBody() and getPostParams() and you say yourself the contrary here : http://stackoverflow.com/questions/18484647/volley-does-not-call-getparams-for-my-custom-request – Poutrathor Nov 07 '13 at 15:18
  • You're right, I got mixed up between the methods (not enough sleep). I edited my answer. – Itai Hanski Nov 07 '13 at 15:26
  • tried with POST and GET method. both not working. I'm out of idea. – Amir Fazwan Oct 13 '15 at 17:48
  • Your code is throwing > com.android.volley.ParseError: org.json.JSONException: Value of type java.lang.String cannot be converted to JSONObject exception. Do you know why? – The_Martian May 26 '16 at 19:18
5

Easy one for me ! I got it few weeks ago :

This goes in getBody() method, not in getParams() for a post request.

Here is mine :

    @Override
/**
 * Returns the raw POST or PUT body to be sent.
 *
 * @throws AuthFailureError in the event of auth failure
 */
public byte[] getBody() throws AuthFailureError {
    //        Map<String, String> params = getParams();
    Map<String, String> params = new HashMap<String, String>();
    params.put("id","1");
    params.put("name", "myname");
    if (params != null && params.size() > 0) {
        return encodeParameters(params, getParamsEncoding());
    }
    return null;

}

(I assumed you want to POST the params you wrote in your getParams)

I gave the params to the request inside the constructor, but since you are creating the request on the fly, you can hard coded them inside your override of the getBody() method.

This is what my code looks like :

    Bundle param = new Bundle();
    param.putString(HttpUtils.HTTP_CALL_TAG_KEY, tag);
    param.putString(HttpUtils.HTTP_CALL_PATH_KEY, url);
    param.putString(HttpUtils.HTTP_CALL_PARAM_KEY, params);

    switch (type) {
    case RequestType.POST:
        param.putInt(HttpUtils.HTTP_CALL_TYPE_KEY, RequestType.POST);
        SCMainActivity.mRequestQueue.add(new SCRequestPOST(Method.POST, url, this, tag, receiver, params));

and if you want even more this last string params comes from :

param = JsonUtils.XWWWUrlEncoder.encode(new JSONObject(paramasJObj)).toString();

and the paramasJObj is something like this : {"id"="1","name"="myname"} the usual JSON string.

Poutrathor
  • 1,990
  • 2
  • 20
  • 44
2

When you working with JsonObject request you need to pass the parameters right after you pass the link in the initialization , take a look on this code :

        HashMap<String, String> params = new HashMap<>();
        params.put("user", "something" );
        params.put("some_params", "something" );

    JsonObjectRequest request = new JsonObjectRequest(Request.Method.POST, "request_URL", new JSONObject(params), new Response.Listener<JSONObject>() {
        @Override
        public void onResponse(JSONObject response) {

           // Some code 

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


}
Kmelliti
  • 101
  • 7
1

All you need to do is to override getParams method in Request class. I had the same problem and I searched through the answers but I could not find a proper one. The problem is unlike get request, post parameters being redirected by the servers may be dropped. For instance, read this. So, don't risk your requests to be redirected by webserver. If you are targeting http://example/myapp , then mention the exact address of your service, that is http://example.com/myapp/index.php.
Volley is OK and works perfectly, the problem stems from somewhere else.

Community
  • 1
  • 1
Davood Falahati
  • 1,474
  • 16
  • 34
1

The override function getParams works fine. You use POST method and you have set the jBody as null. That's why it doesn't work. You could use GET method if you want to send null jBody. I have override the method getParams and it works either with GET method (and null jBody) either with POST method (and jBody != null)

Also there are all the examples here

user4292106
  • 441
  • 1
  • 11
  • 24
1

I had the same issue once, the empty POST array is caused due a redirection of the request (on your server side), fix the URL so it doesn't have to be redirected when it hits the server. For Example, if https is forced using the .htaccess file on your server side app, make sure your client request has the "https://" prefix. Usually when a redirect happens the POST array is lost. I Hope this helps!

0

It worked for can try this for calling with Volley Json Request and Response ith Java Code .

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
        }

    }
Tarit Ray
  • 944
  • 12
  • 24
0



build gradle(app)
dependencies {
    implementation fileTree(dir: "libs", include: ["*.jar"])
    implementation "org.jetbrains.kotlin:kotlin-stdlib:$kotlin_version"
    implementation 'androidx.core:core-ktx:1.1.0'
    implementation 'androidx.appcompat:appcompat:1.1.0-alpha01'
    implementation 'androidx.constraintlayout:constraintlayout:1.1.3'
    testImplementation 'junit:junit:4.12'
    androidTestImplementation 'androidx.test.ext:junit:1.1.1'
    androidTestImplementation 'androidx.test.espresso:espresso-core:3.2.0'
    implementation 'com.android.volley:volley:1.1.1'
}

android manifest
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />

MainActivity
When you use JsonObjectRequest it is mandatory to send a jsonobject and receive jsonobject otherwise you will get an error as it only accepts jsonobject.
import com.android.volley.Request
import com.android.volley.Response
import com.android.volley.toolbox.JsonObjectRequest
import com.android.volley.toolbox.Volley

fun peticion(){
    val jsonObject = JSONObject()
    jsonObject.put("user", "jairo")
    jsonObject.put("password", "1234")
    val queue = Volley.newRequestQueue(this)
    val url = "http://192.168.0.3/get_user.php"
    // GET: JsonObjectRequest( url, null,
    // POST: JsonObjectRequest( url, jsonObject,
    val jsonObjectRequest = JsonObjectRequest( url, jsonObject,
        Response.Listener { response ->
            // Check if the object 'msm' does not exist
            if(response.isNull("msm")){
                println("Name: "+response.getString("nombre1"))
            }
            else{
                // If the object 'msm' exists we print it
                println("msm: "+response.getString("msm"))
            }
        },
        Response.ErrorListener { error ->
            error.printStackTrace()
            println(error.toString())
        }
    )
    queue.add(jsonObjectRequest)
}

file php get_user.php
<?php
    header("Access-Control-Allow-Origin: *");
    header("Access-Control-Allow-Headers: *");
    // we receive the parameters
    $json = file_get_contents('php://input');
    $params = json_decode($json);
    error_reporting(0);
    require_once 'conexion.php';

    $mysqli=getConex();
    $user=$params->user;
    $password=$params->password;
    $res=array();
    $verifica_usuario=mysqli_query($mysqli,"SELECT * FROM usuarios WHERE usuario='$user' and clave='$password'");
    if(mysqli_num_rows($verifica_usuario)>0){
        $query="SELECT * FROM usuarios WHERE usuario='$user'";
        $result=$mysqli->query($query);
        while($row = $result->fetch_array(MYSQLI_ASSOC)){
            $res=$row;
        }
    }
    else{
        $res=array('msm'=>"Incorrect user or password");
    }
    $jsonstring = json_encode($res);
    header('Content-Type: application/json');
    echo $jsonstring;
?>

file php conexion
<?php
    function getConex(){
        $servidor="localhost";
        $usuario="root";
        $pass="";  
        $base="db";
        
        $mysqli = mysqli_connect($servidor,$usuario,$pass,$base);
        if (mysqli_connect_errno($mysqli)){
            echo "Fallo al conectar a MySQL: " . mysqli_connect_error();
        }
        $mysqli->set_charset('utf8');
        return $mysqli;
    }
?>
Jairo Rodriguez
  • 356
  • 2
  • 7