Android学习笔记----HttpURLConnection 和 HttpClient(已经被废弃)

/*********** ****************************************************/
使用 HTTP 协议访问网络

在 Android 上发送 HTTP 请求的方式一般有两种, HttpURLConnection 和 HttpClient.

HttpURLConnection

首先需要获取到 HttpURLConnection 的实例,一般只需 new 出一个 URL 对象,并传入目标的网络地址,然后调用一下 openConnection()方法即可。

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

注意:如果URL传入的地址中含有中文要对含有的中文进行URL编码,然后再拼接成地址,否则传递数据会出现中文乱码问题,解决方式如下:

String param1 = URLEncoder.encode(中文);

得到了 HttpURLConnection 的实例之后,我们可以设置一下 HTTP 请求所使用的方法。常用的方法主要有两个, GET 和 POST。
 GET 表示希望从服务器那里获取数据   
 POST 则表示希望提交数据给服务器

connection.setRequestMethod("GET");

注意:其实GET方式也可以向服务器提交数据,如何通过GET方式提交数据,见最后GET方式提交数据

接下来就可以进行一些自由的定制了,比如设置连接超时读取超时的毫秒数,以及服务器希望得到的一些消息头等。这部分内容根据自己的实际情况进行编写

connection.setConnectTimeout(8000); //设置连接超时
connection.setReadTimeout(8000);    //读取超时的毫秒数

获取连接状态码,如果状态码为200则表示连接成功

int status_code = connection.getResponseCode();
if(code == 200){
.........................................................................................
}

之后再调用 getInputStream()方法就可以获取到服务器返回的输入流了

InputStream in = connection.getInputStream();//获取到服务器返回的输入流了

剩下的任务就是对输入流进行读取,然后进行相关处理

public class StreamTool {
    /**
     * 把一个inputstream里面的内容转化成一个byte[]
     */
    public static byte[] getBytes(InputStream is) throws Exception{
        ByteArrayOutputStream bos = new ByteArrayOutputStream();
        byte[] buffer = new byte[1024];
        int len = 0;
        while((len = is.read(buffer))!=-1){
            bos.write(buffer, 0, len);
        }
        is.close();
        bos.flush();
        byte[] result = bos.toByteArray();
        return  result;
    }
}

byte[] result = StreamTool.getBytes(in);
//如果读取的是图片数据
Bitmap bitmap = BitmapFactory.decodeByteArray(result,0,result.length);//也可以直接用Bitmap bitmap = BitmapFactory.decodeStream(in);
......
//如果读取的是网页数据,此处要注意网页的编码问题
String temp = new String(result);
if (temp.contains("gbk")) {
    String temp = new String(result, "gb2312");
    .......................
} else {
    .......................
}
最后需要调用 disconnect()方法将这个 HTTP 连接关闭掉

connection.disconnect();
实例:

private Handler handler = new Handler() {
    public void handleMessage(Message msg) {
    switch (msg.what) {
        case SHOW_RESPONSE:
        String response = (String) msg.obj;
        // 在这里进行UI操作,将结果显示到界面上

    }
  }
};

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(new  InputStreamReader(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();

提交数据给服务器

将 HTTP 请求的方法改成 POST,并在获取输入流之前把要提交的数据写出即可。注意每条数据都要以键值对的形式存在,数据与数据之间用&符号隔开,比如说我们想要向服务器提交用户名和密码,就可以这样写:

connection.setRequestMethod("POST");//设置为POST方式
DataOutputStream out = new DataOutputStream(connection.getOutputStream());
out.writeBytes("username=admin&password=123456");//向服务器提交数据
int code = conn.getResponseCode();//获取服务器返回的状态码,以此来判断数据是否提交成功
if(code==200){
    //数据提交成功,获取服务器返回的数据
    InputStream in = conn.getInputStream();
    byte[] result = StreamTool.getBytes(in); //StreamTool.getBytes(is)是自定义的流处理方法,见第一段实例代码
    ........................................................................
}

注意:如果传入的地址中含有中文要对中文进行URL编码,然后再拼接成地址,否则传递数据会出现中文乱码问题,解决方式如下:

String param1 = URLEncoder.encode(中文参数);
 
同时如果要提交的数据中含有中文要对提交的中文数据进行URL编码,否则传输数据会出现中文乱码问题,解决方式如下:

String param1 = URLEncoder.encode(“张三”);
out.writeBytes("username=
"+
param1+
"
&password=123456");//对于英文或者数字,进不进行URL编码应该没有什么影响


!!!!!!!HttpClient!!!!!!已经被废弃掉了


HttpClient

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

HttpClient httpClient = new DefaultHttpClient();

接下来如果想要发起一条 GET 请求,就可以创建一个 HttpGet 对象,并传入目标的网络地址,然后调用 HttpClient 的 execute()方法即可:

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

注意:如果传入的地址参数中含有中文要对中文参数进行URL编码,然后再拼接成地址,否则传递数据会出现中文乱码问题,解决方式如下:

String param1 = URLEncoder.encode(中文参数);

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

if (httpResponse.getStatusLine().getStatusCode() == 200) {
// 请求和响应都成功了
}

接下来在这个 if 判断的内部取出服务返回的具体内容,可以调用 getEntity()方法获取到一个 HttpEntity 实例,然后再用 EntityUtils.toString()这个静态方法将 HttpEntity 转换成字符串即可(也可以调用entity的getContent()实例方法,得到输入流),如下所示:

HttpEntity entity = httpResponse.getEntity(); 
String response = EntityUtils.toString(entity);


或者

HttpEntity entity = httpResponse.getEntity(); 
InputStream in    = entity.getContent();
byte[] result = StreamTool.getBytes(in);  //StreamTool.getBytes(in)是自定义的流处理方法,见第一段实例代码

注意如果服务器返回的数据是带有中文的,直接调用 EntityUtils.toString()方法进行转换会有乱码的情况出现,这个时候只需要在转换的时候将字符集指定成 utf-8 就可以了,如下所示:

String response = EntityUtils.toString(entity, "utf-8");

实例:

private Handler handler = new Handler() {
    public void handleMessage(Message msg) {
        switch (msg.what) {
            case SHOW_RESPONSE:
                String response = (String) msg.obj;
                // 在这里进行UI操作,将结果显示到界面上

        }
    }
};
new 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();



提交数据给服务器

创建一个 DefaultHttpClient 的实例

HttpClient httpClient = new DefaultHttpClient();

创建一个 HttpPost 对象,并传入目标的网络地址,如下所示:

HttpPost httpPost = new HttpPost("http://www.baidu.com");

注意:如果传入的地址参数中含有中文要对中文参数进行URL编码,然后再拼接成地址,否则传递数据会出现中文乱码问题,解决方式如下:

String param1 = URLEncoder.encode(中文参数);

然后通过一个 NameValuePair 集合来存放待提交的参数,并将这个参数集合传入到一个UrlEncodedFormEntity 中,然后调用 HttpPost 的 setEntity()方法将构建好的 UrlEncodedFormEntity传入,如下所示:

List params = new ArrayList();
params.add(new BasicNameValuePair("username", "admin"));
params.add(new BasicNameValuePair("password", "123456"));
UrlEncodedFormEntity entity = new UrlEncodedFormEntity(params, "utf-8");
httpPost.setEntity(entity);


注意: 如果要 提交的数据中含有中文要对提交的中文数据进行URL编码 ,否则传输数据会出现中文乱码问题,解决方式如下:

String param1 = URLEncoder.encode(“张三”);
params.add(new BasicNameValuePair("username", param1));


接下来的操作就和 HttpGet 一样了,调用 HttpClient 的 execute()方法,并将 HttpPost 对象传入即可:

HttpResponse  httpResponse = httpClient.execute(httpPost);

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

if (httpResponse.getStatusLine().getStatusCode() == 200) {
   // 请求和响应都成功,接下来可以获取服务器的返回数据
     HttpEntity entity = httpResponse.getEntity(); 
     String response = EntityUtils.toString(entity);
   或者
     HttpEntity entity = httpResponse.getEntity(); 
     String response = EntityUtils.toString(entity, "utf-8");//这样可以防止乱码问题
   或者
    HttpEntity entity = httpResponse.getEntity(); 
    InputStream in    = entity.getContent();
    byte[] result = StreamTool.getBytes(in);  //StreamTool.getBytes(in)是自定义的流处理方法,见第一段实例代码
    .........................................................................
}



/*********** ****************************************************/

GET方式提交数据

HttpURLConnection的GET方式:

  String path = "提交数据的服务器的地址";
  String param1 = URLEncoder.encode(name);               //对要传递的数据进行URL编码,防止出现乱码问题
  String param2 = URLEncoder.encode(password);       //对要传递的数据进行URL编码,防止出现乱码问题
  URL url = new URL(path + "?name=" + param1 + "&password=" + param2);//如果path中含有中文参数的话,也要对path进行URL编码
  HttpURLConnection conn = (HttpURLConnection) url.openConnection();
  conn.setRequestMethod("GET");
  conn.setReadTimeout(5000);
  // 只有调用getInputStream()方法的时候,数据才会被提交到服务器。
  // 获取服务器返回的流信息
  InputStream is = conn.getInputStream();
  byte[] result = StreamTool.getBytes(in);  //StreamTool.getBytes(in)是自定义的流处理方法,见第一段实例代码
  .........................................................................


HttpClient的GET方式:
 
 //1. 获取到一个浏览器的实例
  HttpClient client = new DefaultHttpClient();
  //2. 准备请求的地址
  String param1 = URLEncoder.encode(name);                   //对要传递的数据进行URL编码,防止出现乱码问题
  String param2 = URLEncoder.encode(password);            //对要传递的数据进行URL编码,防止出现乱码问题
  HttpGet httpGet = new HttpGet(path + "?name=" + param1 + "&password=" + param2); //如果path中含有中文参数的话,也要对path进行URL编码
 
  //3. 敲回车 发请求
  HttpResponse  ressponse = client.execute(httpGet);
  int code = ressponse.getStatusLine().getStatusCode();
  if(code == 200){
       InputStream is  =ressponse.getEntity().getContent();
       byte[] result = StreamTool.getBytes(in);  //StreamTool.getBytes(in)是自定义的流处理方法,见第一段实例代码
       .....................................................................
  }
  else{
     .....................................................................
  }





POST方式跟GET方式提交数据到服务器的区别:

get 一次提交的数据数据量比较小 4K 内部其实通过组拼url的方式
post 可以提交比较大的数据 form表单的形式 流的方式写到服务器
   
补充:

为了防止服务器端接收到的中文字符是乱码,在服务器端接收到的数据要注意编码问题。

 String name = request.getParameter("name");
  if(name!=null){
      name =	new String( name.getBytes("iso8859-1"),"utf-8");
  }

服务器端对接收的字节流,按照 "iso8859-1" 进行编码生成字符串 所以对接收到的字符串,要按 "iso8859-1" 反编码成字节数组,再按UTF-8重新进行编码,生成中文字符。


你可能感兴趣的:(android,网络,Ht,Android基础)