HttpUrlConnection和HttpClient

众所周知,Android常用的网络开发无外乎HTTP和socket,其中HTTP是应用层协议,TCP/UDP是传输层协议。本文主要来讲讲HTTP协议,其实,HTTP也是用socket封装的,用起来更方便,由于是封装过的,它提供了更强大的功能。Android的HTTP(超文本传输协议)包括两种接口:
1、标准Java接口(java.net) —-HttpURLConnection,可以实现简单的基于URL的请求、响应功能。
2、Apache接口(org.appache.http)—-HttpClient,使用起来更方面更强大。
Android SDK中包含了HttpClient,在Android6.0版本直接删除了HttpClient类库,如果仍想使用则解决方法是:在libs中加入org.apache.http.legacy.jar
这个jar包在:**sdk\platforms\android-23\optional目录中(需要下载android 6.0的SDK)

HttpURLConnection和HttpClient,这两种方式都支持HTTPS协议、以流的形式进行上传和下载、配置超时时间、IPv6、以及连接池等功能。

HttpURLConnection

HttpURLConnection是Java的标准类,继承自URLConnection,用它可以发送和接受任何类型和长度的数据,且预先不用知道数据流的长度,可以设置请求方式GET或POST、超时时间、缓存处理(4.0以上)等,HttpUrlConnection直接支持GZIP压缩。

Android 2.2版本之前,HttpURLConnection一直存在着一些令人厌烦的bug。比如说对一个可读的InputStream调用close()方法时,就有可能会导致连接池失效了。那么我们通常的解决办法就是直接禁用掉连接池的功能:

private void disableConnectionReuseIfNecessary() {
      // 这是一个2.2版本之前的bug
      if (Integer.parseInt(Build.VERSION.SDK) < Build.VERSION_CODES.FROYO) {
            System.setProperty("http.keepAlive", "false");
      }
}

所以在Android 2.2版本以及之前的版本使用HttpClient是较好的选择,而在Android 2.3版本及以后,HttpURLConnection则是最佳的选择,它的API简单,体积较小,因而非常适用于Android项目。压缩和缓存机制可以有效地减少网络访问的流量,在提升速度和省电方面也起到了较大的作用。另外在Android 6.0版本中,HttpClient库被移除了,HttpURLConnection则是以后我们唯一的选择。

    public static String requestContentWithGet(String urlStr) {
        String content = null;
        if (urlStr != null && urlStr.startsWith("http://")) {
            URL url = null;
            HttpURLConnection conn = null;
            try {
                url = new URL(urlStr);
                conn = (HttpURLConnection) url.openConnection();                 
                conn.setDoOutput(true); //设置是否向conn输出,因为这个是post请求,参数要放在http正文内,因此需要设为true, 默认情况下是false      
                conn.setDoInput(true); //设置是否从conn读入,默认情况下是true            
                conn.setUseCaches(false); //Post请求不能使用缓存                
                conn.setRequestMethod("POST"); // 设定请求的方法为"POST",默认是GET
                conn.setConnectTimeout(6*1000); //设置连接主机超时
                conn.setReadTimeout(6*1000); //设置从主机读取数据超时
                conn.setRequestProperty("Content-type", "application/x-java-serialized-object"); //设定传送的内容类型是可序列化的java对象,(如果不设此项,在传送序列化对象时,当WEB服务默认的不是这种类型时可能抛java.io.EOFException)
                conn.setRequestProperty("accept", "*/*");
                conn.setRequestProperty("Charset", "UTF-8");
                conn.connect(); //连接,所有的配置必须要在connect之前完成  
                OutputStream outStrm = conn.getOutputStream(); //此处getOutputStream会隐含的进行connect(即:如同调用上面的connect()方法,所以在开发中不调用上述的connect()也可以)。              
                ObjectOutputStream objOutputStrm = new ObjectOutputStream(outStrm); //现在通过输出流对象构建对象输出流对象,以实现输出可序列化的对象。 
                objOutputStrm.writeObject(new String("我是测试数据")); //向对象输出流写出数据,这些数据将存到内存缓冲区中  
                objOutputStm.flush(); //刷新对象输出流    
                objOutputStm.close(); //关闭流对象。此时,不能再向对象输出流写入任何数据,先前写入的数据存在于内存缓冲区中,在调用下边的getInputStream()函数时才把准备好的http请求正式发送到服务器
                int responseCode = conn.getResponseCode();
                if (responseCode == HttpURLConnection.HTTP_OK) {
                //调用conn连接对象的getInputStream()函数, 将内存缓冲区中封装好的完整的HTTP请求电文发送到服务端。
                    content = convertStream2String(conn.getInputStream()); //getInputStream()方法已调用,本次HTTP请求已结束,下边向对象输出流的输出已无意义,因此,要重新发送数据时需要重新创建连接、重新设参数、重新创建流对象、重新写数据
                } else {
                    content = "";
                }
            } catch (Exception e) {
            } finally {
                if (conn != null) {
                    conn.disconnect();
                    conn = null;
                }
            }
        }
        return content;
    }

注:
(1)URL请求的类别:

  • GET:get请求可以获取静态页面,也可以把参数放在URL字串后面,传递给servlet。
    /** 
     * 发送GET请求 
     * @param path 请求路径 
     * @param params 请求参数 
     * @param encoding 编码 
     * @return 请求是否成功 
     */ 
    private static boolean sendGETRequest(String urlStr, Map<String, String> params, String encoding) throws Exception{
        StringBuilder url = new StringBuilder(urlStr);  
        url.append("?");  
        for(Map.Entry<String, String> entry : params.entrySet()){  
            url.append(entry.getKey()).append("=");  
            url.append(URLEncoder.encode(entry.getValue(), encoding));  
            url.append("&");  
        }  
        url.deleteCharAt(url.length() - 1);  
        HttpURLConnection conn = (HttpURLConnection)new URL(url.toString()).openConnection();  
        conn.setConnectTimeout(5000);  
        conn.setRequestMethod("GET");  
        if(conn.getResponseCode() == 200){  
            return true;  
        }  
        return false;  
    } 
  • POST:post与get的不同之处在于post的参数不是放在URL字串里面,而是放在http请求的正文内。
    /** 
     * 发送Post请求 
     * @param path 请求路径 
     * @param params 请求参数 
     * @param encoding 编码 
     * @return 请求是否成功 
     */  
    private static boolean sendPOSTRequest(String path, Map<String, String> params, String encoding) throws Exception{
        StringBuilder data = new StringBuilder(); 
        if(params!=null && !params.isEmpty()){  
            for(Map.Entry<String, String> entry : params.entrySet()){  
                data.append(entry.getKey()).append("=");  
                data.append(URLEncoder.encode(entry.getValue(), encoding));  
                data.append("&");  
            }  
            data.deleteCharAt(data.length() - 1);  
        }  
        byte[] entity = data.toString().getBytes();//生成实体数据,Post方式提交参数的话,不能省略内容类型与长度
        HttpURLConnection conn = (HttpURLConnection) new URL(path).openConnection();  
        conn.setConnectTimeout(5000);  
        conn.setRequestMethod("POST");  
        conn.setDoOutput(true);//允许对外输出数据  
        conn.setRequestProperty("Content-Type", "application/x-www-form-urlencoded");  
        conn.setRequestProperty("Content-Length", String.valueOf(entity.length));  
        OutputStream outStream = conn.getOutputStream();  
        outStream.write(entity);  
        if(conn.getResponseCode() == 200){  
            return true;  
        }  
        return false;  
    }

(2)Http请求头(Header):
所有关于此次http请求的配置都在http头里面定义,connect()函数会根据HttpURLConnection对象的配置值生成http头信息,因此在调用connect函数之前,就必须把所有的配置(那一堆set函数)准备好。
(3)Http请求消息体(Body):
在http头后面紧跟着的是http请求的正文,正文的内容是通过outputStream流写入的,实际上outputStream不是一个网络流,充其量是个字符串流,往里面写入的东西不会立即发送到网络,而是存在于内存缓冲区中,待outputStream流关闭时,根据输入的内容生成http正文。至此,http请求的东西已经全部准备就绪。在getInputStream()函数调用的时候,就会把准备好的http请求(包括http头和正文)正式发送到服务器了,然后返回一个输入流,用于读取服务器对于此次http请求的返回信息。由于http请求在getInputStream的时候已经发送出去了,因此在getInputStream()函数之后对connection对象进行设置(对http头的信息进行修改)或者写入outputStream(对正文进行修改)都是没有意义的了,执行这些操作会导致异常的发生。

任何一种接口,无外乎四个基本功能:访问网页、下载图片或文件、上传文件。下面我们逐一看一下。
(1)访问网页:
GET:

    /**
     * @Description Get获取网络资源
     * @param urlPath 网络资源的地址
     * @param params Get请求参数
     * @param encoding 发送内容编码方式
     * @return 返回网络资源的内容(字符串)
     */
    public static String sendGetRequest(String urlPath, Map<String, String> params, String encoding) throws Exception {

        // 使用StringBuilder对象
        StringBuilder sb = new StringBuilder(urlPath);
        sb.append('?');

        // 迭代Map
        for (Map.Entry<String, String> entry : params.entrySet()) {
        //解决请求参数中含有中文导致乱码问题
            sb.append(entry.getKey()).append('=').append(URLEncoder.encode(entry.getValue(), encoding)).append('&');
        }
        sb.deleteCharAt(sb.length() - 1);

        // 打开链接
        URL url = new URL(sb.toString());
        HttpURLConnection conn = (HttpURLConnection) url.openConnection();
        conn.setRequestMethod("GET");
        conn.setRequestProperty("Content-Type", "text/xml");
        conn.setRequestProperty("Charset", encoding);
        conn.setConnectTimeout(PARAM_CONNECT_TIMEOUT);
        // 如果请求响应码是200,则表示成功
        if (conn.getResponseCode() == 200) {
            // 获得服务器响应的数据
            BufferedReader in = new BufferedReader(new InputStreamReader(conn.getInputStream(), encoding));
            // 数据
            String retData = null;
            String responseData = "";
            while ((retData = in.readLine()) != null) {
                responseData += retData;
            }
            in.close();
            return responseData;
        }
        return "sendGetRequest error!";
    }

POST:

    /**
     * 通过Post方式提交参数给服务器
     */
    public static String sendPostRequest(String urlPath,Map<String, String> params, String encoding) throws Exception {
        StringBuilder sb = new StringBuilder();
        // 如果参数不为空
        if (params != null && !params.isEmpty()) {
            for (Map.Entry<String, String> entry : params.entrySet()) {
                // Post方式提交参数的话,不能省略内容类型与长度
                sb.append(entry.getKey()).append('=').append(URLEncoder.encode(entry.getValue(), encoding)).append('&');
            }
            sb.deleteCharAt(sb.length() - 1);
        }
        // 得到实体的二进制数据
        byte[] entitydata = sb.toString().getBytes();
        URL url = new URL(urlPath);
        HttpURLConnection conn = (HttpURLConnection) url.openConnection();
        conn.setRequestMethod("POST");
        conn.setConnectTimeout(PARAM_CONNECT_TIMEOUT);
        // 如果通过post提交数据,必须设置允许对外输出数据
        conn.setDoOutput(true);
        // 这里只设置内容类型与内容长度的头字段
        conn.setRequestProperty("Content-Type","application/x-www-form-urlencoded");
        // conn.setRequestProperty("Content-Type", "text/xml");
        conn.setRequestProperty("Charset", encoding);
        conn.setRequestProperty("Content-Length", String.valueOf(entitydata.length));
        OutputStream outStream = conn.getOutputStream();
        // 把实体数据写入是输出流
        outStream.write(entitydata);
        // 内存中的数据刷入
        outStream.flush();
        outStream.close();
        // 如果请求响应码是200,则表示成功
        if (conn.getResponseCode() == 200) {
            // 获得服务器响应的数据
            BufferedReader in = new BufferedReader(new InputStreamReader(conn.getInputStream(), encoding));
            // 数据
            String retData = null;
            String responseData = "";
            while ((retData = in.readLine()) != null) {
                responseData += retData;
            }
            in.close();
            return responseData;
        }
        return "sendPostRequest error!";
    }
/**
     * 通过Post方式传送文本给服务器,例如Json,xml等
     */
    public static String sendTxtWithPost(String urlPath, String txt, String encoding) throws Exception {
        byte[] sendData = txt.getBytes(encoding);
        URL url = new URL(urlPath);
        HttpURLConnection conn = (HttpURLConnection) url.openConnection();
        conn.setRequestMethod("POST");
        conn.setConnectTimeout(PARAM_CONNECT_TIMEOUT);
        // 如果通过post提交数据,必须设置允许对外输出数据
        conn.setDoOutput(true);
        conn.setRequestProperty("Content-Type", "text/xml");
        conn.setRequestProperty("Charset", encoding);
        conn.setRequestProperty("Content-Length", String.valueOf(sendData.length));
        OutputStream outStream = conn.getOutputStream();
        outStream.write(sendData);
        outStream.flush();
        outStream.close();
        if (conn.getResponseCode() == 200) {
            // 获得服务器响应的数据
            BufferedReader in = new BufferedReader(new InputStreamReader(conn.getInputStream(), encoding));
            // 数据
            String retData = null;
            String responseData = "";
            while ((retData = in.readLine()) != null) {
                responseData += retData;
            }
            in.close();
            return responseData;
        }
        return "sendTxtWithPost error!";
    }

(2)下载文件或图片:

/**
     * @Description Get获取网络资源
     * @param urlPath 网络资源的地址
     * @param params Get请求参数
     * @param encoding 发送内容编码方式
     * @return 返回下载结果
     */
    public static String downloadFileWithGet(String urlPath, String dirPath, String filename, String encoding) throws Exception {
        // 使用StringBuilder对象
        StringBuilder sb = new StringBuilder(urlPath);
        sb.append('?');
        //解决请求参数中含有中文导致乱码问题
        sb.append("filename").append('=').append(URLEncoder.encode(filename, encoding));

        // 打开链接
        URL url = new URL(sb.toString());
        HttpURLConnection conn = (HttpURLConnection) url.openConnection();
        conn.setRequestMethod("GET");
        conn.setRequestProperty("Content-Type", "image/png");
        conn.setRequestProperty("Charset", encoding);
        conn.setConnectTimeout(PARAM_CONNECT_TIMEOUT);
        // 如果请求响应码是200,则表示成功
        if (conn.getResponseCode() == 200) {
            // 获得服务器响应的数据
            InputStream in = conn.getInputStream(); 
            File resultFile = write2SDFromInput(dirPath, filename, in);
            in.close();
            if (resultFile == null) {
                return "下载失败";
            }
            return "下载成功";
        }
        return "下载失败";
    }

    /**
     * 将一个InputStream里面的数据写入到SD卡中
     */
    private static File write2SDFromInput(String directory, String fileName,InputStream input) {
        File file = null;
        FileOutputStream output = null;
        File dir = new File(directory);
        if (!dir.exists()) {
            dir.mkdir();
        }
        try {
            file = new File(dir + File.separator + fileName);
            file.createNewFile();
            output = new FileOutputStream(file);
            byte buffer[] = new byte[1024];
            while ((input.read(buffer)) != -1) {
                output.write(buffer);
            }
            output.flush();
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            try {
                output.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
        return file;
    }

(3)上传文件

    /**
     * 上传文件,这里不支持进度显示和断点续传         
     * @param urlPath 上传的服务器的路径 
     * @param filePath 需要上传的文件路径
     * @param newName 上传的文件名称,不填写将为需要上传文件表单中的名字
     * @throws IOException 
     */  
    public static String sendFileWithPost (String urlPath, String filePath,String newName) throws Exception {
        String end = "\r\n";
        String twoHyphens = "--";
        String boundary = "*****";

        StringBuilder sb = new StringBuilder();
        /** 
         * 上传文件的头 
         */  
        sb.append(twoHyphens + boundary + end);  
        sb.append("Content-Disposition: form-data; " + "name=\"uploadFile\";filename=\"" + newName + "\"" + end);  
 //     sb.append("Content-Type: image/png" + "\r\n");// 如果服务器端有文件类型的校验,必须明确指定ContentType  
        sb.append(end);  

        byte[] headerInfo = sb.toString().getBytes("UTF-8");  
        byte[] endInfo = (end + twoHyphens + boundary + twoHyphens + end).getBytes("UTF-8");

        URL url = new URL(urlPath);
        HttpURLConnection con = (HttpURLConnection) url.openConnection();
        /* 允许Input、Output,不使用Cache */
        con.setDoInput(true);
        con.setDoOutput(true);
        con.setUseCaches(false);
        /* 设置传送的method=POST */
        con.setRequestMethod("POST");
        /* setRequestProperty */
        con.setRequestProperty("Connection", "Keep-Alive");
        con.setRequestProperty("Charset", "UTF-8");
        con.setRequestProperty("Content-Type", "multipart/form-data;boundary=" + boundary);

        /* 设置OutputStream */
        OutputStream out = con.getOutputStream();       
        out.write(headerInfo);

        /* 取得文件的FileInputStream */
        FileInputStream in = new FileInputStream(filePath);
        /* 设置每次写入1024bytes */
        int bufferSize = 1024;
        byte[] buffer = new byte[bufferSize];
        int length = -1;
        /* 从文件读取数据至缓冲区 */
        while ((length = in.read(buffer)) != -1) {
            /* 将资料写入DataOutputStream中 */
            out.write(buffer, 0, length);
        }
        out.write(endInfo);

        /* close streams */
        in.close();  
     // 内存中的数据刷入
        out.flush();
        out.close();

        /* 取得Response内容 */     
        // 如果请求响应码是200,则表示成功
        if (con.getResponseCode() == 200) {
            // 获得服务器响应的数据
            BufferedReader bf = new BufferedReader(new InputStreamReader(con.getInputStream(), "utf-8"));
            // 数据
            String retData = null;
            String responseData = "";
            while ((retData = bf.readLine()) != null) {
                responseData += retData;
            }
            bf.close();
            return responseData;
        }  
        return "sendFileWithPost error!";
    }

HttpClient

如果只是向Web站点的某个简单页面提交请求并获取服务器响应,HttpURLConnection完全可以胜任。但在绝大部分情况下,Web站点的网页可能没这么简单,这些页面并不是通过一个简单的URL就可访问的,可能需要用户登录而且具有相应的权限才可访问该页面。在这种情况下,就需要涉及Session、Cookie的处理了,如果打算使用HttpURLConnection来处理这些细节,当然也是可能实现的,只是处理起来难度就大了。
为了更好地处理向Web站点请求,包括处理Session、Cookie等细节问题,Apache开源组织提供了一个HttpClient项目,它是一个简单的HTTP客户端(并不是浏览器),可以用于发送HTTP请求,接收HTTP响应,但不会缓存服务器的响应,不能执行HTML页面中嵌入的JavaScript代码;也不会对页面内容进行任何解析、处理。它只是关注于如何发送请求、接收响应,以及管理HTTP连接。
其实访问Web应用中被保护的页面,使用浏览器则十分简单,用户通过系统提供的登录页面登录系统,浏览器会负责维护与服务器之间的Sesion,如果用户登录的用户名、密码符合要求,就可以访问被保护资源了。在Android应用程序中,则可使用HttpClient来登录系统,只要应用程序使用同一个HttpClient发送请求,HttpClient会自动维护与服务器之间的Session状态,也就是说程序第一次使用HttpClient登录系统后,接下来使用HttpClient即可访问被保护页而了。
HttpClient有三个已知的实现类分别是:AbstractHttpClient, AndroidHttpClient, DefaultHttpClient,会发现有一个专门为Android应用准备的实现类AndroidHttpClient,当然使用常规的DefaultHttpClient也可以实现功能,但是既然开发的是Android应用程序,还是使用Android专有的实现类,一定有其优势。HttpClient支持但默认不带GZIP压缩,可以自己写。

使用方法:
1. 创建HttpClient对象。
2. 创建请求方法的实例,并指定请求URL。如果需要发送GET请求,创建HttpGet对象;如果需要发送POST请求,创建HttpPost对象。
3. 如果需要发送请求参数,可调用HttpGet、HttpPost共同的setParams(HttpParams params)方法来添加请求参数;对于HttpPost对象而言,也可调用setEntity(HttpEntity entity)方法来设置请求参数。
4. 调用HttpClient对象的execute(HttpUriRequest request)发送请求,该方法返回一个HttpResponse。
5. 调用HttpResponse的getAllHeaders()、getHeaders(String name)等方法可获取服务器的响应头;调用HttpResponse的getEntity()方法可获取HttpEntity对象,该对象包装了服务器的响应内容。程序可通过该对象获取服务器的响应内容。
6. 释放连接。无论执行方法是否成功,都必须释放连接。

public static String sendHttpClientWithPost(String urlPath,Map<String, String> params, String encoding) throws Exception {
        BasicHttpParams params = new BasicHttpParams();
        HttpConnectionParams.setConnectionTimeout(params, 6000); //连接超时
        HttpConnectionParams.setSoTimeout(params, 6000); //等待数据超时
        DefaultHttpClient client = new DefaultHttpClient(params);
        // 需要把参数放到NameValuePair
        List<NameValuePair> paramPairs = new ArrayList<NameValuePair>();
        if (params != null && !params.isEmpty()) {
            for (Map.Entry<String, String> entry : params.entrySet()) {
                paramPairs.add(new BasicNameValuePair(entry.getKey(), entry.getValue()));
            }
        }
        // 对请求参数进行编码,得到实体数据
        UrlEncodedFormEntity entitydata = new UrlEncodedFormEntity(paramPairs, encoding);
        // 构造一个请求路径
        HttpPost post = new HttpPost(urlPath);
        //添加请求头
        post.addHeader("Connection", "Keep-Alive");
        // 设置请求实体
        post.setEntity(entitydata);
        // 执行post请求
        HttpResponse response = client.execute(post);
        // 从状态行中获取状态码,判断响应码是否符合要求
        if (response.getStatusLine().getStatusCode() == 200) {
            HttpEntity entity = response.getEntity();
            InputStream inputStream = entity.getContent();
            InputStreamReader inputStreamReader = new InputStreamReader(inputStream, encoding);
            BufferedReader reader = new BufferedReader(inputStreamReader);// 读字符串用的。
            String s;
            String responseData = "";
            while (((s = reader.readLine()) != null)) {
                responseData += s;
            }
            reader.close();// 关闭输入流
            return responseData;
        }
        return "sendHttpClientPost error!";
    }

选用:
1、涉及Session、Cookie的处理建议使用HttpClient。
2、在Android 2.2版本之前,HttpClient拥有较少的bug,因此使用它是最好的选择。而在Android 2.3版本及以后,HttpURLConnection则是最佳的选择。它的API简单,体积较小,因而非常适用于Android项目。压缩和缓存机制可以有效地减少网络访问的流量,在提升速度和省电方面也起到了较大的作用。对于新的应用程序应该更加偏向于使用HttpURLConnection,因为在以后的工作当中我们也会将更多的时间放在优化HttpURLConnection上面。

AsyncHttpClient

HttpURLConnection和HttpClient的用法还是稍微有些复杂的,如果不进行适当封装的话,很容易就会写出不少重复代码。于是乎,一些Android网络通信框架也就应运而生,比如说AsyncHttpClient(需要导入JAR包),它把HTTP所有的通信细节全部封装在了内部,我们只需要简单调用几行代码就可以完成通信操作了。它是专门针对Android在Apache的HttpClient基础上构建的异步的callback-based http client。所有的请求全在UI线程之外发生,而callback发生在创建它的线程中,应用了Android的Handler发送消息机制。你也可以把AsyncHttpClient应用在Service中或者后台线程中,库代码会自动识别出它所运行的context。

AsyncHttpClient client = new AsyncHttpClient();
client.get("http://www.google.com", new AsyncHttpResponseHandler() {
    @Override
    public void onStart() {
        // called before request is started
    }
    @Override
    public void onSuccess(int statusCode, Header[] headers, byte[] response) {
        // called when response HTTP status is "200 OK"
    }
    @Override
    public void onFailure(int statusCode, Header[] headers, byte[] errorResponse, Throwable e) {
        // called when response HTTP status is "4XX" (eg. 401, 403, 404)
    }
    @Override
    public void onRetry(int retryNo) {
        // called when request is retried
    }
});

这里你只需要通过匿名内部类的方式实现AsyncHttpResponseHandler,而且更棒的是你只需要override感兴趣的方法,比如一般都是onSuccess和onFailure。这个版本的get方法没有为请求传递任何参数,当然你也可以通过RequestParams来传递各种参数,如下:

AsyncHttpClient client = new AsyncHttpClient();
RequestParams params = new RequestParams();
params.put("key", "value");
params.put("more", "data");
client.get("http://www.google.com", params, new AsyncHttpResponseHandler() {
        @Override
        public void onSuccess(int statusCode, Header[] headers, byte[] responseBody) {
            String reponse = new String(responseBody);
            Log.d("onSuccess", reponse );
        }
        @Override
        public void onFailure(int statusCode, Header[] headers, byte[] responseBody, Throwable error) {
            Log.d("onFailure", error);
        }    
    }
);

以上的例子是返回的response直接是原生字节流的情况,如果你需要把返回的结果当一个String对待,这时只需要匿名实现一个TextHttpResponseHandler就行,其继承自AsyncHttpResponse,并将原生的字节流根据指定的encoding转化成了string对象

AsyncHttpClient client = new AsyncHttpClient();
RequestParams params = new RequestParams();
params.put("key", "value");
params.put("more", "data");
client.get("http://www.google.com", params, new TextHttpResponseHandler() {
        @Override
        public void onSuccess(int statusCode, Header[] headers, String responseBody) {
            Log.d("onSuccess", responseBody);
        }
        @Override
        public void onFailure(int statusCode, Header[] headers, String responseBody, Throwable error) {
            Log.d("onFailure", error);
        }    
    }
);

同样的方式,你可以实现JsonHttpResponseHandler,返回的response已经自动转化成JSONObject了,当然也支持JSONArray类型,override你需要的那个版本就行。

AsyncHttpClient client = new AsyncHttpClient();
RequestParams params = new RequestParams();
params.put("key", "value");
params.put("more", "data");
client.get("http://www.google.com", params, new JsonHttpResponseHandler() {            
    @Override
    public void onSuccess(int statusCode, Header[] headers, JSONObject responseBody) {
       // Handle resulting parsed JSON response here
    }
    @Override
    public void onSuccess(int statusCode, Header[] headers, JSONArray responseBody) {
      // Handle resulting parsed JSON response here
    }
});
  • 1
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值