• android 网络编程之HttpURLConnection与HttpClient使用与封装


    博客逐步迁移至 极客兔兔的小站

    1.写在前面

        大部分andriod应用需要与服务器进行数据交互,HTTP、FTP、SMTP或者是直接基于SOCKET编程都可以进行数据交互,但是HTTP必然是使用最广泛的协议。
        本文并不针对HTTP协议的具体内容,仅探讨android开发中使用HTTP协议访问网络的两种方式——HttpURLConnectionHttpClient
        因为需要访问网络,需在AndroidManifest.xml中添加如下权限

    <uses-permission android:name="android.permission.INTERNET" />  
    

    2.HttpURLConnection

    2.1 GET方式

    import java.io.BufferedReader;
    import java.io.InputStream;
    import java.io.InputStreamReader;
    import java.net.HttpURLConnection;
    import java.net.URL;
    
    // 以下代码实现了以GET方式发起HTTP请求
    // 连接网络是耗时操作,一般新建线程进行
    
    private void connectWithHttpURLConnection() {
        new Thread( new Runnable() {
            @Override
            public void run() {
                HttpURLConnection connection = null;
                try {
                    // 调用URL对象的openConnection方法获取HttpURLConnection的实例
                    URL url = new URL("http://www.cnblogs.com/gzdaijie");
                    connection = (HttpURLConnection) url.openConnection();
                    // 设置请求方式,GET或POST
                    connection.setRequestMethod("GET");
                    // 设置连接超时、读取超时的时间,单位为毫秒(ms)
                    connection.setConnectTimeout(8000);
                    connection.setReadTimeout(8000);
                    // getInputStream方法获取服务器返回的输入流
                    InputStream in = connection.getInputStream();
                    // 使用BufferedReader对象读取返回的数据流
                    // 按行读取,存储在StringBuider对象response中
                    BufferedReader reader = new BufferedReader(new InputStreamReader(in));
                    StringBuilder response = new StringBuilder();
                    String line;
                    while ((line = reader.readLine()) != null) {
                        response.append(line);
                    }
                    //..........
                    // 此处省略处理数据的代码
                    // 若需要更新UI,需将数据传回主线程,具体可搜索android多线程编程
                } catch (Exception e){
                    e.printStackTrace();
                } finally {
                    if (connection != null){
                        // 结束后,关闭连接
                        connection.disconnect();
                    }
                }
            }
        }).start();
    }
    

    2.2 POST方式

    import java.io.DataOutputStream;
    
    //将对应部分改为
    connection.setRequestMethod("POST");
    DataOutputStream data = new DataOutputStream(connection.getOutputStream());
    data.writeBytes("stu_no=12345&stu_name=Tom");
    
    • 传入多个参数用 & 隔开
    • 如需传入复杂的参数,可使用JSON,关于JSON的用法介绍,可以参考我的另一篇随笔JSON解析的两种方法

    3.HttpClient

    3.1 GET方式

    import org.apache.http.client.HttpClient;
    import org.apache.http.client.methods.HttpGet;
    import org.apache.http.impl.client.DefaultHttpClient;
    import org.apache.http.HttpResponse;
    import org.apache.http.HttpEntity;
    import org.apache.http.HttpStatus;
    
    // 创建DefaultHttpClient实例
    HttpClient httpClient = new DefaultHttpClient();      
    //传入网址,然后执行
    HttpGet httpGet = new HttpGet("http://www.cnblogs.com/gzdaijie");
    HttpResponse httpResponse = httpClient.execute(httpGet); 
    // 由状态码判断请求结果,
    // 常见状态码 200 请求成功,404 页面未找到
    // 关于HTTP的更多状态码直接GOOGLE
    if (httpResponse.getStatusLine().getStatusCode() == HttpStatus.SC_OK) {       
        // 请求成功,使用HttpEntity获得返回数据
        // 使用EntityUtils将返回数据转换为字符串
        HttpEntity entity = httpResponse.getEntity(); 
        String response = EntityUtils.toString(entity);
        //如果是中文,指定编码 
        //==>String response = EntityUtils.toString(entity, "utf-8"); 
    }
    

    3.2 POST方式

    import org.apache.http.client.HttpClient;
    import org.apache.http.client.methods.HttpPost;
    import org.apache.http.HttpResponse;
    import org.apache.http.NameValuePair;
    import org.apache.http.client.entity.UrlEncodedFormEntity;
    import org.apache.http.message.BasicNameValuePair;
    
    HttpClient httpClient = new DefaultHttpClient();
    HttpPost httpPost("http://www.cnblogs.com/gzdaijie");  
    // 使用NameValuePair(键值对)存放参数
    List<NameValuePair> data = new ArrayList<NameValuePair>();
    // 添加键值对
    data.add(new BasicNameValuePair("stu_no", 12345));
    data.add(new BasicNameValuePair("stu_name", "Tom"));
    // 使用setEntity方法传入编码后的参数
    httpPost.setEntity(new UrlEncodedFormEntity(data, "utf-8")); 
    // 执行该POST请求
    HttpResponse httpResponse = httpClient.execute(httpPost);
    // .....省略处理httpResponse的代码,与GET方式一致 
    

    3.3 android 6.0移除HttpClient

    • android 6.0(API 23)版本的SDK已将Apache HttpClient相关类移除,解决办法自行GOOGLE,推荐使用HTTPURLConnection。
    • 若还需使用该类,点击查看解决办法

    4.HttpURLConnection实战

        如果你使用过JQuery(一个javasript库),你一定对JQuery的网路编程印象深刻,比如一个HTTP请求只需以下几行代码。

    // JQuery的post方法
    $.post("http://www.cnblogs.com/gzdaijie",{
            "stu_no":12345,
            "stu_name":"Tom",
        }).done(function(){
            //...请求成功的代码
        }).fail(function(){
            //...请求失败的代码
        }).always(function(){
            //...总会执行的代码
        })
    

        我们当然不希望每次网络请求都写下2.1中那么繁琐的代码,那么android的HTTP请求能否像JQuery那么简单呢?当然可以!下面的代码实现了HttpURLConnection的HTTP请求方法封装

    4.1 定义接口HttpCallbackListener,为了实现回调

    // 定义HttpCallbackListener接口
    // 包含两个方法,成功和失败的回调函数定义
    public interface HttpCallbackListener {
        void onFinish(String response);
        void onError(Exception e);
    }
    

    4.2 创建HttpTool类,抽象请求方法(GET)

    import java.io.BufferedReader;
    import java.io.InputStream;
    import java.io.InputStreamReader;
    import java.net.HttpURLConnection;
    import java.net.URL;
    
    /* 创建一个新的类 HttpTool,将公共的操作抽象出来
     * 为了避免调用sendRequest方法时需实例化,设置为静态方法
     * 传入HttpCallbackListener对象为了方法回调
     * 因为网络请求比较耗时,一般在子线程中进行,
     * 为了获得服务器返回的数据,需要使用java的回调机制 */
     
    public class HttpTool {
        public static void sendRequest(final String address, 
                final HttpCallbackListener listener) {
            new Thread(new Runnable() {
                @Override
                public void run() {
                    HttpURLConnection connection = null;
    
                    try {
                        URL url = new URL(address);
                        connection = (HttpURLConnection) url.openConnection();
                        connection.setRequestMethod("GET");
                        connection.setConnectTimeout(8000);
                        connection.setReadTimeout(8000);
                        InputStream in = connection.getInputStream();
                        BufferedReader reader = new BufferedReader(new InputStreamReader(in));
                        StringBuilder response = new StringBuilder();      String line;
                        while ((line = reader.readLine()) != null) {
                            response.append(line);
                        }
                        if (listener != null) {
                            // 回调方法 onFinish()
                            listener.onFinish(response.toString());
                        }
                    } catch (Exception e) {
                        if (listener != null) {
                            // 回调方法 onError()
                            listener.onError(e);
                        }
                    } finally {
                        if (connection != null) {
                            connection.disconnect();
                        }
                    }
                }
            }).start();
        }
    }  
    

    4.3 调用示例

    //使用该HttpTool发起GET请求
    String url = "http://www.cnblogs.com/gzdaijie";
    HttpTool.sendRequest(url,new HttpCallbackListener(){
        @Override  
        public void onFinish(String response) {
            // ...省略对返回结果的处理代码  
        }  
        
        @Override  
        public void onError(Exception e) {   
            // ...省略请求失败的处理代码
        } 
    });
    

    4.4 抽象请求方法(POST)

    /* 在GET方法实现的基础上增加一个参数params即可,
     * 将参数转换为字符串后传入
     * 也可以传入键值对集合,再处理 */
    public static void sendRequest(final String address,
        final String params, final HttpCallbackListener listener){
            //...
    }
    
  • 相关阅读:
    程序员职业路线图
    程序员职业路线图
    高级程序员和低级程序员的区别
    高级程序员和低级程序员的区别
    高级程序员和低级程序员的区别
    使用fastai完成图像分类
    hibernate JPA
    mongodb增删改查
    【树莓派从入门到入土】1.什么是树莓派?
    输入一个url之后到底发生了什么
  • 原文地址:https://www.cnblogs.com/gzdaijie/p/5191617.html
Copyright © 2020-2023  润新知