【问题标题】:Android Volley POST string in body正文中的Android Volley POST字符串
【发布时间】:2014-02-27 01:10:30
【问题描述】:

我正在尝试使用 Volley 库与我的 RESTful API 进行通信。

当我要求持有者令牌时,我必须在正文中发布字符串。字符串应如下所示: grant_type=密码&用户名=Alice&密码=密码123 和标题: 内容类型:application/x-www-form-urlencoded

有关 WebApi 个人帐户的更多信息: http://www.asp.net/web-api/overview/security/individual-accounts-in-web-api

不幸的是,我不知道如何解决它..

我正在尝试这样的事情:

StringRequest req = new StringRequest(Request.Method.POST, URL, new Response.Listener<String>() {
                    @Override
                    public void onResponse(String response) {
                        VolleyLog.v("Response:%n %s", response);
                    }
                }, new Response.ErrorListener() {
                    @Override
                    public void onErrorResponse(VolleyError error) {
                        VolleyLog.e("Error: ", error.getMessage());
                    }
                }){
                    @Override
                    protected Map<String, String> getParams() throws AuthFailureError {
                        Map<String, String> params = new HashMap<String, String>();
                        params.put("grant_type", "password");
                        params.put("username", "User0");
                        params.put("password", "Password0");
                        return params;
                    }

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

我一直收到 400 错误请求。 我认为我实际上是在发送这样的请求:

grant_type:password, username:User0, password:Password0

代替:

grant_type=password&username=Alice&password=password123

如果有人有任何想法或建议,我将非常感激..

【问题讨论】:

标签: android asp.net rest asp.net-web-api android-volley


【解决方案1】:

要发送带有用户名和密码等参数的普通 POST 请求(无 JSON),您通常会覆盖 getParams() 并传递参数映射:

public void HttpPOSTRequestWithParameters() {
    RequestQueue queue = Volley.newRequestQueue(this);
    String url = "http://www.somewebsite.com/login.asp";
    StringRequest postRequest = new StringRequest(Request.Method.POST, url, 
        new Response.Listener<String>() 
        {
            @Override
            public void onResponse(String response) {
                Log.d("Response", response);
            }
        }, 
        new Response.ErrorListener() 
        {
            @Override
            public void onErrorResponse(VolleyError error) {
                Log.d("ERROR","error => "+error.toString());
            }
        }
            ) {     
        // this is the relevant method
        @Override
        protected Map<String, String> getParams() 
        {  
            Map<String, String>  params = new HashMap<String, String>();
            params.put("grant_type", "password"); 
            // volley will escape this for you 
            params.put("randomFieldFilledWithAwkwardCharacters", "{{%stuffToBe Escaped/");
            params.put("username", "Alice");  
            params.put("password", "password123");

            return params;
        }
    };
    queue.add(postRequest);
}

若要在 Volley StringRequest 中将任意字符串作为 POST 正文数据发送,请覆盖 getBody()

public void HttpPOSTRequestWithArbitaryStringBody() {
    RequestQueue queue = Volley.newRequestQueue(this);
    String url = "http://www.somewebsite.com/login.asp";
    StringRequest postRequest = new StringRequest(Request.Method.POST, url, 
        new Response.Listener<String>() 
        {
            @Override
            public void onResponse(String response) {
                Log.d("Response", response);
            }
        }, 
        new Response.ErrorListener() 
        {
            @Override
            public void onErrorResponse(VolleyError error) {
                Log.d("ERROR","error => "+error.toString());
            }
        }
            ) {  
         // this is the relevant method   
        @Override
        public byte[] getBody() throws AuthFailureError {
            String httpPostBody="grant_type=password&username=Alice&password=password123";
            // usually you'd have a field with some values you'd want to escape, you need to do it yourself if overriding getBody. here's how you do it 
            try {
                httpPostBody=httpPostBody+"&randomFieldFilledWithAwkwardCharacters="+URLEncoder.encode("{{%stuffToBe Escaped/","UTF-8");
            } catch (UnsupportedEncodingException exception) {
                Log.e("ERROR", "exception", exception);
                // return null and don't pass any POST string if you encounter encoding error
                return null;
            }
            return httpPostBody.getBytes();
        }
    };
    queue.add(postRequest);
}

顺便说一句,Volley 文档不存在,StackOverflow 答案的质量也很差。简直不敢相信这样的例子还没有答案。

【讨论】:

  • 你说得对,Volley 文档根本没有帮助!
【解决方案2】:

首先,我建议您通过打印到日志或使用诸如wireshark 或fiddler 之类的网络嗅探器来准确查看您发送的内容。

尝试将参数放入 body 中怎么样?如果您仍然需要 StringRequest,则需要扩展它并覆盖 getBody() 方法(类似于 JsonObjectRequest

【讨论】:

  • 几分钟前我刚刚在谷歌上搜索过!有用!!谢谢 :-) 对于其他感兴趣的人..您可以将 JsonObjectRequest 与 null JSON 和 Override getBody() 一起使用,或者使用 StringRequest 并且您必须如上所述扩展它.. 关于使用网络嗅探器的另一个问题。我正在使用 Fiddler,我记录请求的唯一方法是使用模拟器并将代理设置为 Fiddler。还有其他选择如何记录来自真实设备的请求吗?
  • 您可以通过 WiFi 连接到您的计算机所连接的同一网络,在设备上使用您的 PC 的 IP 作为主机名和 8888 设置代理港口。 Fiddler 现在应该接受您的请求。
【解决方案3】:

我知道这已经过时了,但我也遇到了同样的问题,我在这里找到了一个更清洁的解决方案:How to send a POST request using volley with string body?

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-09-24
    • 1970-01-01
    • 1970-01-01
    • 2017-11-24
    • 2017-11-14
    • 2021-05-24
    相关资源
    最近更新 更多