在 Volley HTTP POST 请求中设置简单字符串 header(不是 key/value 对)
Set simple string header (not key/value pair) in Volley HTTP POST request
编辑:看起来主要问题是设置 string-only header 没有 key/value 对和相关的分隔符,因为 运行 没有“=”的手动 curl 请求得到了服务器响应,因此我编辑了标题。
我正在尝试使用 Volley 从 Android 应用发送 POST 请求以按照 this Amazon Alexa tutorial 中所述进行身份验证。
对于我发送的第二个请求(需要 header),我收到 400 服务器错误,表示请求错误。
根据教程页面,请求 header 应该是这样的:
The request must include the following headers:
POST /auth/o2/token
Host: api.amazon.com
Content-Type: application/x-www-form-urlencoded
如果我对 Volley Request class 使用常规的 getHeaders() 方法来覆盖 headers,我只能设置一个 hashmap,结果如下 header格式:
{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;
}
};
我怀疑 header 有什么问题,但我真的无法确定。我也尝试过不覆盖 headers,但无济于事。任何指针将不胜感激!谢谢!
本例中的 400 响应并不意味着我的请求格式错误。这只是服务器 returns 的响应代码,所有错误都与授权过程有关,在我的例子中,例如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();
编辑:看起来主要问题是设置 string-only header 没有 key/value 对和相关的分隔符,因为 运行 没有“=”的手动 curl 请求得到了服务器响应,因此我编辑了标题。
我正在尝试使用 Volley 从 Android 应用发送 POST 请求以按照 this Amazon Alexa tutorial 中所述进行身份验证。
对于我发送的第二个请求(需要 header),我收到 400 服务器错误,表示请求错误。
根据教程页面,请求 header 应该是这样的:
The request must include the following headers:
POST /auth/o2/token Host: api.amazon.com Content-Type: application/x-www-form-urlencoded
如果我对 Volley Request class 使用常规的 getHeaders() 方法来覆盖 headers,我只能设置一个 hashmap,结果如下 header格式:
{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;
}
};
我怀疑 header 有什么问题,但我真的无法确定。我也尝试过不覆盖 headers,但无济于事。任何指针将不胜感激!谢谢!
本例中的 400 响应并不意味着我的请求格式错误。这只是服务器 returns 的响应代码,所有错误都与授权过程有关,在我的例子中,例如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();