我正在开发一个Android应用程序,并且已经发现不同的Android版本在处理Http(s)URLConnections(http://stackoverflow.com/q/9556316/151682)方面有不同的方式。
我遇到了Android 4很好地通过HTTPS执行POST请求的问题,在运行下面的代码时会自动添加Content-Type等标题。
但是,在Android 2.3.5(设备和模拟器)上,对输出流的任何写入似乎都被忽略 - 我使用Web代理Charles调试它,并且在发送所有标头时,将数据写入输出流没有被发送......
任何人都知道如何解决这个问题?
注意:由于我正在开发的API只有一个自签名证书,我现在需要禁用认证验证。
TIA,Patrick
更新 与此同时,我也试图效仿,但无济于事:
close()
调用后调用flush()
close()
在致电close()
getInputStream()
HttpURLConnection connection = (HttpURLConnection) url.openConnection();
connection.setConnectTimeout(CONNECT_TIMEOUT);
connection.setDoOutput(true); // Triggers POST.
connection.setRequestMethod("POST");
int contentLength = 0;
if(body != null) {
contentLength = body.getBytes().length;
}
// Workarounds for older Android versions who do not do that automatically (2.3.5 for example)
connection.setRequestProperty(HTTP.TARGET_HOST, url.getHost());
connection.setRequestProperty("Content-Type", "application/x-www-form-urlencoded");
// Set SSL Context -- Development only
if(context != null && connection instanceof HttpsURLConnection){
HttpsURLConnection conn = (HttpsURLConnection)connection;
conn.setSSLSocketFactory(context.getSocketFactory());
conn.setHostnameVerifier(new HostnameVerifier() {
@Override
public boolean verify(String hostname, SSLSession session) {
return true;
}
});
}
try{
// Add headers
if(headers != null){
for (NameValuePair nvp : headers) {
if(nvp != null){
connection.setRequestProperty(nvp.getName(), nvp.getValue());
}
}
}
connection.setFixedLengthStreamingMode(contentLength);
OutputStream outputStream = null;
try {
if(body != null){
outputStream = connection.getOutputStream();
BufferedOutputStream stream = new BufferedOutputStream(outputStream);
stream.write(body.getBytes()); // <<<< No effect ?!
stream.flush();
}
} finally {
if (outputStream != null)
try {
outputStream.close();
}
catch (IOException logOrIgnore) {
// ...
}
}
InputStream inputStream = connection.getInputStream();
// .... Normal case ....
}
catch(IOException e){
// ... Exception! Check Error stream and the response code ...
}
finally{
connection.disconnect();
}
}
答案 0 :(得分:6)
对我而言,您调用DoSetOutput
等的顺序似乎是奇怪行为的原因......
一些链接/来源与Android上的HTTP POST工作代码:
答案 1 :(得分:4)
我上面的代码实际上工作正常 - 原因是我包含了一个Base64编码的头。在我的Android 2.3.5上,指定的选项(Base64.DEFAULT
)似乎在末尾插入了一个额外的换行符,它过早地结束了请求,让我没有时间发送实际的正文。
在Android 4上,默认似乎更改为BASE64.NO_WRAP,如下面链接的帖子中所述......
实际上已经回答了here。
感谢您的努力。