Java AsyncTask HttpsUrlConnection在getOutputStream()上引发IOException

Java AsyncTask HttpsUrlConnection在getOutputStream()上引发IOException,java,android,http,io,httpurlconnection,Java,Android,Http,Io,Httpurlconnection,我尝试使用包含json数据(用户名和密码)的POST请求登录web服务器RESTAPI。问题是,当我调用urlConnection.getOutputStream()时,会抛出一个IOException 我尝试在urlConnection.getOutputStream()之前调用urlConnection.setDoOutput(true)和urlConnection.setDoInput(true),但直到出现相同的错误。但当我尝试使用GET方法从google.com这样的网站读取数据时,并

我尝试使用包含json数据(用户名和密码)的POST请求登录web服务器RESTAPI。问题是,当我调用urlConnection.getOutputStream()时,会抛出一个IOException

我尝试在urlConnection.getOutputStream()之前调用urlConnection.setDoOutput(true)和urlConnection.setDoInput(true),但直到出现相同的错误。但当我尝试使用GET方法从google.com这样的网站读取数据时,并没有出现错误

一种可能是使用HttpClient,但此库已被弃用

e、 printStackTrace()不打印任何内容

web服务器的证书是自签名的。 要执行此操作,我使用AsyncTask。 安卓版本4.1.2 Android studio 1.3 RC3 明斯克版本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'未验证

之后,我编写了一个类来接受所有主机名,请参阅,并将其设置为默认主机名验证器:
HttpsURLConnection.setDefaultHostnameVerifier(新的IPSHostnameVerrifier())
并且它工作正常

另一个错误是json字符串必须使用“而不是”:

String logginRequest = "{\"login\" : \"" + login + "\", \"password\" : \"" + password + "\"}";

哪个IOException?使用e.getMessage()。更改为Log.e(“集中器导出”,“IOException:+e.getMessage());在每个catch块中放置这样的日志语句。不要在catch之后继续执行代码,而是返回。您可以在中看到我对sslsocketfactory&hostnameverifier的回答