使用Volley发送带有JSONArray的POST请求

6
我想在Android中发送一个简单的POST请求,请求体应该等于以下内容:
[
 {
  "value": 1
 }
]

我尝试在Android中使用Volley库,这是我的代码:

// 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);

问题在于getParams方法只接受Map对象,而我想要发送一个JSONArray。所以,我不得不使用强制转换,这会生成错误。我不知道该如何解决这个问题。谢谢。

阅读我的答案在这里。但是,你的JSON是JSONArray而不是JSONObject。 - BNK
谢谢,我终于解决了这个问题,因为我使用了JSONArray。但是由于getparams方法,我又遇到了另一个错误... - fujitsu4
请发布它和任何可用的logcat信息。此外,对于POST body参数,请重写getBody而不是getParams。 - BNK
尝试重写getBody而不是getParams来处理POST请求的body参数。 - BNK
抱歉,我现在正在使用手机,所以请查看我上面评论的答案链接,或者您可以查看我在SO中关于Volley的其他答案(查看我的个人资料,然后查看我的答案)。服务器响应:如果成功,将调用onResponse;如果出错,则调用onErrorResponse。 - BNK
显示剩余13条评论
1个回答

5
你可以参考下面的示例代码:

针对你提供的 pastebin 链接的更新:

由于服务器响应的是一个JSONArray,所以我使用了 JsonArrayRequest 而不是 JsonObjectRequest。而且再也不需要覆盖 getBody 方法了。

        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();
        }

我的代码适用于Google官方的volley库和mcxiaoke的库

如果你想使用Google的库,在按照Google文档进行git clone后,从你克隆的Volley项目的\src\main\java\com目录下复制android文件夹到你的项目的\app\src\main\java\com目录下,如下图所示:

enter image description here

build.gradle应该包含以下内容:

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'    
}

如果您的项目使用了mcxiaoke的库,build.gradle文件将如下所示(请注意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'
}

我建议您创建两个新的示例项目,其中一个将使用 Google 的库,另一个将使用 mcxiaoke 的库。

更新结束

        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);

以下截图是服务器端Web服务收到的内容:

在此输入图片描述


我尝试了你的代码,但是出现了与“PROTOCOL_CHARSET”相关的错误。它告诉我:“com.android.volley.toolbox.JsonRequest中的'PROTOCOL_CHARSET'具有私有访问权限。” - fujitsu4
我猜你的项目在build.gradle文件中使用了volley库,版本为compile 'com.mcxiaoke.volley:library:1.0.17'。我的项目使用Google官方的volley库。你可以将PROTOCOL_CHARSET替换为"utf-8"。 - BNK
我仍然遇到一个错误:com.android.volley.ServerError。也许是由于糟糕的Volley库编程?或者采用Google的库可能是一个解决方案? - fujitsu4
1
是的,是的,是的,终于成功了。非常感谢你,真的非常感谢你! - fujitsu4
1
正好是我需要的 :) - ka_lin
显示剩余21条评论

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接