【封装】异步HttpURLConnection网络访问

版权声明:本文为博主项目中经验总结,著文备份,欢迎补充交流! https://blog.csdn.net/u013806583/article/details/69916214

知识扩展:

【面相对象】静态代码块、构造代码块和构造函数的执行顺序

http://blog.csdn.net/u013806583/article/details/69934058


【封装】使用okHttp进行网络请求及上传下载进度监听

http://blog.csdn.net/u013806583/article/details/69944279


主体:

import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.HttpURLConnection;
import java.net.SocketTimeoutException;
import java.net.URL;
import java.security.KeyManagementException;
import java.security.NoSuchAlgorithmException;
import java.security.cert.X509Certificate;
import java.util.Scanner;

import javax.net.ssl.HostnameVerifier;
import javax.net.ssl.HttpsURLConnection;
import javax.net.ssl.SSLContext;
import javax.net.ssl.SSLSession;
import javax.net.ssl.TrustManager;
import javax.net.ssl.X509TrustManager;

/**
 * Asynchronous http requests implementation.
 */
public class AsyncHttpURLConnection {
    private static final int HTTP_TIMEOUT_MS = 8000;
    private static final String HTTP_ORIGIN = AppRTC_Common.HTTP_ORIGIN;
    private final String method;
    private final String url;
    private final String message;
    private final AsyncHttpEvents events;
    private String contentType;


    private String TAG = "AsyncHttp";

    /**
     * 定义回调的接口
     * Http requests callbacks.
     */
    public interface AsyncHttpEvents {
        void onHttpError(String errorMessage);

        void onHttpComplete(String response);
    }

    //静态代码块。
    //重要:关于静态代码块的执行顺序问题,请关注本博文开头的相关链接。
    static {
        //忽略安全证书的问题,即https
        disableSslVerification();
    }


    /**
     * 构造函数
     *
     * @param method
     * @param url
     * @param message
     * @param events
     */
    public AsyncHttpURLConnection(String method, String url, String message, AsyncHttpEvents events) {
        this.method = method;
        this.url = url;
        this.message = message;
        this.events = events;
    }

    public void setContentType(String contentType) {
        this.contentType = contentType;
    }

    public void send() {
        Runnable runHttp = new Runnable() {
            public void run() {
                sendHttpMessage();
            }
        };
        new Thread(runHttp).start();
    }

    private void sendHttpMessage() {
        try {
            HttpURLConnection connection; //= (HttpURLConnection) new URL(url).openConnection();

            URL Url = new URL(url);


            connection = (HttpURLConnection) Url.openConnection();


            byte[] postData = new byte[0];
            if (message != null) {
                postData = message.getBytes("UTF-8");
            }
            connection.setRequestMethod(method);
            connection.setUseCaches(false);
            connection.setDoInput(true);
            connection.setConnectTimeout(HTTP_TIMEOUT_MS);
            connection.setReadTimeout(HTTP_TIMEOUT_MS);
            // TODO(glaznev) - query request origin from pref_room_server_url_key preferences.
            connection.addRequestProperty("origin", HTTP_ORIGIN);
            /**
             * 为了防止CSRF的攻击,我们建议修改浏览器在发送POST请求的时候加上一个Origin字段.
             * 这个Origin字段主要是用来标识出最初请求是从哪里发起的。
             * 如果浏览器不能确定源在哪里,那么在发送的请求里面Origin字段的值就为空。
             */

            boolean doOutput = false;
            if (method.equals("POST")) {
                doOutput = true;
                connection.setDoOutput(true);
                connection.setFixedLengthStreamingMode(postData.length);
            }
            if (contentType == null) {
                connection.setRequestProperty("Content-Type", "text/plain; charset=utf-8");
            } else {
                connection.setRequestProperty("Content-Type", contentType);
            }

            // Send POST request.
            if (doOutput && postData.length > 0) {
                OutputStream outStream = connection.getOutputStream();
                outStream.write(postData);
                outStream.close();
            }

            // Get response.
            int responseCode = connection.getResponseCode();
            //Log.e(TAG, "responseCode:" + responseCode);

            if (responseCode != 200) {
                events.onHttpError("Non-200 response to " + method + " to URL: " + url + " : "
                        + connection.getHeaderField(null));
                connection.disconnect();
                return;
            }

            InputStream responseStream = connection.getInputStream();
            String response = drainStream(responseStream);
            responseStream.close();
            connection.disconnect();
            events.onHttpComplete(response);
        } catch (SocketTimeoutException e) {
            events.onHttpError("HTTP " + method + " to " + url + " timeout");
        } catch (IOException e) {
            events.onHttpError("HTTP " + method + " to " + url + " error: " + e.getMessage());
        }
    }

    // Return the contents of an InputStream as a String.
    private static String drainStream(InputStream in) {
        Scanner s = new Scanner(in).useDelimiter("\\A");
        return s.hasNext() ? s.next() : "";
    }


    /**
     * 忽略安全证书
     */
    private static void disableSslVerification() {
        try {
            // Create a trust manager that does not validate certificate chains
            TrustManager[] trustAllCerts = new TrustManager[]{new X509TrustManager() {
                public X509Certificate[] getAcceptedIssuers() {
                    return null;
                }

                public void checkClientTrusted(X509Certificate[] certs, String authType) {
                }

                public void checkServerTrusted(X509Certificate[] certs, String authType) {
                }
            }
            };

            // Install the all-trusting trust manager
            SSLContext sc = SSLContext.getInstance("SSL");
            sc.init(null, trustAllCerts, new java.security.SecureRandom());
            HttpsURLConnection.setDefaultSSLSocketFactory(sc.getSocketFactory());

            // Create all-trusting host name verifier
            HostnameVerifier allHostsValid = new HostnameVerifier() {
                public boolean verify(String hostname, SSLSession session) {
                    return true;
                }
            };

            // Install the all-trusting host verifier
            HttpsURLConnection.setDefaultHostnameVerifier(allHostsValid);
        } catch (NoSuchAlgorithmException e) {
            e.printStackTrace();
        } catch (KeyManagementException e) {
            e.printStackTrace();
        }
    }
}

使用

  • 发送POST请求
        //POST请求中,表单的具体内容
        JSONObject json = new JSONObject();
        jsonPut(json, "type", "text");
        jsonPut(json, "content", "balabala");
        jsonPut(json, "id", "123");


        String method="POST";
        String myUrl="www.balabalabala.com/query";

        AsyncHttpURLConnection httpURLConnection = new AsyncHttpURLConnection(method, 
                myUrl,
                json.toString(),
                new AsyncHttpURLConnection.AsyncHttpEvents() {
                    @Override
                    public void onHttpError(String errorMessage) {
                        //Log.e(TAG, "网络连接失败:" + errorMessage);
                        //System.out.println("网络连接失败:" + errorMessage);
                    }

                    @Override
                    public void onHttpComplete(String response) {
                        //Log.e(TAG,"网络连接成功:"+response);
                        //System.out.println("网络连接成功:"+response);
                    }
                });
        httpURLConnection.send();

辅助作用的类

    // Put a |key|->|value| mapping in |json|.
    public static void jsonPut(JSONObject json, String key, Object value) {
        try {
            json.put(key, value);
        } catch (JSONException e) {
            throw new RuntimeException(e);
        }
    }

抓住Demo一只:

为了方便以后调用,本人已经将上述方法封装到了.aar文件中。以后调用时,只需要导入第三方包即可。

https://github.com/shanxu100/GUtils

欢迎大家补充交流。

猜你喜欢

转载自blog.csdn.net/u013806583/article/details/69916214