在 Volley HTTP POST 请求中设置简单的字符串标头不是键/值对

如何解决在 Volley HTTP POST 请求中设置简单的字符串标头不是键/值对

编辑:看起来主要问题是设置没有键/值对和相关分隔符的仅字符串标头,因为运行没有“=”的手动卷曲请求为我提供了一个服务器回复,因此我编辑了标题

我正在尝试使用 Volley 从 Android 应用发送 POST 请求以按照 this Amazon Alexa tutorial 中所述进行身份验证。

对于我发送的第二个请求(需要一个标头),我收到 400 服务器错误,表明请求错误

根据教程页面,这是请求标头的样子:

请求必须包含以下标头:

POST /auth/o2/token
Host: api.amazon.com
Content-Type: application/x-www-form-urlencoded

如果我对 Volley Request 类使用常规的 getHeaders() 方法来覆盖标头,我只能设置一个 hashmap,这会导致以下标头格式:

{Host=api.amazon.com,Content-Type=application/x-www-form-urlencoded}

(或 {POST=/auth/o2/token,Host=api.amazon.com,Content-Type=application/x-www-form-urlencoded},如果我在第一位包含另一行)

总的来说,我是 Volley 的新手,我想知道我是否在这里遗漏了一些非常明显的东西。这是我发送的请求:

StringRequest tokenPoller = new StringRequest(
        Request.Method.POST,"https://api.amazon.com/auth/O2/token",new Response.Listener<String>() {
            @Override
            public void onResponse(String response) {
                Log.i("volley",response);
            }
        },new Response.ErrorListener() {

            @Override
            public void onErrorResponse(VolleyError error) {
                VolleyLog.d("volley","Error: " + error.getMessage());
                error.printstacktrace();
            }
        }) {

    @Override
    public String getBodyContentType() {
        return "application/x-www-form-urlencoded";
    }

    @Override
    protected Map<String,String> getParams() throws AuthFailureError {
        Map<String,String> params = new HashMap<String,String>();
        params.put("grant_type","device_code");
        params.put("device_code",{{my device code from prevIoUs request}});
        params.put("user_code",{{my user code from prevIoUs request}});
        return params;
    }

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

        return headers;
    }
};

我怀疑有关标题的某些内容关闭,但我真的无法解决。我也试过不覆盖标题,但无济于事。任何指针将不胜感激!谢谢!

解决方法

这种情况下的 400 响应并不意味着我的请求格式不正确。这只是服务器返回的响应代码以及与授权过程相关的所有错误,在我的情况下,例如authorization_pending。由于我没有请求错误消息(通过 Volley 或其他方式),我直到很久以后才看到。

虽然教程确实提到在轮询令牌时可以传递多种响应,但没有提到它们实际上是 400 响应的错误和错误描述。

我最终从 Volley 切换到 HttpsUrlConnection,并使用 this question 的响应将错误和错误消息作为 json 响应接收并实现相应的响应。

最后,我的 HTTP 请求是这样的:

String stringUrl = "https://api.amazon.com/auth/o2/token";
URL url = null;

try {
    url = new URL(stringUrl);
} catch (MalformedURLException exception) {
    Log.e(TAG,"Error with creating URL",exception);
}

String response = "";
HttpsURLConnection conn = null;
HashMap<String,String> params = new HashMap<String,String>();
String scope_data = null;


try {
    params.put("grant_type","device_code");
    params.put("device_code",mDeviceCode);
    params.put("user_code",mUserCode);
    Set set = params.entrySet();
    Iterator i = set.iterator();
    StringBuilder postData = new StringBuilder();
    for (Map.Entry<String,String> param : params.entrySet()) {
        if (postData.length() != 0) {
            postData.append('&');
        }
        postData.append(URLEncoder.encode(param.getKey(),"UTF-8"));
        postData.append('=');
        postData.append(URLEncoder.encode(String.valueOf(param.getValue()),"UTF-8"));
    }
    byte[] postDataBytes = postData.toString().getBytes("UTF-8");


    conn = (HttpsURLConnection) url.openConnection();

    conn.setRequestMethod("POST");
    conn.setRequestProperty("Content-Type","application/x-www-form-urlencoded");

    conn.setDoOutput(true);
    conn.getOutputStream().write(postDataBytes);

    InputStream inputStream = null;

    try {
        inputStream = conn.getInputStream();
    } catch(IOException exception) {
        inputStream = conn.getErrorStream();
    }

    BufferedReader reader = new BufferedReader(new InputStreamReader(inputStream));
    StringBuilder builder = new StringBuilder();

    for (String line = null; (line = reader.readLine()) != null;) {
        builder.append(line).append("\n");
    }

    reader.close();
    conn.disconnect();

    response = builder.toString();

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。

相关推荐


Selenium Web驱动程序和Java。元素在(x,y)点处不可单击。其他元素将获得点击?
Python-如何使用点“。” 访问字典成员?
Java 字符串是不可变的。到底是什么意思?
Java中的“ final”关键字如何工作?(我仍然可以修改对象。)
“loop:”在Java代码中。这是什么,为什么要编译?
java.lang.ClassNotFoundException:sun.jdbc.odbc.JdbcOdbcDriver发生异常。为什么?
这是用Java进行XML解析的最佳库。
Java的PriorityQueue的内置迭代器不会以任何特定顺序遍历数据结构。为什么?
如何在Java中聆听按键时移动图像。
Java“Program to an interface”。这是什么意思?
Java在半透明框架/面板/组件上重新绘画。
Java“ Class.forName()”和“ Class.forName()。newInstance()”之间有什么区别?
在此环境中不提供编译器。也许是在JRE而不是JDK上运行?
Java用相同的方法在一个类中实现两个接口。哪种接口方法被覆盖?
Java 什么是Runtime.getRuntime()。totalMemory()和freeMemory()?
java.library.path中的java.lang.UnsatisfiedLinkError否*****。dll
JavaFX“位置是必需的。” 即使在同一包装中
Java 导入两个具有相同名称的类。怎么处理?
Java 是否应该在HttpServletResponse.getOutputStream()/。getWriter()上调用.close()?
Java RegEx元字符(。)和普通点?