使用自定义证书并忽略验证的HTTPS连接Post请求方式的封装

来源:互联网 发布:东非解放军 知乎 编辑:程序博客网 时间:2024/04/21 00:07

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

1 0
原创粉丝点击