简体   繁体   中英

AsyncTask HttpsUrlConnection throw IOException on getOutputStream()

I try to log into a web server REST API with a POST request that contains json data(username and password). The problem is that when I call urlConnection.getOutputStream() an IOException is throw.

I tryed to call urlConnection.setDoOutput(true) and urlConnection.setDoInput(true) befor urlConnection.getOutputStream() but till the same error. But when I try to read data with the GET Method from a website like google.com there are no errors.

One possibility is to use HttpClient but this library is deprecated.

e.printStackTrace() prints nothing.

The web server's certificate is self-signed. To perform this operation I use AsyncTask. Android version 4.1.2 Android studio 1.3 RC3 minSdkVersion 11 targetSdkVersion 23

Is it because of the self-signed certificate ? Can someone help me please ?

@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();
    }
}

Application permissions :

<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" />

I found the answer. The error message displayed by Log.e("ConcentratorExport", e.getMessage()) was Hostname '160.98.21.182' was not verified .

After that, I wrote a class to accept all hostnames, see java.io.IOException: Hostname was not verified , and set it as the default hostname verifier : HttpsURLConnection.setDefaultHostnameVerifier(new IPSHostnameVerrifier()) and the it worked.

Another error was that " must be used instead of ' for the json string :

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

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM