android网络应用(二)——HttpURLConnection和HttpClient

来源:互联网 发布:善待网络 编辑:程序博客网 时间:2024/06/10 23:54

    • HttpURLConnection
      • 获取HttpURLConnection实例对象
      • 请求方法一get
      • 请求方法二post
    • HttpClient
      • 获取HttpClient抽象类
      • GET 请求创建一个 HttpGet 对象
      • POST请求HttpPost 对象
      • execute
      • 实例
    • 网络编程的最佳实践
      • 抽取公有部分设置快速使用网络功能类
      • 改进版
    • 二者区别

HttpURLConnection

获取HttpURLConnection实例对象

URL url = new URL("http://www.baidu.com");HttpURLConnection connection = (HttpURLConnection) url.openConnection();

请求方法一——get

1、设置请求方法

connection.setRequestMethod("GET");

2、接下来设置延时设置或者服务器希望得到的一些消息头!!!

connection.setConnectTimeout(8000);connection.setReadTimeout(8000);

3、获取输入流,并进行读取

InputStream in = connection.getInputStream();

4、关闭连接

connection.disconnect();

5、实例

// 开启线程来发起网络请求new Thread(new Runnable() {    @Override    public void run() {        HttpURLConnection connection = null;        try {            URL url = new URL("http://www.baidu.com");            connection = (HttpURLConnection) url.openConnection();            connection.setRequestMethod("GET");            connection.setConnectTimeout(8000);            connection.setReadTimeout(8000);            InputStream in = connection.getInputStream();            // 下面对获取到的输入流进行读取            BufferedReader reader = new BufferedReader(newInputStreamReader(in));            StringBuilder response = new StringBuilder();            String line;            while ((line = reader.readLine()) != null) {                response.append(line);            }            Message message = new Message();            message.what = SHOW_RESPONSE;            // 将服务器返回的结果存放到Message中            message.obj = response.toString();            handler.sendMessage(message);        } catch (Exception e) {            e.printStackTrace();        } finally {            if (connection != null) {                connection.disconnect();            }        }    }}).start();}
//注意权限<uses-permission android:name="android.permission.INTERNET" />

请求方法二——post

和get差距不大,但是要注意参数以及提交数据设置

connection.setRequestMethod("POST");DataOutputStream out = new DataOutputStream(connection.getOutputStream());out.writeBytes("username=admin&password=123456");

HttpClient

获取HttpClient(抽象类)

HttpClient 是一个接口,因此无法创建它的实例,通常情况下都会创建一个 DefaultHttpClient 的实例。

HttpClient httpClient = new DefaultHttpClient();

GET 请求——创建一个 HttpGet 对象

HttpGet httpGet = new HttpGet("http://www.baidu.com");httpClient.execute(httpGet);

POST请求——HttpPost 对象

要创建一个 HttpPost 对象,并传入目标的网络地址,如下所示:    HttpPost httpPost = new HttpPost("http://www.baidu.com");然后通过一个 NameValuePair 集合来存放待提交的参数,并将这个参数集合传入到一个UrlEncodedFormEntity 中,然后调用 HttpPost 的 setEntity()方法将构建好的UrlEncodedFormEntity传入,如下所示:    List<NameValuePair> params = new ArrayList<NameValuePair>();    params.add(new BasicNameValuePair("username", "admin"));    params.add(new BasicNameValuePair("password", "123456"));    UrlEncodedFormEntity entity = new UrlEncodedFormEntity(params, "utf-8");    httpPost.setEntity(entity);    httpClient.execute(httpPost);

execute()

执行 execute()方法之后会返回一个 HttpResponse 对象,服务器所返回的所有信息就会包含在这里面。通常情况下我们都会先取出服务器返回的状态码,如果等于 200 就说明请求和响应都成功了,如下所示:

if (httpResponse.getStatusLine().getStatusCode() == 200) {// 请求和响应都成功了接下来在这个 if 判断的内部取出服务返回的具体内容,可以调用 getEntity()方法获取到一个 HttpEntity 实例,然后再用 EntityUtils.toString()这个静态方法将 HttpEntity 转换成字符串即可,如下所示:    HttpEntity entity = httpResponse.getEntity();    //String response = EntityUtils.toString(entity);    //上面会出现中文乱码    String response = EntityUtils.toString(entity, "utf-8");}

实例

Thread(new Runnable() {    @Override    public void run() {        try {            HttpClient httpClient = new DefaultHttpClient();            HttpGet httpGet = new HttpGet("http://www.baidu.com");            HttpResponse httpResponse = httpClient.execute(httpGet);            if (httpResponse.getStatusLine().getStatusCode() == 200) {                // 请求和响应都成功了                HttpEntity entity = httpResponse.getEntity();                String response = EntityUtils.toString(entity,"utf-8");                Message message = new Message();                message.what = SHOW_RESPONSE;                // 将服务器返回的结果存放到Message中                message.obj = response.toString();                handler.sendMessage(message);            }        } catch (Exception e) {            e.printStackTrace();        }    }    }).start();}

网络编程的最佳实践

抽取公有部分,设置快速使用网络功能类

public class HttpUtil {    public static String sendHttpRequest(String address) {        HttpURLConnection connection = null;        try {            URL url = new URL(address);            connection = (HttpURLConnection) url.openConnection();            connection.setRequestMethod("GET");            connection.setConnectTimeout(8000);            connection.setReadTimeout(8000);            connection.setDoInput(true);            connection.setDoOutput(true);            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);            }            return response.toString();        } catch (Exception e) {            e.printStackTrace();            return e.getMessage();        } finally {            if (connection != null) {                connection.disconnect();            }        }    }}
//调用String address = "http://www.baidu.com";String response = HttpUtil.sendHttpRequest(address);

网络请求通常都是属于耗时操作,而 sendHttpRequest()方法的内部并没有开启线程,这样就有可能导致在调用 sendHttpRequest()方法的时候使得主线程被阻塞住。PS:现在网络请求都要求不能在主线程中启用。

在sendHttpRequest()方法内部开启一个线程不就解决这个问题了吗?其实不是像你想象中的那么容易,因为如果我们在 sendHttpRequest()方法中开启了一个线程来发起 HTTP 请求,那么服务器响应的数据是无法进行返回的,所有的耗时逻辑都是在子线程里进行的,sendHttpRequest()方法会在服务器还来得及响应的时候就执行结束了,当然也就无法返回响应的数据了。
解决方法:Java 的回调机制

public interface HttpCallbackListener {    //当服务器成功响应我们请求的时候调用    void onFinish(String response);    //当进行网络操作出现错误的时候调用    void onError(Exception e);}

这两个方法都带有参数,onFinish()方法中的参数代表着服务器返回的数据,而 onError()方法中的参数记录着错误的详细信息。

改进版

public class HttpUtil {    public static void sendHttpRequest(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);                    connection.setDoInput(true);                    connection.setDoOutput(true);                    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();    }}
//调用HttpUtil.sendHttpRequest(address, new HttpCallbackListener() {    @Override    public void onFinish(String response) {        // 在这里根据返回内容执行具体的逻辑    }    @Override    public void onError(Exception e) {        // 在这里对异常情况进行处理    }});

当服务器成功响应的时候我们就可以在 onFinish()方法里对响应数据进行处理了,类似地,如果出现了异常,就可以在 onError()方法里对异常情况进行处理。如此一来,我们就巧妙地利用回调机制将响应数据成功返回给调用方了。另外需要注意的是,onFinish()方法和 onError()方法最终还是在子线程中运行的,因此我们不可以在这里执行任何的 UI 操作。

二者区别

http://blog.csdn.net/hguang_zjh/article/details/33743249

0 0
原创粉丝点击