Sending a POST request with JSONArray using Volley
Asked Answered
K

1

6

I want to send a simple POST request in Android with a body equaling this :

[
 {
  "value": 1
 }
]

I tried to use Volley library in Android, and this is my code :

// the jsonArray that I want to POST    
String json = "[{\"value\": 1}]";
JSONArray jsonBody = null;
try {
     jsonBody = new JSONArray(json);
    } catch (JSONException e) {
                               e.printStackTrace();
                              }
final JSONArray finalJsonBody = jsonBody;

// starting the request
final RequestQueue queue = Volley.newRequestQueue(getApplicationContext());
JsonObjectRequest request = 
new JsonObjectRequest(com.android.volley.Request.Method.POST,"https://...",null,

new Response.Listener<JSONObject>() {

@Override
public void onResponse(JSONObject response) {
Log.d("mytag", "Response is: " + response);}},
new Response.ErrorListener() {

@Override
public void onErrorResponse(VolleyError error) {
Log.d("Mytag", "error");}}) {

@Override
protected  Map<String,String> getParams() {
// the problem is here...
return (Map<String, String>) finalJsonBody;
}

@Override
public Map<String, String> getHeaders() throws AuthFailureError  {
HashMap<String, String> params = new HashMap<String, String>();
// I put all my headers here like the following one : 
params.put("Content-Type", "application/json");                                    
return params;}};

queue.add(request);

The problem is that the getParams method only accepts a Map object since I want to send a JSONArray. So, I'm obliged to use a cast, which generate an error then...

I don't know how can I fix that Thank you

Kenyettakenyon answered 23/9, 2015 at 17:2 Comment(18)
Read my asnwer here. However, your json is JSONArray, not JSONObject.Stolen
can you be more explicite? I still fail to code this jsonArray... thank you for your comprehensionKenyettakenyon
JSONObject jsonBody = new JSONObject("{\"value\": 1}"); a JSONObject starts with { and ends with }. Moreover, what is the error message did you get? Pls post it and any logcat info if available.Stolen
thanks man, I finally resolved this part since I use a JSONArray. But I get another error due to the getparams method...Kenyettakenyon
Pls post it and any logcat info if available. Moreover, overrid getBody instead of getParams for POST body paramsStolen
I edited my initial post. The error is from the "getParams" method which required a Map object. But in my case, I want to send "finalJsonBody" which is a JSONAray... I hope it's clear for you ?Kenyettakenyon
Try override getBody instead of getParams for POST body paramsStolen
If you want to send JSONArray as params, try using Google's official volley (git clone android.googlesource.com/platform/frameworks/volley) the use their JsonArrayRequestStolen
But it's what I'm trying to do. I don't know how can I send a JSONArray that's it. I'm trying to override getBody as you say but it's not obvious..Kenyettakenyon
So, what is the error message did you get? Can you post server side code that processes your request?Stolen
Ah, I see what you mean know. You talk about JsonArrayRequest while I'm using JsonObjectRequest. I don't find any useful tutorial or example about JsonArrayRequest...Kenyettakenyon
Not much different but the response :-)Stolen
Can you PLEASE tell me how can I override getBody in my example ? Or at least how can I get the server response. Because in my current code, I only got "error" as you can guess from my codeKenyettakenyon
Sorry, I am on mobile now, so please see my answer link I commented above or you can look at my other answers about Volley available in SO before (view my profile, then my answers). Response from server: if success, onResponse will be called; if error, onErrorResponse calledStolen
I looked in JsonArrayRequest in your link, but apparently, you can't do a POST with it, you can only do a get. It seems too complicated (while my request is not really as difficult as that). Can you help me please ? (with the getbody or anything else, all what I want is to do this request), you are the only one who had answered me...Kenyettakenyon
Please wait until tomorrow, however, please post your server-side code if availableStolen
The only error that I get is that : "com.android.volley.ServerError" (I get that with : Log.d("Mytag", "error is " + error);Kenyettakenyon
Use parseNetworkError to find out more detailsStolen
S
5

You can refer to my following sample code:

UPDATE for your pastebin link:

Because the server responses a JSONArray, I use JsonArrayRequest instead of JsonObjectRequest. And no need to override getBody anymore.

        mTextView = (TextView) findViewById(R.id.textView);
        String url = "https://api.orange.com/datavenue/v1/datasources/2595aa553d3049f0b0f03fbaeaa7ddc7/streams/9fe5edb1c76e4968bdcc9c902010bc6c/values";
        RequestQueue requestQueue = Volley.newRequestQueue(this);
        final String jsonString = "[\n" +
                " {\n" +
                "  \"value\": 1\n" +
                " }\n" +
                "]";
        try {
            JSONArray jsonArray = new JSONArray(jsonString);
            JsonArrayRequest jsonArrayRequest = new JsonArrayRequest(Request.Method.POST, url, jsonArray, new Response.Listener<JSONArray>() {
                @Override
                public void onResponse(JSONArray response) {
                    mTextView.setText(response.toString());
                }
            }, new Response.ErrorListener() {
                @Override
                public void onErrorResponse(VolleyError error) {
                    mTextView.setText(error.toString());
                }
            }) {
                @Override
                public Map<String, String> getHeaders() throws AuthFailureError {
                    Map<String, String> headers = new HashMap<>();
                    headers.put("X-OAPI-Key","TQEEGSk8OgWlhteL8S8siKao2q6LIGdq");
                    headers.put("X-ISS-Key","2b2dd0d9dbb54ef79b7ee978532bc823");
                    return headers;
                }
            };
            requestQueue.add(jsonArrayRequest);
        } catch (JSONException e) {
            e.printStackTrace();
        }

My code works for both Google's official volley libray and mcxiaoke's library

If you want to use Google's library, after you git clone as Google documentation, copy android folder from \src\main\java\com (of Volley project that you cloned) to \app\src\main\java\com of your project as the following screenshot:

enter image description here

The build.gradle should contain the following

dependencies {
    compile fileTree(dir: 'libs', include: ['*.jar'])
    compile 'com.android.support:appcompat-v7:23.0.1'
    compile 'com.google.code.gson:gson:2.3.1'    
}

If your project uses mcxiaoke's library, the build.gradle will look like the following (pay attention to dependencies):

apply plugin: 'com.android.application'

android {
    compileSdkVersion 23
    buildToolsVersion "23.0.0"

    defaultConfig {
        applicationId "com.example.samplevolley"
        minSdkVersion 16
        targetSdkVersion 23
        versionCode 1
        versionName "1.0"
    }
    buildTypes {
        release {
            minifyEnabled false
            proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
        }
    }
}

dependencies {
    compile fileTree(dir: 'libs', include: ['*.jar'])
    compile 'com.android.support:appcompat-v7:23.0.0'
    compile 'com.mcxiaoke.volley:library:1.0.17'
    compile 'com.google.code.gson:gson:2.3'
}

I suggest that you will create 2 new sample projects, then one will use Google's library, the other will use mcxiaoke's library.

END OF UPDATE

        String url = "http://...";
        RequestQueue requestQueue = Volley.newRequestQueue(this);
        final String jsonString = "[\n" +
                " {\n" +
                "  \"value\": 1\n" +
                " }\n" +
                "]";
        JsonObjectRequest jsonObjectRequest = new JsonObjectRequest(Request.Method.POST, url, null, new Response.Listener<JSONObject>() {
            @Override
            public void onResponse(JSONObject response) {
                // do something...
            }
        }, new Response.ErrorListener() {
            @Override
            public void onErrorResponse(VolleyError error) {
                // do something...
            }
        }) {
            @Override
            public byte[] getBody() {
                try {
                    return jsonString.getBytes(PROTOCOL_CHARSET);
                } catch (UnsupportedEncodingException uee) {
                    VolleyLog.wtf("Unsupported Encoding while trying to get the bytes of %s using %s",
                            jsonString, PROTOCOL_CHARSET);
                    return null;
                }
            }
        };
        requestQueue.add(jsonObjectRequest);

The following screenshot is what server-side web service received:

enter image description here

Stolen answered 25/9, 2015 at 6:13 Comment(26)
I tried your code and I get an error related to "PROTOCOL_CHARSET". It tells me : 'PROTOCOL_CHARSET' has private access in com.android.volley.toolbox.JsonRequestKenyettakenyon
I guess that your project uses volley library by compile 'com.mcxiaoke.volley:library:1.0.17' in build.gradle file. My project uses Google's official volley library. You can replace PROTOCOL_CHARSET by "utf-8"Stolen
I am still getting an error : com.android.volley.ServerError. Perhaps it's due to volley library which is badly programmed?? Perhaps it will be a solution to take the google one?Kenyettakenyon
I think you should override parseNetworkError to find out more error details. You should also check your server-side app to see how it processed your request.Stolen
I think it's better to work with the google library instead of mcxiaoke one. Do you know how can I find their .jar directly ? (I did a git clone in my Mac but after that I always get an error after the android start project command and it's very frustrating). Testing google library will be my last attempt^^Kenyettakenyon
I don't use jar file. After you git clone as Google documentation, copy android folder inside \src\main\java\com (of Volley project that you cloned) into \app\src\main\java\com of your project. About mcxiaoke's volley, I used it already, it is good too :-)Stolen
This is the request that I want to send : pastebin.com/wt4ndxvH Can you please test if it works for you or not? please. Thank you!!!Kenyettakenyon
Ok, I will test tomorrow. You can also do your own test by a very helpful tool. That is Postman for ChromeStolen
Ah no no, unfortunately it's not the case yet. I'm waiting for you to test if you can post the request that i showed you (i said thank you -by politeness- for all your help), but unfortunately the problem is still occuring. Sorry if my precedent message was ambiguousKenyettakenyon
I have tested as your pastepin link, it works. Here is the screenshot linkStolen
So, you need to add X-OAPI-Key and X-ISS-Key in the headers of the volley request.Stolen
Thank you very much!! I don't have android studio now. So, I can't test that before Monday. But I have faith this time, there is no reason to not work. Again, thank you very much!!!Kenyettakenyon
You're welcome! Don't worry, I often test OK before posting answer :-)Stolen
I tried your code since 2 hours and guess what. It still doesn't work for me, it will get me crazy... Here is my code : img11.hostingpics.net/pics/990905error1.png and here is the error message that i get in android studio : img11.hostingpics.net/pics/246513error2.png. In my opinion, it's due to the wrong library that i choose to work with, i should try the google one to fix this problem, what do you think please?Kenyettakenyon
Can you please tell me what import have you used, please? I'm so so confused. I used some like these : import com.android.volley.RequestQueue or import com.android.volley.Response. So it's the google library and not the mcxiaoke one no????Kenyettakenyon
YES, YES, YES, it finally works. Thank you so so so so so much, really THANK you man !Kenyettakenyon
Glad my answer could help you!Stolen
Can you tell me your email PLEASE? I just want to ask about an Android project (which is very very urgent because I have to finish it before this friday :( Thanks !Kenyettakenyon
My email [email protected] :)Stolen
@Stolen I saw your profile and I feel you might be able to help me the problem is I am sending some json data to mysql database using volley but the value of my last entry updates all the other values inside the database. This is a link to my code pastebin.com/DGVQkNJCTugboat
@anup I cannot find where you call "insertToDb" inside your code. However, IMO, you should create a new question in S.O instead comments here, because perhaps there will be many other comments beside above ones.Stolen
Exactly what I needed :)Futtock
hi , I used your suggested, but it gives com.android.volley.NoConnectionError: java.net.ConnectException error.Limestone
@Limestone check the connection from your phone to the web server/web service address, or you can search more in StackOverflow about that exceptionStolen
connection is fine .when I use 1.0 version it working fine,but when I use 1.0.17 version it throws following error 'com.android.volley.NoConnectionError'Limestone
@Limestone you can try with 1.0.19 at github.com/mcxiaoke/android-volley, however, as his notice this project is deprecated and no longer being maintained...Stolen

© 2022 - 2024 — McMap. All rights reserved.