Java 带有POST数据的Android HttpsUrlConnection在姜饼上不起作用
我已经编写了从外部服务器下载一些数据的代码。服务器正在使用自签名证书,需要设置会话cookie和一些POST数据。目前我有以下代码:Java 带有POST数据的Android HttpsUrlConnection在姜饼上不起作用,java,android,https,httpsurlconnection,Java,Android,Https,Httpsurlconnection,我已经编写了从外部服务器下载一些数据的代码。服务器正在使用自签名证书,需要设置会话cookie和一些POST数据。目前我有以下代码: private byte[] getResponse(URL url, String postData) throws IOException, KeyManagementException, CertificateException, KeyStoreException, NoSuchAlgorithmException { Byte
private byte[] getResponse(URL url, String postData)
throws IOException, KeyManagementException, CertificateException, KeyStoreException,
NoSuchAlgorithmException
{
ByteArrayOutputStream baos = new ByteArrayOutputStream();
byte[] buffer = new byte[1024];
HttpsURLConnection urlConnection = (HttpsURLConnection) url.openConnection();
urlConnection.setRequestProperty("User-Agent", userAgent);
urlConnection.setRequestProperty("Cookie", cookie);
urlConnection.setRequestMethod("POST");
urlConnection.setDoInput(true);
urlConnection.setDoOutput(true);
urlConnection.setSSLSocketFactory(getSocketFactory());
OutputStream os = urlConnection.getOutputStream();
BufferedWriter writer = new BufferedWriter(
new OutputStreamWriter(os, "UTF-8"));
writer.write(postData);
writer.flush();
writer.close();
os.close();
try {
urlConnection.connect();
InputStream is = urlConnection.getInputStream();
int len = 0;
while ((len = is.read(buffer)) != -1)
{
baos.write(buffer, 0, len);
}
}
catch(IOException e)
{
throw e;
}
finally {
urlConnection.disconnect();
}
return baos.toByteArray();
}
在冰激凌三明治和更高的(API>=14)上,一切正常。当我试图使应用程序在API>=8上工作时,问题就开始了。它现在正确地发送带有GET和no-params(CAPTCHA)的请求,但是当涉及到获取实际数据时,urlConnection的connect方法毫无例外地失败。getSocketFactory()的代码是:
编辑:我刚刚意识到connect方法显然是有效的,但它没有遵循响应的重定向,所以输入流总是空的。我自己刚刚找到了它。由于某种原因,HttpsUrlConnection似乎并不遵循API 10及更低版本上的重定向,即使隐式调用setInstanceFlowRedirects(true)。它只是忽略了这个设置。在调用urlConnection.connect()之后,我用这段代码解决了这个问题:
private SSLSocketFactory getSocketFactory()
throws CertificateException, IOException, KeyStoreException, NoSuchAlgorithmException,
KeyManagementException
{
CertificateFactory cf = CertificateFactory.getInstance("X.509");
InputStream caInput = context.getResources().openRawResource(R.raw.historiapojazdu);
Certificate ca;
try {
ca = cf.generateCertificate(caInput);
} finally {
caInput.close();
}
// Create a KeyStore containing our trusted CAs
String keyStoreType = KeyStore.getDefaultType();
KeyStore keyStore = KeyStore.getInstance(keyStoreType);
keyStore.load(null, null);
keyStore.setCertificateEntry("ca", ca);
// Create a TrustManager that trusts the CAs in our KeyStore
String tmfAlgorithm = TrustManagerFactory.getDefaultAlgorithm();
TrustManagerFactory tmf = TrustManagerFactory.getInstance(tmfAlgorithm);
tmf.init(keyStore);
// Create an SSLContext that uses our TrustManager
SSLContext context = SSLContext.getInstance("TLS");
context.init(null, tmf.getTrustManagers(), null);
return context.getSocketFactory();
}
String redirect = urlConnection.getHeaderField("Location");
if(redirect != null) //truth before ICS
{
urlConnection.disconnect();
urlConnection = (HttpsURLConnection) (new URL(redirect)).openConnection();
urlConnection.setRequestProperty("User-Agent", userAgent);
urlConnection.setRequestProperty("Cookie", cookie);
urlConnection.setRequestMethod("POST");
urlConnection.setDoInput(true);
urlConnection.setDoOutput(true);
urlConnection.setSSLSocketFactory(getSocketFactory());
OutputStream os2 = urlConnection.getOutputStream();
BufferedWriter writer2 = new BufferedWriter(
new OutputStreamWriter(os2, "UTF-8"));
writer2.write(postData);
writer2.flush();
writer2.close();
os2.close();
urlConnection.connect();
}