如何在android中调用Https Rest服务

时间:2015-11-12 13:27:16

标签: android web-services rest ssl https

我正在尝试调用应返回Json的Https服务。但是,我无法正确设置连接。我使用了本主题“正确”答案中的代码:How to call https web service in Android

这是我的代码exaclty:

MainActivity.java

import android.content.Context;
import android.os.Bundle;
import android.support.design.widget.FloatingActionButton;
import android.support.design.widget.Snackbar;
import android.support.v7.app.AppCompatActivity; 
import android.support.v7.widget.Toolbar;
import android.view.View;
import android.view.Menu;
import android.view.MenuItem;
import android.widget.EditText;
import android.widget.TextView;

import org.apache.http.HttpResponse;
import org.apache.http.client.HttpClient;
import org.apache.http.client.methods.HttpGet;

import java.io.BufferedReader;
import java.io.IOException;

public class MainActivity extends AppCompatActivity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        Context con = getApplicationContext();
        Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);
        setSupportActionBar(toolbar);

        FloatingActionButton fab = (FloatingActionButton) findViewById(R.id.fab);
        fab.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                Snackbar.make(view, "Replace with your own action", Snackbar.LENGTH_LONG)
                    .setAction("Action", null).show();
            }
        });
        TextView t = (TextView) findViewById(R.id.textView1);
        HttpGet httpGet = new HttpGet("https://...");
        HttpClient httpClient = new NetworkUtility().getDefaultHttpClient(con, "https://...);
        try {
            HttpResponse response = httpClient.execute(httpGet);   //line 44
            if(response!=null) t.setText("1");
        } catch (IOException e) {
            t.setText("IO Exception");
        }
    }


    public void apiCall(View v) {
        EditText ed = (EditText) findViewById(R.id.editText1);
        TextView t = (TextView) findViewById(R.id.textView1);
        String username = ed.getText().toString();
        BufferedReader reader = null;
    }

        @Override
        public boolean onCreateOptionsMenu(Menu menu) {
        getMenuInflater().inflate(R.menu.menu_main, menu);
        return true;
    }

    @Override
    public boolean onOptionsItemSelected(MenuItem item) {
        // Handle action bar item clicks here. The action bar will
        // automatically handle clicks on the Home/Up button, so long
        // as you specify a parent activity in AndroidManifest.xml.
        int id = item.getItemId();

        if (id == R.id.action_settings) {
            return true;
        }

        return super.onOptionsItemSelected(item);
    }
}

NetworkUtility.java

import java.io.IOException;
import java.net.Socket;
import java.security.KeyManagementException;
import java.security.KeyStore;
import java.security.KeyStoreException;
import java.security.NoSuchAlgorithmException;
import java.security.UnrecoverableKeyException;
import java.security.cert.CertificateException;
import java.security.cert.X509Certificate;
import java.util.Enumeration;

import javax.net.ssl.SSLContext;
import javax.net.ssl.TrustManager;
import javax.net.ssl.TrustManagerFactory;
import javax.net.ssl.X509TrustManager;

import org.apache.http.client.HttpClient;
import org.apache.http.conn.ClientConnectionManager;
import org.apache.http.conn.scheme.PlainSocketFactory;
import org.apache.http.conn.scheme.Scheme;
import org.apache.http.conn.scheme.SchemeRegistry;
import org.apache.http.conn.ssl.AllowAllHostnameVerifier;
import org.apache.http.conn.ssl.SSLSocketFactory;
import org.apache.http.impl.client.DefaultHttpClient;
import org.apache.http.impl.conn.tsccm.ThreadSafeClientConnManager;
import org.apache.http.params.BasicHttpParams;
import org.apache.http.params.HttpConnectionParams;
import org.apache.http.params.HttpParams;

import android.content.Context;
import android.util.Log;

public class NetworkUtility {
    protected static final String TAG = NetworkUtility.class.getSimpleName();

    private static final int HTTP_CONNECTION_TIMEOUT = 150000;

    public static HttpClient getDefaultHttpClient(Context context,
                                               String targetUrl) {
        HttpParams params = new BasicHttpParams();
        HttpConnectionParams.setConnectionTimeout(params,
            HTTP_CONNECTION_TIMEOUT);
        HttpConnectionParams.setSoTimeout(params, HTTP_CONNECTION_TIMEOUT);
        try {
            SchemeRegistry registry = new SchemeRegistry();
            registry.register(new Scheme("http", PlainSocketFactory
                .getSocketFactory(), 80));
            registry.register(new Scheme("https", new MySSLSocketFactory(
                context.getApplicationContext(), targetUrl), 443));
            ClientConnectionManager ccm = new ThreadSafeClientConnManager(
                params, registry);
            return new DefaultHttpClient(ccm, params);
        } catch (Exception e) {
            e.printStackTrace();
            return new DefaultHttpClient(params);
        }
    }

    private static class MyTrustManager implements X509TrustManager {
        private X509TrustManager mOriginalX509TrustManager;
        private Context mContext;
        private String mTargetUrl;

        public MyTrustManager(Context context, String targetUrl) {
            try {
                this.mContext = context;
                this.mTargetUrl = targetUrl;
                TrustManagerFactory originalTrustManagerFactory = TrustManagerFactory
                    .getInstance("X509");
                originalTrustManagerFactory.init((KeyStore) null);
                TrustManager[] originalTrustManagers = originalTrustManagerFactory
                    .getTrustManagers();
                this.mOriginalX509TrustManager = (X509TrustManager) originalTrustManagers[0];
            } catch (Exception e) {
                e.printStackTrace();
            }
        }

        public void checkClientTrusted(X509Certificate[] cert, String authType)
            throws CertificateException {
        }

        public void checkServerTrusted(X509Certificate[] cert, String authType)
                throws CertificateException {
            try {
                mOriginalX509TrustManager.checkServerTrusted(cert, authType);
            } catch (CertificateException originalException) {
                X509Certificate certificate = getCertificateToInstall(cert);
                Log.d(TAG, "Showing dialog for certificate exception...");
                throw originalException;
            }
        }

        public X509Certificate[] getAcceptedIssuers() {
            return null;
        }
    }

    private static X509Certificate getCertificateToInstall(
        X509Certificate[] certificates) {
        X509Certificate result = null;
        try {
            KeyStore ks = KeyStore.getInstance("AndroidCAStore");
            if (ks != null) {
                ks.load(null, null);
                boolean certFound = false;
                for (X509Certificate certificate : certificates) {
                    Enumeration<String> aliases = ks.aliases();
                    while (aliases.hasMoreElements()) {
                        String alias = (String) aliases.nextElement();
                        X509Certificate cert = (X509Certificate) ks
                            .getCertificate(alias);
                        if (certificate.equals(cert) == true) {
                            certFound = true;
                            break;
                        }
                    }
                    if (certFound == false) {
                        Log.d(TAG, "Not found certificate");
                        result = certificate;
                        break;
                    }
                }
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
        return result;
    }


    private static class MySSLSocketFactory extends SSLSocketFactory {
        private javax.net.ssl.SSLSocketFactory mFactory;

        public MySSLSocketFactory(Context context, String targetUrl)
            throws KeyManagementException, NoSuchAlgorithmException,
            KeyStoreException, UnrecoverableKeyException {
            super((KeyStore) null);
            try {
                SSLContext sslcontext = SSLContext.getInstance("TLS");
                sslcontext.init(null, new TrustManager[] { new MyTrustManager(
                    context, targetUrl) }, null);
                mFactory = sslcontext.getSocketFactory();
                setHostnameVerifier(new AllowAllHostnameVerifier());
            } catch (Exception ex) {
                ex.printStackTrace();
            }
        }

        @Override
        public Socket createSocket() throws IOException {
            return mFactory.createSocket();
        }

        @Override
        public Socket createSocket(Socket socket, String s, int i, boolean flag)
            throws IOException {
            return mFactory.createSocket(socket, s, i, flag);
        }
    }
}

我从MainActivity第44行收到此错误:

11-12 08:00:52.671 2294-2294/com.nicu.bogdan.lolstats E/AndroidRuntime: FATAL EXCEPTION: main
11-12 08:00:52.671 2294-2294/com.nicu.bogdan.lolstats E/AndroidRuntime: Process: com.nicu.bogdan.lolstats, PID: 2294
11-12 08:00:52.671 2294-2294/com.nicu.bogdan.lolstats E/AndroidRuntime: java.lang.RuntimeException: Unable to start activity ComponentInfo{com.nicu.bogdan.lolstats/com.nicu.bogdan.lolstats.MainActivity}: android.os.NetworkOnMainThreadException

非常感谢任何形式的帮助。

2 个答案:

答案 0 :(得分:2)

如异常所述(NetworkOnMainThreadException)。不要在主线程中启动http请求。相反,请使用AsyncTask:http://developer.android.com/reference/android/os/AsyncTask.html

答案 1 :(得分:0)

   //Thread policy for internet access in onCreate()
        val SDK_INT = android.os.Build.VERSION.SDK_INT
        if (SDK_INT > 8) {
            val policy = StrictMode.ThreadPolicy.Builder()
                    .permitAll().build()
            StrictMode.setThreadPolicy(policy)


        }

   button.setOnClickListener({
                tv.setText("Clicked");
                progress_bar.visibility = View.VISIBLE

    // Kotlin + HttpURLConnection

                val connection = URL("example.com").openConnection() as HttpURLConnection
                connection.connect()
                println(connection.responseCode)
                println(connection.getHeaderField("Content-Type"))
                val text = connection.inputStream.use { it.reader().use { reader -> reader.readText() } }
    <p>
    //suppose sample data from http get calls

                println(text)   //sample data output
                //setting text in txt view for demo.
                tv.setText(text)

    //optional block
    //response to pojo work . following statement may be different in your case plz do as per your data
                val gson = Gson()        //gson object
                val list1 = gson.fromJson<List<Product>>(text) 
    //convert/store response data to kotlin data class Product

    println("Saved Data "+list1.size)   //how much data saved
                val s=list1.size;   //size of collection
    //printing saved data in pojo class
                for (i in 0..s-1) {
                    //printing list from loop
                    println("Products Data : $list1.get(i).sku $list1.get(i).position $list1.get(i).category_id")

                }
    // end of optional block

                progress_bar.visibility = View.GONE;  //hide progress bar

            })   //end of button event


    //add following library in build.gradle module:app
    <p>
    compile 'com.beust:klaxon:0.30'
    compile 'com.github.salomonbrys.kotson:kotson:2.5.0'
    for more details
    http://iotwebplanet.com/learn/call-webservice-kotlin-android/
    </p>
    /*
                [
                {"sku":"00012","position":1,"category_id":"6"},
                {"sku":"00077","position":1,"category_id":"6"},
                {"sku":"00072","position":1,"category_id":"6"},
                {"sku":"00032","position":1,"category_id":"6"},
                {"sku":"00074","position":1,"category_id":"6"},
                {"sku":"00078","position":1,"category_id":"6"}
                ]

    */ </p>