Volley JsonObjectRequest Post request not working
Asked Answered
B

9

81

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);
Blanketing answered 7/11, 2013 at 13:58 Comment(4)
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 ?Myrmeco
Yes of course. you have to create your CustomJsonObjectRequest like in here #19838320Blanketing
because the 3rd parameter to your constructor is null.Enwreathe
@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.Sungsungari
J
136

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);
Jaala answered 13/11, 2013 at 4:59 Comment(32)
Thx it works ! Why override getParams() in JsonObjectRequest is not worked ? Is it Volley bug ?Myrmeco
Its work for me, but how and why. what's wrong with getParems mehthod.Haffner
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?Scramble
this is not a bug, the getParams() doesn't invoke because JsonObjectRequest extended JsonRequest which invoke getBody() directly to encoding the constructor second parameter(call requestBody) as contentType, that's why it ignore your getParam() method.Selfpronouncing
@Jaala what is this.createRequestSuccessListener(), this.createRequestErrorListener()); I dont understand it please explain.Betweenwhiles
@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.Byerly
How to use headers with post method?Millen
@user2455320 look at this #24023054Jaala
but it's not working in my case.can I post my code? I have used both headers and parameters.Millen
@user2455320 create new question, before that test your REST api in any of the REST client plugin.Jaala
i was having a lot of issues, and this working nice :D thanksPeewee
How to pass JsonArray as params to request ?Headwaters
@Headwaters I'm sending array as string by array.toString() and backend dev responsibility to parse that one :)Jaala
ok. how i can cancel all request that are in volley queue Before processing my new requests?Headwaters
use this #16775167 & arnab.ch/blog/2013/08/…Jaala
WORKS WITH android:configChanges="keyboardHidden|orientation|screenSize", (in my case) your are awesome man pfff +100 likesCoppage
@Jaala this.createRequestSuccessListener(), this.createRequestErrorListener()); cannot be resolved in my activity how can i fix that please. Thank youCitrate
@MostafaAddam you should implement that Listener Ref: michenux.net/android-volley-and-gson-tutorial-797.htmlJaala
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.Arvad
@Jaala What about the this.creatSuccessfulRequestListener ?Petal
@Jaala how to get response data in the RequestSuccessListener?Blowout
@Blowout arnab.ch/blog/2013/08/…Jaala
@Jaala I still can't get into my onresponse methode. (no response) pastebin.com/x2cMTTdX do you see the problem? thank youBlowout
what are "params" in helper? how do you create them in Activity?Monteverdi
@Monteverdi 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 https://mcmap.net/q/236851/-volley-post-get-parametersJaala
@Jaala possible to add JSONObject mparams instead of Map<String, String> params?Rescission
@Rescission try #32438227Jaala
@Jaala need help #37481728Dearman
and what if you want to add json body ??Boulogne
And what about if I want to send a header with the auth token? @JaalaHortensiahorter
@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 -->android-arsenal.com/search?q=volley hope this helps youJaala
Its working but when i add multiple headers using getHeaders() method its not working :(Squaw
E
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);
Eisinger answered 7/11, 2013 at 14:51 Comment(6)
nice and fast ! but if you need x-www-urlencoded is it done by volley?Underdrawers
I'm not sure, but you can easily test it.Eisinger
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 : #18485147Underdrawers
You're right, I got mixed up between the methods (not enough sleep). I edited my answer.Eisinger
tried with POST and GET method. both not working. I'm out of idea.Pastrami
Your code is throwing > com.android.volley.ParseError: org.json.JSONException: Value <!DOCTYPE > of type java.lang.String cannot be converted to JSONObject exception. Do you know why?Kessiah
U
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.

Underdrawers answered 7/11, 2013 at 14:8 Comment(6)
I don't get it how to pass params here. String s = new String(param). What is it?Blanketing
it's just a string with my params there. I send it in the constructor. I ll show you some more.Underdrawers
Thanks @poutrathor if you can tell me how to send that params that in getParams() method.Blanketing
ah. So you want to use them as params. What do you post to your server by curiosity?Underdrawers
My goal is that I have to send params like wrote in getParams, I can't send there jsonObject.Blanketing
i edit it for u. but look at below, there is a new simpler answer for your case :)Underdrawers
A
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
        }
    });


}
Apoplectic answered 22/12, 2017 at 18:38 Comment(0)
R
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.

Reata answered 18/1, 2016 at 19:41 Comment(0)
B
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

Boulogne answered 16/11, 2016 at 11:49 Comment(0)
E
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!

Eleventh answered 17/5, 2018 at 9:57 Comment(0)
G
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
        }

    }
Glory answered 3/5, 2020 at 17:55 Comment(0)
E
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;
    }
?>
Excise answered 21/10, 2020 at 3:48 Comment(1)
Could you explain this code? Right now it's a bit unclear how this solves the problem.Toponymy

© 2022 - 2024 — McMap. All rights reserved.