网络相关系列之中的一个:Android中使用HttpClient发送HTTP请求
一、HTTP协议初探:
HTTP(Hypertext Transfer Protocol)中文 “超文本传输协议”,是一种为分布式,合作式,多媒体信息系统服务,面向应用层的协议,是Internet上眼下使用最广泛的应用层协议。它基于传输层的TCP协议进行通信,HTTP协议是通用的、无状态的协议。
这几个名词有一种通俗的解释:
- 通讯协议:两方对话的标准
- 通用的:用了都说好,谁用谁知道
- 无状态的:翻脸不认人
- 超文本:除了文本,还能够是音频、视频
HTTP协议与Android开发之间的关系:
watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQv/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/Center" alt="">
HTTP协议的学习重点:
- Http协议基础概念、
- 请求响应模型、
- 提交请求的不同方法、
- 响应状态推断、
- 获取响应以及解析响应、
- 数据下载的实现方法、
- 数据上传的实现方法、
- 请求头具体内容、
- 响应头具体内容等
1、http协议定义:
WWW的工作是基于客户机/server计算模型,由Web浏览器和Webserver构成,两者之间採用超文本传输协议HTTP进行通信。
- 第一:浏览器和server是通过什么来连接的。
- 第二:这样的连接方式是怎么实现的。
- 第一种: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。
- 1、以HTML代码内容返回。
- 2、以XML字符串的形式返回,在android开发中这样的形式返回数据比較多。
- 3、以JSON对象形式返回,在网络流量上考虑JSON要比XML方式要好一些,便于解析。
在Android其中,一般使用xml和Json数据解析。
三、使用HTTP协议訪问网络:
Android中的WebView控件已经在后台帮我们处理好了发送HTTP请求、接收服务响应、解析返回数据,以及终于的页面展示这几步工作,只是因为它封装得太好了,反而不能直观地看出HTTP协议是怎样工作的。因此接下来我们通过手动发送HTTP请求的方式。来更加深入的了解这一过程。
在Android上发送HTTP请求的方式一般有两种:HttpURLConnection和HttpClient。
我们先来学习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,显示结果例如以下:
关于http协议的学习,推荐两个链接:
http://www.cnblogs.com/TankXiao/archive/2012/02/13/2342672.html
网络相关系列之中的一个:Android中使用HttpClient发送HTTP请求的更多相关文章
- Android中使用HttpClient发送Get请求
这里要指定编码,不然服务器接收到的会是乱码的.
- 网络相关系列之三:通过GET和POST方法发送数据
写在最前面:年少的安逸舒适在随着年龄的到来和现实生活的压迫总有一天会全数归还(事实上就是<无间道>中那句:"出来混,迟早要还的!") so fighting. 一.GE ...
- android中Post方式发送HTTP请求
Post方式比Get方式要复杂一点,因为该方式需要将请求的参数放在http请求的正文中,所以需要构造请求体. 步骤: 1.构造URL URL url = new URL(PATH); 2.设置连接 H ...
- Android系列之网络(三)----使用HttpClient发送HTTP请求(分别通过GET和POST方法发送数据)
[声明] 欢迎转载,但请保留文章原始出处→_→ 生命壹号:http://www.cnblogs.com/smyhvae/ 文章来源:http://www.cnblogs.com/smyhvae/p/ ...
- Android系列之网络(一)----使用HttpClient发送HTTP请求(通过get方法获取数据)
[声明] 欢迎转载,但请保留文章原始出处→_→ 生命壹号:http://www.cnblogs.com/smyhvae/ 文章来源:http://www.cnblogs.com/smyhvae/p/4 ...
- hdu1465不easy系列之中的一个(错排)
版权声明:本文为博主原创文章,未经博主同意不得转载. vasttian https://blog.csdn.net/u012860063/article/details/37512659 转载请注明出 ...
- Android笔记---使用HttpClient发送POST和GET请求
在Android上发送 HTTP 请求的方式一般有两种, HttpURLConnection 和 HttpClient,关于HttpURLConnection的使用方法能够參考HTTP之利用HttpU ...
- 在android用Get方式发送http请求
烦人的日子终于过去啦,终于又可以写博客啦,对自己的android学习做个总结,方便以后查看...... 一.在android用Get方式发送http请求,使用的是java标准类,也比较简单. 主要分以 ...
- Java发布一个简单 webservice应用 并发送SOAP请求
一.创建并发布一个简单的webservice应用 1.webservice 代码: package com.ls.demo; import javax.jws.WebMethod; import ja ...
随机推荐
- RHN Classic and Red Hat Subscription Management
What's the difference between RHN Classic and Red Hat Subscription Management? Introduction With the ...
- HTTP基础--cookie机制和session机制
1.介绍cookie和session的区别,怎么获取与使用?(这个问题比较开放,可深可浅,现在将这里涉及的主要问题总计如下答案) 答: 一.cookie机制和session机制的区别 cookie机制 ...
- getElementsByName
name属性,name属性是input标签的内建属性,早期浏览器的getElementsByName方法是为了方便的获取用户的输入.由于name只是input的内建属性,其它标签没有,所以getEle ...
- 在本地文件当中package.json的作用
除了常见的指定包的相关依赖,一些包的相关信息之外 main: 它是用来指定当前包的入口文件,容易让人忽视的一点是它不仅仅在发布的npm包当中有用,在你的业务代码当中也具有一样的作用. 例如,我需要一个 ...
- 行为型设计模式之状态模式(State)
结构 意图 允许一个对象在其内部状态改变时改变它的行为.对象看起来似乎修改了它的类. 适用性 一个对象的行为取决于它的状态, 并且它必须在运行时刻根据状态改变它的行为. 一个操作中含有庞大的多分支的条 ...
- [LeetCode] Sqrt(x) 二分搜索
Implement int sqrt(int x). Compute and return the square root of x. Hide Tags Math Binary Search ...
- 使用matlab判断男声与女声
(转自) http://wenku.baidu.com/view/1d55480fbe1e650e52ea99a3.html %filename:manwoman.m %different man f ...
- Appium+python自动化20-查看iOS上app元素属性【转载】
前言 学UI自动化首先就是定位页面元素,玩过android版的appium小伙伴应该都知道,appium的windows版自带的Inspector可以定位app上的元素Mac版的appium1.6的版 ...
- Android 利用 AsyncTask 异步读取网络图片
1.新建Android工程AsyncLoadPicture 新建布局文件activity_main.xml主界面为一个GridView,还有其子项布局文件gridview_item.xml 2.功能主 ...
- Python与数据结构[2] -> 队列/Queue[0] -> 数组队列的 Python 实现
队列 / Queue 数组队列 数组队列是队列基于数组的一种实现,其实现类似于数组栈,是一种FIFO的线性数据结构. Queue: <--| 1 | 2 | 3 | 4 | 5 |<-- ...