【问题标题】:Pass Parameter with Volley POST使用 Volley POST 传递参数
【发布时间】:2018-11-07 04:56:47
【问题描述】:

我能够使用 Postman 和这些参数调用 HTTP 端点:

{
    "name":"Val",
    "subject":"Test"
}

但是我无法通过 Android 对 Volley 做同样的事情:这里正在尝试使用 JSONRequest:

HashMap<String, String> params2 = new HashMap<String, String>();
        params.put("name", "Val");
        params.put("subject", "Test Subject");

        JsonObjectRequest jsObjRequest = new JsonObjectRequest
                (Request.Method.POST, Constants.CLOUD_URL, new JSONObject(params2), new Response.Listener<JSONObject>() {

                    @Override
                    public void onResponse(JSONObject response) {
                        mView.showMessage("Response: " + response.toString());
                    }
                }, new Response.ErrorListener() {

                    @Override
                    public void onErrorResponse(VolleyError error) {
                        // TODO Auto-generated method stub
                        mView.showMessage(error.getMessage());

                    }
                });

        // Access the RequestQueue through your singleton class.
        VolleySingleton.getInstance(mContext).addToRequestQueue(jsObjRequest);

这里正在尝试 StringRequest

private void postMessage(Context context, final String name, final String subject ){

        RequestQueue queue = Volley.newRequestQueue(context);
        StringRequest sr = new StringRequest(Request.Method.POST, Constants.CLOUD_URL, new Response.Listener<String>() {
            @Override
            public void onResponse(String response) {
                mView.showMessage(response);
            }
        }, new Response.ErrorListener() {
            @Override
            public void onErrorResponse(VolleyError error) {

            }
        }){
            @Override
            protected Map<String,String> getParams(){
                Map<String,String> params = new HashMap<String, String>();
                params.put("name", name);
                params.put("subject", subject);

                return params;
            }

            @Override
            public Map<String, String> getHeaders() throws AuthFailureError {
                Map<String,String> params = new HashMap<String, String>();
                params.put("Content-Type","application/x-www-form-urlencoded");
                return params;
            }
        };
        queue.add(sr);
    }

当我使用 JSONRequest 时,调用 POSTs 但未传递任何参数,当我使用 StringRequest 时出现以下错误?如何将 JSON 数据传递给 Volley 调用?

E/Volley: [13053] BasicNetwork.performRequest: Unexpected response code 400 for 

这是处理请求的服务器代码

public static async Task<HttpResponseMessage> Run(HttpRequestMessage req, TraceWriter log)
{
    var helloRequest = await req.Content.ReadAsAsync<HelloRequest>();

    var name = helloRequest?.Name ?? "world";    
    var responseMessage = $"Hello {personToGreet}!";


    log.Info($"Message: {responseMessage}");


    return req.CreateResponse(HttpStatusCode.OK, $"All went well.");
}

public class HelloRequest
{
    public string Name { get; set; }
    public string Subject { get; set; }
}

【问题讨论】:

  • 服务器是否接受 JSON 或 URL 编码形式? new JSONObject(params2) 是使用JSONObjectRequest 的正确方法。您的 StringRequest 没有传递 JSON 数据。查看getHeaders()中的Content-Type
  • 您能否向我们展示您正在处理 POST 请求的服务器部分?您的 JSONObject POST 请求看起来不错。
  • 我已经添加了处理这个请求的服务器代码。

标签: android android-volley azure-functions


【解决方案1】:

服务器代码期望 JSON 对象返回字符串或者更确切地说是 Json 字符串。

JsonObjectRequest

JSONRequest 在请求正文中发送一个 JSON 对象,并在响应中期望一个 JSON 对象。由于服务器返回一个字符串,它最终抛出 ParseError

字符串请求

StringRequest 发送一个正文类型为 x-www-form-urlencoded 的请求,但因为服务器需要一个 JSON 对象。你最终得到 400 Bad Request

解决方案

解决方案是将字符串请求中的内容类型更改为 JSON,并在正文中传递一个 JSON 对象。因为它已经需要一个字符串,所以你会响应你在那里很好。代码如下。

StringRequest sr = new StringRequest(Request.Method.POST, Constants.CLOUD_URL, new Response.Listener<String>() {
    @Override
    public void onResponse(String response) {
        mView.showMessage(response);
    }
}, new Response.ErrorListener() {
    @Override
    public void onErrorResponse(VolleyError error) {
        mView.showMessage(error.getMessage());
    }
}) {
    @Override
    public byte[] getBody() throws AuthFailureError {
        HashMap<String, String> params2 = new HashMap<String, String>();
        params2.put("name", "Val");
        params2.put("subject", "Test Subject");
        return new JSONObject(params2).toString().getBytes();
    }

    @Override
    public String getBodyContentType() {
        return "application/json";
    }
};

服务器代码中也有一个错误

var responseMessage = $"Hello {personToGreet}!";

应该是

var responseMessage = $"Hello {name}!";

【讨论】:

  • 如何使用 volley 在 getParams() 方法中添加字符串列表?在我的情况下,我需要添加一个字符串和一个字符串列表的参数。请帮帮我
【解决方案2】:

在标题中添加内容类型

@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;
}    

【讨论】:

    【解决方案3】:

    您在传递参数时在哈希图中使用 params.put 而不是 params2.put。 因为你的对象名称是 params2

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2020-11-20
      • 1970-01-01
      • 2015-10-13
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2018-06-03
      相关资源
      最近更新 更多