AsyncTask HttpUrlConnection 在 getOutputStream() 上抛出 IOException
AsyncTask HttpsUrlConnection throw IOException on getOutputStream()
我尝试使用包含 json 数据(用户名和密码)的 POST 请求登录 Web 服务器 REST API。问题是当我调用 urlConnection.getOutputStream() 时抛出一个 IOException。
我试图在 [=26] 之前调用 urlConnection.setDoOutput(true) 和 urlConnection.setDoInput(true) =]urlConnection.getOutputStream() 但直到出现同样的错误。但是当我尝试使用 GET 方法从像 google.com 这样的网站读取数据时,没有任何错误。
一种可能是使用 HttpClient,但此库已弃用。
e.printStackTrace() 什么都不打印。
Web 服务器的证书是自签名的。
为了执行此操作,我使用 AsyncTask。
Android 版本 4.1.2
Android 工作室 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
。
之后,我写了一个 class 来接受所有主机名,见 java.io.IOException: Hostname was not verified,并将其设置为默认主机名验证器:
HttpsURLConnection.setDefaultHostnameVerifier(new IPSHostnameVerrifier())
成功了。
另一个错误是 json 字符串必须使用 " 而不是 ' :
String logginRequest = "{\"login\" : \"" + login + "\", \"password\" : \"" + password + "\"}";
我尝试使用包含 json 数据(用户名和密码)的 POST 请求登录 Web 服务器 REST API。问题是当我调用 urlConnection.getOutputStream() 时抛出一个 IOException。
我试图在 [=26] 之前调用 urlConnection.setDoOutput(true) 和 urlConnection.setDoInput(true) =]urlConnection.getOutputStream() 但直到出现同样的错误。但是当我尝试使用 GET 方法从像 google.com 这样的网站读取数据时,没有任何错误。
一种可能是使用 HttpClient,但此库已弃用。
e.printStackTrace() 什么都不打印。
Web 服务器的证书是自签名的。 为了执行此操作,我使用 AsyncTask。 Android 版本 4.1.2 Android 工作室 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
。
之后,我写了一个 class 来接受所有主机名,见 java.io.IOException: Hostname was not verified,并将其设置为默认主机名验证器:
HttpsURLConnection.setDefaultHostnameVerifier(new IPSHostnameVerrifier())
成功了。
另一个错误是 json 字符串必须使用 " 而不是 ' :
String logginRequest = "{\"login\" : \"" + login + "\", \"password\" : \"" + password + "\"}";