android 网络编程 HttpGet类和HttpPost类使用详解

    虽然在登录系统中使用了Web Service与服务端进行交互。但是在传递大量的数量时,Web Service显得有些笨拙。在本节将介绍移动电子相册中使用的另外一种与数据库交互的方法。直接发送HTTP GET或POST请求。这就要用到HttpGet、HttpPost以及HttpURLConnection这些类。

15.3.1  HttpGet类和HttpPost类

本节将介绍Android SDK集成的Apache HttpClient模块。要注意的是,这里的Apache HttpClient模块是HttpClient 4.0(org.apache.http.*),而不是Jakarta Commons HttpClient 3.x(org.apache.commons.httpclient.*)。

在HttpClient模块中用到了两个重要的类:HttpGet和HttpPost。这两个类分别用来提交HTTP GET和HTTP POST请求。为了测试本节的例子,需要先编写一个Servlet程序,用来接收HTTP GET和HTTP POST请求。读者也可以使用其他服务端的资源来测试本节的例子。

假设192.168.17.81是本机的IP,客户端可以通过如下的URL来访问服务端的资源:

http://192.168.17.81:8080/querybooks/QueryServlet?bookname=开发

在这里bookname是QueryServlet的请求参数,表示图书名,通过该参数来查询图书信息。

现在我们要通过HttpGet和HttpPost类向QueryServlet提交请求信息,并将返回结果显示在TextView组件中。

无论是使用HttpGet,还是使用HttpPost,都必须通过如下3步来访问HTTP资源。

1.创建HttpGet或HttpPost对象,将要请求的URL通过构造方法传入HttpGet或HttpPost对象。

2.使用DefaultHttpClient类的execute方法发送HTTP GET或HTTP POST请求,并返回HttpResponse对象。

3.通过HttpResponse接口的getEntity方法返回响应信息,并进行相应的处理。

如果使用HttpPost方法提交HTTP POST请求,还需要使用HttpPost类的setEntity方法设置请求参数。

本例使用了两个按钮来分别提交HTTP GET和HTTP POST请求,并从EditText组件中获得请求参数(bookname)值,最后将返回结果显示在TextView组件中。两个按钮共用一个onClick事件方法,代码如下:

public void onClick(View view)  

{  

    //  读者需要将本例中的IP换成自己机器的IP  

    String url = "http://192.168.17.81:8080/querybooks/QueryServlet";  

    TextView tvQueryResult = (TextView) findViewById(R.id.tvQueryResult);  

    EditText etBookName = (EditText) findViewById(R.id.etBookName);  

    HttpResponse httpResponse = null;  

    try  

    {  

        switch (view.getId())  

        {  

            //  提交HTTP GET请求  

            case R.id.btnGetQuery:  

                //  向url添加请求参数  

                url += "?bookname=" + etBookName.getText().toString();  

                //  第1步:创建HttpGet对象  

                HttpGet httpGet = new HttpGet(url);  

                //  第2步:使用execute方法发送HTTP 
GET请求,并返回HttpResponse对象  

                httpResponse = new DefaultHttpClient().execute(httpGet);  

                //  判断请求响应状态码,状态码为200表
示服务端成功响应了客户端的请求  

                if (httpResponse.getStatusLine().
getStatusCode() == 200)  

                {  

                    //  第3步:使用getEntity方法获得返回结果  

                    String result = EntityUtils.
toString(httpResponse.getEntity());  

                    //  去掉返回结果中的"\r"字符,
否则会在结果字符串后面显示一个小方格  

                    tvQueryResult.setText(result.replaceAll("\r", ""));  

                }  

                break;  

            //  提交HTTP POST请求  

            case R.id.btnPostQuery:  

                //  第1步:创建HttpPost对象  

                HttpPost httpPost = new HttpPost(url);  

                //  设置HTTP POST请求参数必须用NameValuePair对象  

                List<NameValuePair> params = new 
ArrayList<NameValuePair>();  

                params.add(new BasicNameValuePair
("bookname", etBookName.getText(). toString()));  

                //  设置HTTP POST请求参数  

                httpPost.setEntity(new 
UrlEncodedFormEntity(params, HTTP.UTF_8));  

                //  第2步:使用execute方法发送HTTP 
POST请求,并返回HttpResponse对象  

                httpResponse = new DefaultHttpClient().
execute(httpPost);  

                if (httpResponse.getStatusLine().
getStatusCode() == 200)  

                {  

                    //  第3步:使用getEntity方法获得返回结果  

                    String result = EntityUtils.toString
(httpResponse.getEntity());  

                    //  去掉返回结果中的"\r"字符,
否则会在结果字符串后面显示一个小方格  

                    tvQueryResult.setText(result.replaceAll("\r", ""));  

                }  

                break;  

        }  

    }  

    catch (Exception e)  

    {  

        tvQueryResult.setText(e.getMessage());  

    }  

HttpClient是一个很方便进行Http连接操作的工具包,用它可以设置代理和模拟浏览器下载网页,对于爬虫程序来说,是特别好的工具。
它提供的 HTTP 的访问主要是通过 GetMethod 类和 PostMethod 类来实现的,他们分别对应了 HTTP Get 请求与 Http Post 请求.
下面我分别给出两种访问方式的代码及注意事项:

get方式:

   //生成 HttpClinet 对象
          HttpClient client = new DefaultHttpClient();   
     //生成 GetMethod 对象
     HttpGet httpGet = new HttpGetpsURL );
     //设置请求头,这里很关键,细节在注意事项中描述
     httpGet.setHeader("user-agent", "Mozilla/5.0 (Windows NT 5.1; rv:8.0.1) Gecko/20100101") ;
     httpGet.setHeader("accept", "*/*") ;
     httpGet.setHeader("accept-language", "zh-CN") ;
     httpGet.setHeader("accept-encoding", "utf-8, deflate") ;
    
     StringBuffer strBuf = new StringBuffer();    
  try {
      //执行 HTTP GET 请求,获取响应
      HttpResponse response = client.execute(httpGet);
      //根据响应码判断是否正确获取响应
      if (HttpStatus.SC_OK == response.getStatusLine().getStatusCode()) {
          //若正确获得响应则对内容进行处理
          HttpEntity entity = response.getEntity();    
          if (entity != null) {    
              BufferedReader reader = new BufferedReader(    
                  new InputStreamReader(entity.getContent(), "UTF-8"));    
              String line = null;    
              if (entity.getContentLength() > 0) {    
                  strBuf = new StringBuffer((int) entity.getContentLength());    
                  while ((line = reader.readLine()) != null) {    
                      strBuf.append(line);    
                  }    
              }    
          }    
   //释放连接
          if (entity != null) {    
              EntityUtils.consume(entity);    
          }    
      } 
  } catch (ClientProtocolException e) {
   
   e.printStackTrace();
  } catch (IOException e) {
   
   e.printStackTrace();
  }    

 

post方式:
 
 //存放参数
 List<NameValuePair> nvps= new ArrayList<NameValuePair>();

 nvps.add(new BasicNameValuePair("txtUserName", UAERNAME));
 nvps.add(new BasicNameValuePair("txtPassword", PASSWORD));
 nvps.add(new BasicNameValuePair("ImageButton1.x", "17"));
 nvps.add(new BasicNameValuePair("ImageButton1.y", "10"));
 nvps.add(new BasicNameValuePair("__VIEWSTATE", FLAG));
 //生成 PostMethod 对象
 HttpPost httpPostLogin = new HttpPost(URL)
 //添加参数
 httpPostLogin.setEntity(new UrlEncodedFormEntity(nvps, HTTP.UTF_8));
 //以下为执行请求,获取响应,并对响应进行处理,与get方式类似
 httpResponseLogin = getHttpClientInstance().execute(httpPostLogin);

 status=httpResponseLogin.getStatusLine().getStatusCode();
   
 if (status == 302||status==HttpStatus.SC_OK) {

  Header[] locationHeader = httpResponseLogin.getHeaders("location");

  if (locationHeader != null) {

   HttpEntity httpEntityLogin = httpResponseLogin.getEntity();
     
   if (httpEntityLogin != null) {

    EntityUtils.consume(httpEntityLogin);
      
     }
    }

   }
   
  } catch (Exception e1) {
   // TODO Auto-generated catch block
   e1.printStackTrace();
  }


以下为我在写爬虫程序的时候遇到的问题及解决方案,权作注意事项吧:

1、关于get方式设置请求头的问题,最令人头疼:
   1)、上面实例中列出的四种请求头一般情况下已够用,无需添加。
   2)、要特别注意accept-encoding的值,有两种:gzip, deflate 和utf-8, deflate。
 gzip是经过压缩的大量数据的,一般不常用;
 utf-8符合一般使用规律,具体可以两种都尝试一下,或者干脆不加该请求头。
2、无论哪种方式,接受后一定要使用
  EntityUtils.consume(entity);释放连接


你可能感兴趣的:(android 网络编程 HttpGet类和HttpPost类使用详解)