使用自定义证书并忽略验证的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等,但并不能代表源生的有多么差,看个人爱好吧。

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