![](/img/trans.png)
[英]HttpUrlConnection getOutputStream throws IOException
[英]AsyncTask HttpsUrlConnection throw IOException on getOutputStream()
我嘗試使用包含json數據(用戶名和密碼)的POST請求登錄Web服務器REST API。 問題是當我調用urlConnection.getOutputStream()時 ,拋出IOException。
我試圖在 urlConnection.getOutputStream()之前調用urlConnection.setDoOutput(true)和urlConnection.setDoInput(true ),但是直到出現相同的錯誤。 但是,當我嘗試使用GET方法從類似google.com的網站讀取數據時,沒有任何錯誤。
一種可能性是使用HttpClient,但不建議使用該庫。
e.printStackTrace()不打印任何內容。
Web服務器的證書是自簽名的。 要執行此操作,請使用AsyncTask。 Android版本4.1.2 Android Studio 1.3 RC3 minSdkVersion 11 targetSdkVersion 23
是因為有自簽名證書嗎? 有人能幫助我嗎 ?
@Override
protected Void doInBackground(Void... params) {
login();
return null;
}
private KeyStore getKeyStore() {
KeyStore trusted;
try {
trusted = KeyStore.getInstance("BKS");
InputStream in = activity.getBaseContext().getResources().openRawResource(R.raw.cert);
try {
trusted.load(in, "password".toCharArray());
} finally {
in.close();
}
} catch (Exception e) {
throw new AssertionError(e);
}
return trusted;
}
public void login() {
HttpsURLConnection urlConnection = null;
try {
//prepare request
URL url = new URL("https://" + ip + "/api/login");
urlConnection = (HttpsURLConnection) url.openConnection();
TrustManagerFactory tmf = null;
SSLContext context;
try {
tmf = TrustManagerFactory.getInstance("X509");
tmf.init(getKeyStore());
context = SSLContext.getInstance("TLS");
context.init(null, tmf.getTrustManagers(), null);
urlConnection.setSSLSocketFactory(context.getSocketFactory());
} catch (NoSuchAlgorithmException e) {
e.printStackTrace();
} catch (KeyManagementException e) {
e.printStackTrace();
}
urlConnection.setRequestMethod("POST");
urlConnection.addRequestProperty("Content-Type", "application/json");
//write request
urlConnection.setDoOutput(true);
urlConnection.setChunkedStreamingMode(0);
//error at this line
OutputStreamWriter out = new OutputStreamWriter(urlConnection.getOutputStream());
String logginRequest = "{'login' : '" + login + "', 'password' : '" + password + "'}";
out.write(logginRequest.toCharArray());
out.close()
//connect
urlConnection.connect();
//read
BufferedInputStream in = new BufferedInputStream(urlConnection.getInputStream());
printData(in);
in.close();
} catch (MalformedURLException e) {
Log.e("ConcentratorExport", "MalformedURLException");
e.printStackTrace();
} catch (IOException e) {
Log.e("ConcentratorExport", "IOException");
e.printStackTrace();
} finally {
urlConnection.disconnect();
}
}
申請權限:
<uses-permission android:name="android.permission.ACCESS_WIFI_STATE" />
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
<uses-permission android:name="android.permission.INTERNET" />
我找到了答案。 Log.e("ConcentratorExport", e.getMessage())
顯示的錯誤消息是Hostname '160.98.21.182' was not verified
。
之后,我編寫了一個類來接受所有主機名,請參見java.io.IOException:主機名未驗證 ,並將其設置為默認主機名驗證程序: HttpsURLConnection.setDefaultHostnameVerifier(new IPSHostnameVerrifier())
,它可以正常工作。
另一個錯誤是json字符串必須使用“而不是':
String logginRequest = "{\"login\" : \"" + login + "\", \"password\" : \"" + password + "\"}";
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.