使用自定義證書並忽略驗證的HTTPS連接Post請求方式的封裝

使用自定義證書並忽略驗證的HTTPS連接Post請求方式的封裝

  • 使用自定義證書並忽略驗證的HTTPS連接方式

  • 解決證書不被系統承認的方法,就是跳過系統校驗。要跳過系統校驗,就不能再使用系統標準的SSL SocketFactory了,需要自定義一個。

  • 然後爲了在這個自定義SSL SocketFactory裏跳過校驗,還需要自定義一個TrustManager,在其中忽略所有校驗,即TrustAll。

HttpClientInstance:

  public class HttpClientInstance {

  private static HttpClient mHttpClient = null;

  public static synchronized HttpClient getHttpsClientIns() {


    if (mHttpClient == null) {
        try {

            KeyStore trustStore = KeyStore.getInstance(KeyStore
                    .getDefaultType());
            trustStore.load(null, null);

            SSLSocketFactory sf = new SSLSocketFactoryImp(trustStore);

            sf.setHostnameVerifier(SSLSocketFactory.ALLOW_ALL_HOSTNAME_VERIFIER);

            HttpParams httpParameters = new BasicHttpParams();

            HttpConnectionParams
                    .setConnectionTimeout(httpParameters, 20000);

            HttpConnectionParams.setSoTimeout(httpParameters, 20000);

            HttpProtocolParams.setVersion(httpParameters,
                    HttpVersion.HTTP_1_1);
            HttpProtocolParams
                    .setContentCharset(httpParameters, HTTP.UTF_8);

            SchemeRegistry registry = new SchemeRegistry();
            registry.register(new Scheme("http", PlainSocketFactory
                    .getSocketFactory(), 80));
            registry.register(new Scheme("https", sf, 443));

            ClientConnectionManager ccm = new ThreadSafeClientConnManager(
                    httpParameters, registry);

            mHttpClient = new DefaultHttpClient(ccm, httpParameters);

            return mHttpClient;

        } catch (Exception e) {

            e.printStackTrace();
        }
    }

    return mHttpClient;
}

public static class SSLSocketFactoryImp extends SSLSocketFactory {

    final SSLContext sslContext = SSLContext.getInstance("TLS");

    public SSLSocketFactoryImp(KeyStore truststore)
            throws NoSuchAlgorithmException, KeyManagementException,
            KeyStoreException, UnrecoverableKeyException {
        super(truststore);

        TrustManager tm = new X509TrustManager() {
            public java.security.cert.X509Certificate[] getAcceptedIssuers() {
                return null;
            }

            @Override
            public void checkClientTrusted(
                    java.security.cert.X509Certificate[] chain,
                    String authType)
                    throws java.security.cert.CertificateException {

            }

            @Override
            public void checkServerTrusted(
                    java.security.cert.X509Certificate[] chain,
                    String authType)
                    throws java.security.cert.CertificateException {

            }
        };
        sslContext.init(null, new TrustManager[] { tm }, null);
    }

    @Override
    public Socket createSocket(Socket socket, String host, int port,
            boolean autoClose) throws IOException, UnknownHostException {
        return sslContext.getSocketFactory().createSocket(socket, host,
                port, autoClose);
    }

    @Override
    public Socket createSocket() throws IOException {

        return sslContext.getSocketFactory().createSocket();
    }
}

}

HttpRequestDispatch:

這個類作爲網絡連接的封裝類,繼承Thread,構造函數有5個參數,分別爲所在類,Handler,URL,post請求參數,以及handler的索引值。

public class HttpRequestDispatch extends Thread 
{
  private BaseAction mAction = null;
  private Handler mHandler = null;
  private String mUrl = null;
  private List<NameValuePair> mParams = null;
  private int mHandlerIndex = 0;


  public HttpRequestDispatch(BaseAction action,Handler   handler,String url,List<NameValuePair> params,int handlerIndex)
   {
    mAction = action;
    mHandler = handler;
    mUrl = url;
    mParams = params;
    mHandlerIndex = handlerIndex;
}

  public void run()
  {
    try
    {
        if(mUrl == null || mHandler == null)
        {
            mAction.alertToast("請求地址不能爲空");
            return;
        }

        HttpClient httpsClient = HttpClientInstance.getHttpsClientIns();
        HttpPost httpRequest = new HttpPost(mUrl);
        if(mParams != null)
        {
            httpRequest.setEntity(new UrlEncodedFormEntity(mParams,HTTP.UTF_8));
        }
        HttpResponse response = httpsClient.execute(httpRequest);
        if(response.getStatusLine().getStatusCode() != HttpURLConnection.HTTP_OK)
        {
            throw new Exception("ResponseCode:" + response.getStatusLine().getStatusCode());
        }

        BufferedReader reader = new BufferedReader(new InputStreamReader(response.getEntity().getContent()));
        StringBuffer buffer = new StringBuffer();
        String line = null;
        while ((line = reader.readLine()) != null) 
        {
            buffer.append(line);
        }

        sendResultBack(buffer.toString());
    }
    catch(Exception e)
    {
        Message message = mHandler.obtainMessage();
        message.what = HttpTool.HTTP_DISPATH_ERROR;
        message.obj = e.getMessage();
        mHandler.sendMessage(message);

        e.printStackTrace();
    }
}

private void sendResultBack(String result)
{
    Message message = mHandler.obtainMessage();
    message.what = mHandlerIndex;
    message.obj = result;
    mHandler.sendMessage(message);
}

}

這樣所有的後臺交互的封裝已經差不多了,也可以根據以上修改下,因爲不只是使用自定義證書忽略,也可是系統,也可以驗證自定義證書,依情況而定。

接下來看下如何調用的,只需要在交互的方法中去New一個HttpRequestDispatch,拿登陸來說,

LoginAction:

private void processUserLogin(String phone, String pass, String code) {



    List<NameValuePair> params = new ArrayList<NameValuePair>();

    JSONObject json = new JSONObject();
    try {
        json.put("username", phone);
        json.put("password",pass);
    } catch (JSONException e) {

        e.printStackTrace();
    }

    params.add(new BasicNameValuePair("message", MyUtils
            .encodeBase64String(json.toString())));

    new HttpRequestDispatch(LoginAction.this, mHandler,
            HttpUrl.getLoginUrl(), params, STATE_LOGIN_INFO).start();
}

雖然說現在不少網絡交互的框架應有盡有,Volly,Okhttp,再到現在的Retrofit+RxJava等,但並不能代表源生的有多麼差,看個人愛好吧。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章