• 网络相关系列之中的一个:Android中使用HttpClient发送HTTP请求


    一、HTTP协议初探:

    HTTP(Hypertext Transfer Protocol)中文 “超文本传输协议”,是一种为分布式,合作式,多媒体信息系统服务,面向应用层的协议,是Internet上眼下使用最广泛的应用层协议。它基于传输层的TCP协议进行通信,HTTP协议是通用的、无状态协议。

    这几个名词有一种通俗的解释:

    • 通讯协议:两方对话的标准
    • 通用的:用了都说好,谁用谁知道
    • 无状态的:翻脸不认人
    • 超文本:除了文本,还能够是音频、视频

    HTTP协议与Android开发之间的关系:


    HTTP协议的学习重点:

    • Http协议基础概念、
    • 请求响应模型、
    • 提交请求的不同方法、
    • 响应状态推断、
    • 获取响应以及解析响应、
    • 数据下载的实现方法、
    • 数据上传的实现方法、
    • 请求头具体内容、
    • 响应头具体内容等
    二、http协议概念:
    1、http协议定义:
    WWW是以Internet作为传输媒介的一个应用系统。WWW网上主要的传输单位是Web网页。

    WWW的工作是基于客户机/server计算模型,由Web浏览器和Webserver构成,两者之间採用超文本传输协议HTTP进行通信。

    这里我还专门查了一下:
    首先必须强调的是C/S和B/S并没有本质的差别:B/S是基于特定通信协议(HTTP)的C/S架构,也就是说B/S包括在C/S中,是特殊的C/S架构。

    之所以在C/S架构上提出B/S架构,是为了满足瘦client、一体化client的须要,终于目的节约client更新、维护等的成本,及广域资源的共享。
    (1)B/S属于C/S,浏览器仅仅是特殊的client。
    (2)C/S能够使用不论什么通信协议,而B/S这个特殊的C/S架构规定必须实现HTTP协议
    (3)浏览器是一个通用client,本质上开发浏览器。还是实现一个C/S系统。

    HTTP协议时基于TCP/IP协议之上的协议,是Web浏览器和Webserver之间的应用层的协议,是通用的、无状态的面向对象的协议。 
    假设要实现网络互联我们要思考两个须要解决的技术问题:
    • 第一:浏览器和server是通过什么来连接的。
    • 第二:这样的连接方式是怎么实现的。
    通过Internet去发送到server其中。而Internet内部能够通过三种方式来实现发送信息和数据:

    • 第一种:HTTP协议。也是在工作中最经常使用的。是建立在TCP/IP基础上实现的。
    • 另外一种:FTP协议
    • 第三种:TCP/IP协议,它也是最底层的协议族。其他的方式必须是要通过它,可是要想实现这样的协议必需要实现socket编程,这样的方法是用来上传一些比較大的文件,视频,进行断点续传的操作。

    2、client连接server实现内部的原理例如以下:
    分析上图,过程例如以下:
    • 第一步:在浏览器client中得到用户输入的内容。 
    • 第二步:浏览器得到这个网址之后。内部会将这个域名发送到DNS上,进行域名解析。得到它的IP之后就会链接到指定的server上,假如server的地址是:221.104.13.32:80。从浏览器到serverport它使用到最底层的TCP/IP协议。

       

    • 第三步:实现TCP/IP协议用Socket来完毕。使用了Socket的套接字。 
    • 第四步:server端的80port监听client的链接,这样client到server就链接上了。
    • server接收到这些内容之后。并依照这些请求的路径找到相应的页面,进一步找到相应的网页内容,返回给client。
    通俗一点讲,用户在浏览器输入网址,通过http协议发出去,网址经过DNS域名解析。解析成指定的ip地址,并在80port上监听用户的请求。server监听到请求之后。会以三种方式返回给client:HTML、XML、JASON。
    HTTP返回请求数据的三种方式:
    • 1、以HTML代码内容返回。 
    • 2、以XML字符串的形式返回,在android开发中这样的形式返回数据比較多。 
    • 3、以JSON对象形式返回,在网络流量上考虑JSON要比XML方式要好一些,便于解析。
    在Android其中,一般使用xml和Json数据解析。


    三、使用HTTP协议訪问网络:

    Android中的WebView控件已经在后台帮我们处理好了发送HTTP请求、接收服务响应、解析返回数据,以及终于的页面展示这几步工作,只是因为它封装得太好了,反而不能直观地看出HTTP协议是怎样工作的。因此接下来我们通过手动发送HTTP请求的方式。来更加深入的了解这一过程。

    在Android上发送HTTP请求的方式一般有两种:HttpURLConnectionHttpClient

    我们先来学习HttpClient。


    四、HttpCient:

    HttpClient是Apache开源组织提供的HTTP网络訪问接口(一个开源的项目)。从名字上就能够看出。它是一个简单的HTTPclient(并非浏览器)。能够发送HTTP请求,接受HTTP响应。可是不会缓存server的响应。不能运行HTTP页面中签入嵌入的JS代码自然也不会对页面内容进行不论什么解析、处理,这些都是须要开发者来完毕的。

    如今Android已经成功集成了HttpClient,所以开发者在Android项目中能够直接使用HttpClient来向Web网站提交请求以及接受响应,假设使用其它的Java项目,须要引入进对应的Jar包。HttpClient能够在官网上下载。

    官网链接:http://hc.apache.org/downloads.cgi

    HttpClient事实上是一个interface类型,HttpClient封装了对象须要运行的Http请求、身份验证、连接管理和其他特性。

    既然HttpClient是一个接口,因此无法创建它的实例。从文档上看。HttpClient有三个已知的实现类各自是:AbstractHttpClient, AndroidHttpClient, DefaultHttpClient,会发现有一个专门为Android应用准备的实现类AndroidHttpClient,当然使用常规的DefaultHttpClient也能够实现功能。

    从两个类包全部在位置就能够看出差别,AndroidHttpClient定义在android.net.http.AndroidHttpClient包下,属于Android原生的http訪问。而DefaultHttpClient定义在org.apache.http.impl.client.DefaultHttpClient包下,属于对apche项目的支持。

    而AndroidHttpClient没有公开的构造函数,仅仅能通过静态方法newInstance()方法来获得AndroidHttpClient对象。


    简单来说,用HttpClient发送请求、接收响应都非常easy,仅仅须要五大步骤就可以:(要牢记)

    • 创建代表client的HttpClient对象。
    • 创建代表请求的对象,假设须要发送GET请求,则创建HttpGet对象,假设须要发送POST请求。则创建HttpPost对象。

      注:对于发送请求的參数,GET和POST使用的方式不同。GET方式能够使用拼接字符串的方式。把參数拼接在URL结尾。POST方式须要使用setEntity(HttpEntity entity)方法来设置请求參数。

    • 调用HttpClient对象的execute(HttpUriRequest request)发送请求,运行该方法后将获得server返回的HttpResponse对象。server发还给我们的数据就在这个HttpResponse响应其中。调用HttpResponse的相应方法获取server的响应头、响应内容等。
    • 检查对应状态是否正常。server发给client的相响应,有一个响应码:响应码为200。正常;响应码为404,client错误。响应码为505,server端错误。
    • 获得响应对象其中的数据

     

    五、DefaultHttpClient:

    依据上面的五大步骤,我们就拿DefaultHttpClient举例来訪问网络。

    注意这里有一条原则:在主线程中不能訪问网络(在android4.0之后的增加的概念)。

    一个demo:点击button,获取百度首页的文本内容

    新建project文件m04_http01。

    完整版代码例如以下:

    首先是布局文件。尽管比較简单。但还是贴上吧。

    activity_main.xml代码例如以下:

    <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
        xmlns:tools="http://schemas.android.com/tools"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:orientation="vertical"
        tools:context=".MainActivity" >
    
        <Button
            android:id="@+id/button1"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:text="Send Request" />
    
        <ScrollView
            android:layout_width="match_parent"
            android:layout_height="match_parent" >
    
            <TextView
                android:id="@+id/TextView1"
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:text="@string/hello_world" />
        </ScrollView>
    
    </LinearLayout>

    布局文件里,我们用一个ScrollView来包裹TextView。借助ScrollView控件的话。就能够同意我们一滚动的形式查看屏幕外i的那部分内容

    MainActivity.java的代码例如以下:(凝视比較具体)

     package com.example.m04_http01;
      
     import org.apache.http.HttpEntity;
     import org.apache.http.HttpResponse;
     import org.apache.http.client.HttpClient;
     import org.apache.http.client.methods.HttpGet;
     import org.apache.http.impl.client.DefaultHttpClient;
     import org.apache.http.util.EntityUtils;
     import android.app.Activity;
     import android.os.Bundle;
     import android.os.Handler;
     import android.os.Message;
     import android.view.View;
     import android.view.View.OnClickListener;
     import android.widget.Button;
     import android.widget.TextView;
     
     public class MainActivity extends Activity {
     
         public static final int SHOW_RESPONSE = 0;
         
         private Button button_sendRequest;
         private TextView textView_response;
         
         //新建Handler的对象,在这里接收Message。然后更新TextView控件的内容
         private Handler handler = new Handler() {
     
             @Override
             public void handleMessage(Message msg) {
                 super.handleMessage(msg);
                 switch (msg.what) {
                 case SHOW_RESPONSE:
                     String response = (String) msg.obj;
                     textView_response.setText(response);
                     break;
     
                 default:
                     break;
                 }            
             }
     
         };
         
         @Override
         protected void onCreate(Bundle savedInstanceState) {
             super.onCreate(savedInstanceState);
             setContentView(R.layout.activity_main);
             textView_response = (TextView)findViewById(R.id.TextView1);
             button_sendRequest = (Button)findViewById(R.id.button1);
             
             button_sendRequest.setOnClickListener(new OnClickListener() {
                 
                 //点击按钮时。运行sendRequestWithHttpClient()方法里面的线程
                 @Override
                 public void onClick(View v) {
                     // TODO Auto-generated method stub
                     sendRequestWithHttpClient();
                 }
             });
         }
     
         //方法:发送网络请求,获取百度首页的数据。

    在里面开启线程 private void sendRequestWithHttpClient() { new Thread(new Runnable() { @Override public void run() { //用HttpClient发送请求,分为五步 //第一步:创建HttpClient对象 HttpClient httpCient = new DefaultHttpClient(); //第二步:创建代表请求的对象,參数是訪问的server地址 HttpGet httpGet = new HttpGet("http://www.baidu.com"); try { //第三步:运行请求,获取server发还的响应对象 HttpResponse httpResponse = httpCient.execute(httpGet); //第四步:检查响应的状态是否正常:检查状态码的值是200表示正常 if (httpResponse.getStatusLine().getStatusCode() == 200) { //第五步:从对应对象其中取出数据。放到entity其中 HttpEntity entity = httpResponse.getEntity(); String response = EntityUtils.toString(entity,"utf-8");//将entity其中的数据转换为字符串 //在子线程中将Message对象发出去 Message message = new Message(); message.what = SHOW_RESPONSE; message.obj = response.toString(); handler.sendMessage(message); } } catch (Exception e) { // TODO Auto-generated catch block e.printStackTrace(); } } }).start();//这个start()方法不要忘记了 } }

    最后要记得在清单文件里声明訪问网络的权限:
    <uses-sdk
    
    android:minSdkVersion="8"
    
    android:targetSdkVersion="16" />
    
    <uses-permission android:name="android.permission.INTERNET"/>
    程序执行后,点击button,显示结果例如以下:
    server返回给我们的就是这样的HTML代码,仅仅是通常情况下浏览器都会将这些代码解析成美丽的网页后再展示出来。

    关于http协议的学习,推荐两个链接:

    http://www.cnblogs.com/TankXiao/archive/2012/02/13/2342672.html

    http://blog.csdn.net/gueter/article/details/1524447



  • 相关阅读:
    HTML5表单
    jQuery Mobile组件
    HTML5新增加的功能
    jQuery Mobile基础
    【android】两个按钮的宽度各占屏幕的一半
    AndroidUI--SlidingMenu使用例子
    android之PackageManager简介
    AlarmManager类的应用
    AlarmManager类的应用(实现闹钟功能)
    laravel 控制器内使用切换数据库
  • 原文地址:https://www.cnblogs.com/cxchanpin/p/7258183.html
Copyright © 2020-2023  润新知