Http与Android网络请求的几种协议

HTTP(HyperText Transfer Protocol)是一套计算机通过网络进行通信的规则。计算机专家设计出HTTP,使HTTP客户(如Web浏览器)能够从HTTP服务器(Web服务器)请求信息和服务,HTTP目前协议的版本是1.1.HTTP是一种无状态的协议,无状态是指Web浏览器和Web服务器之间不需要建立持久的连接,这意味着当一个客户端向服务器端发出请求,然后Web服务器返回响应(response),连接就被关闭了,在服务器端不保留连接的有关信息.HTTP遵循请求(Request)/应答(Response)模型。Web浏览器向Web服务器发送请求,Web服务器处理请求并返回适当的应答。所有HTTP连接都被构造成一套请求和应答。
HTTP使用内容类型,是指Web服务器向Web浏览器返回的文件都有与之相关的类型。所有这些类型在MIME Internet邮件协议上模型化,即Web服务器告诉Web浏览器该文件所具有的种类,是HTML文档、GIF格式图像、声音文件还是独立的应用程序。大多数Web浏览器都拥有一系列的可配置的辅助应用程序,它们告诉浏览器应该如何处理Web服务器发送过来的各种内容类型。
HTTP通信机制是在一次完整的HTTP通信过程中,Web浏览器与Web服务器之间将完成下列7个步骤:
(1)     建立TCP连接
在HTTP工作开始之前,Web浏览器首先要通过网络与Web服务器建立连接,该连接是通过TCP来完成的,该协议与IP协议共同构建Internet,即著名的TCP/IP协议族,因此Internet又被称作是TCP/IP网络。HTTP是比TCP更高层次的应用层协议,根据规则,只有低层协议建立之后才能,才能进行更层协议的连接,因此,首先要建立TCP连接,一般TCP连接的端口号是80
(2)     Web浏览器向Web服务器发送请求命令
一旦建立了TCP连接,Web浏览器就会向Web服务器发送请求命令
例如:GET/sample/hello.jsp HTTP/1.1
(3)     Web浏览器发送请求头信息
浏览器发送其请求命令之后,还要以头信息的形式向Web服务器发送一些别的信息,之后浏览器发送了一空白行来通知服务器,它已经结束了该头信息的发送。
(4)     Web服务器应答
客户机向服务器发出请求后,服务器会客户机回送应答,
HTTP/1.1 200 OK
应答的第一部分是协议的版本号和应答状态码
(5)     Web服务器发送应答头信息
正如客户端会随同请求发送关于自身的信息一样,服务器也会随同应答向用户发送关于它自己的数据及被请求的文档。
(6)     Web服务器向浏览器发送数据
Web服务器向浏览器发送头信息后,它会发送一个空白行来表示头信息的发送到此为结束,接着,它就以Content-Type应答头信息所描述的格式发送用户所请求的实际数据
(7)     Web服务器关闭TCP连接
一般情况下,一旦Web服务器向浏览器发送了请求数据,它就要关闭TCP连接,然后如果浏览器或者服务器在其头信息加入了这行代码
Connection:keep-alive
TCP连接在发送后将仍然保持打开状态,于是,浏览器可以继续通过相同的连接发送请求。保持连接节省了为每个请求建立新连接所需的时间,还节约了网络带宽。
    
HTTP请求格式
当浏览器向Web服务器发出请求时,它向服务器传递了一个数据块,也就是请求信息,HTTP请求信息由3部分组成:
l    请求方法URI协议/版本
l    请求头(Request Header)
l    请求正文
下面是一个HTTP请求的例子:
GET/sample.jspHTTP/1.1
Accept:image/gif.image/jpeg,*/*
Accept-Language:zh-cn
Connection:Keep-Alive
Host:localhost
User-Agent:Mozila/4.0(compatible;MSIE5.01;Window NT5.0)
Accept-Encoding:gzip,deflate
 
username=jinqiao&password=1234
 
(1)        请求方法URI协议/版本
请求的第一行是“方法URL议/版本”:GET/sample.jsp HTTP/1.1
以上代码中“GET”代表请求方法,“/sample.jsp”表示URI,“HTTP/1.1代表协议和协议的版本。
根据HTTP标准,HTTP请求可以使用多种请求方法。例如:HTTP1.1支持7种请求方法:GET、POST、HEAD、OPTIONS、PUT、DELETE和TARCE。在Internet应用中,最常用的方法是GET和POST。
URL完整地指定了要访问的网络资源,通常只要给出相对于服务器的根目录的相对目录即可,因此总是以“/”开头,最后,协议版本声明了通信过程中使用HTTP的版本。
(2) 请求头(Request Header)
请求头包含许多有关的客户端环境和请求正文的有用信息。例如,请求头可以声明浏览器所用的语言,请求正文的长度等。
Accept:image/gif.image/jpeg.*/*
Accept-Language:zh-cn
Connection:Keep-Alive
Host:localhost
User-Agent:Mozila/4.0(compatible:MSIE5.01:Windows NT5.0)
Accept-Encoding:gzip,deflate.
(3) 请求正文
请求头和请求正文之间是一个空行,这个行非常重要,它表示请求头已经结束,接下来的是请求正文。请求正文中可以包含客户提交的查询字符串信息:
username=jinqiao&password=1234
在以上的例子的HTTP请求中,请求的正文只有一行内容。当然,在实际应用中,HTTP请求正文可以包含更多的内容。
HTTP请求方法我这里只讨论GET方法与POST方法
l          GET方法
GET方法是默认的HTTP请求方法,我们日常用GET方法来提交表单数据,然而用GET方法提交的表单数据只经过了简单的编码,同时它将作为URL的一部分向Web服务器发送,因此,如果使用GET方法来提交表单数据就存在着安全隐患上。例如
从上面的URL请求中,很容易就可以辩认出表单提交的内容。(?之后的内容)另外由于GET方法提交的数据是作为URL请求的一部分所以提交的数据量不能太大
l          POST方法
POST方法是GET方法的一个替代方法,它主要是向Web服务器提交表单数据,尤其是大批量的数据。POST方法克服了GET方法的一些缺点。通过POST方法提交表单数据时,数据不是作为URL请求的一部分而是作为标准数据传送给Web服务器,这就克服了GET方法中的信息无法保密和数据量太小的缺点。因此,出于安全的考虑以及对用户隐私的尊重,通常表单提交时采用POST方法。
  从编程的角度来讲,如果用户通过GET方法提交数据,则数据存放在QUERY_STRING环境变量中,而POST方法提交的数据则可以从标准输入流中获取。
HTTP应答与HTTP请求相似,HTTP响应也由3个部分构成,分别是:
l 协议状态版本代码描述
l 响应头(Response Header)
l 响应正文
下面是一个HTTP响应的例子:
HTTP/1.1 200 OK
Server:Apache Tomcat/5.0.12
Date:Mon,6Oct2003 13:23:42 GMT
Content-Length:112
 
<html>
<head>
<title>HTTP响应示例<title>
</head>
<body>
Hello HTTP!
</body>
</html>
协议状态代码描述HTTP响应的第一行类似于HTTP请求的第一行,它表示通信所用的协议是HTTP1.1服务器已经成功的处理了客户端发出的请求(200表示成功):
HTTP/1.1 200 OK
响应头(Response Header)响应头也和请求头一样包含许多有用的信息,例如服务器类型、日期时间、内容类型和长度等:
   Server:Apache Tomcat/5.0.12
Date:Mon,6Oct2003 13:13:33 GMT
Content-Type:text/html
Last-Moified:Mon,6 Oct 2003 13:23:42 GMT
Content-Length:112
 响应正文响应正文就是服务器返回的HTML页面:
  <html>
<head>
<title>HTTP响应示例<title>
</head>
<body>
Hello HTTP!
</body>
</html>
响应头和正文之间也必须用空行分隔 。  
l         HTTP应答码
   HTTP应答码也称为状态码,它反映了Web服务器处理HTTP请求状态。HTTP应答码由3位数字构成,其中首位数字定义了应答码的类型:
   1XX-信息类(Information),表示收到Web浏览器请求,正在进一步的处理中
   2XX-成功类(Successful),表示用户请求被正确接收,理解和处理例如:200 OK
      3XX-重定向类(Redirection),表示请求没有成功,客户必须采取进一步的动作。
      4XX-客户端错误(Client Error),表示客户端提交的请求有错误 例如:404 NOT
                                    Found,意味着请求中所引用的文档不存在。
      5XX-服务器错误(Server Error)表示服务器不能完成对请求的处理:如 500
      对于我们Web开发人员来说掌握HTTP应答码有助于提高Web应用程序调试的效率和准确性。
 
安全连接
Web应用最常见的用途之一是电子商务,可以利用Web服务器端程序使人们能够网络购物,需要指出一点是,缺省情况下,通过Internet发送信息是不安全的,如果某人碰巧截获了你发给朋友的一则消息,他就能打开它,假想在里面有你的信用卡号码,这会有多么糟糕,幸运的是,很多Web服务器以及Web浏览器都有创立安全连接的能力,这样它们就可以安全的通信了。
通过Internet提供安全连接最常见的标准是安全套接层(Secure Sockets layer,SSl)协议。SSL协议是一个应用层协议(和HTTP一样),用于安全方式在Web上交换数据,SSL使用公开密钥编码系统。从本质讲,这意味着业务中每一方都拥有一个公开的和一个私有的密钥。当一方使用另一方公开密钥进行编码时,只有拥有匹配密钥的人才能对其解码。简单来讲,公开密钥编码提供了一种用于在两方之间交换数据的安全方法,SSL连接建立之后,客户和服务器都交换公开密钥,并在进行业务联系之前进行验证,一旦双方的密钥都通过验证,就可以安全地交换数据。
  • GET
    通过请求URI得到资源
  • POST,
    用于添加新的内容
  • PUT
    用于修改某个内容
  • DELETE,
    删除某个内容
  • CONNECT,
    用于代理进行传输,如使用SSL
  • OPTIONS
    询问可以执行哪些方法
  • PATCH,
    部分文档更改
  • PROPFIND, (wedav)
    查看属性
  • PROPPATCH, (wedav)
    设置属性
  • MKCOL, (wedav)
    创建集合(文件夹)
  • COPY, (wedav)
    拷贝
  • MOVE, (wedav)
    移动
  • LOCK, (wedav)
    加锁
  • UNLOCK (wedav)
    解锁
  • TRACE
    用于远程诊断服务器
  • HEAD
    类似于GET, 但是不返回body信息,用于检查对象是否存在,以及得到对象的元数据
apache2中,可使用Limit,LimitExcept进行访问控制的 方法包括: GETPOSTPUTDELETECONNECT, OPTIONSPATCHPROPFINDPROPPATCHMKCOLCOPYMOVELOCK, 和  UNLOCK.
其中, HEAD GET POST OPTIONS PROPFIND是和读取相关的 方法,MKCOL PUT DELETE LOCK UNLOCK COPY MOVE PROPPATCH是和修改相关的 方法.

Android应用经常会和服务器端交互,这就需要手机客户端发送网络请求,下面介绍四种常用网络请求方式,我这边是通过Android单元测试来完成这四种方法的,还不清楚Android的单元测试的同学们请看Android开发技巧总结中的Android单元测试的步骤一文。

Java.net包中的HttpURLConnection类

Get方式:

[java]  view plain  copy
  1. // Get方式请求  
  2. public static void requestByGet() throws Exception {  
  3.     String path = "https://reg.163.com/logins.jsp?id=helloworld&pwd=android";  
  4.     // 新建一个URL对象  
  5.     URL url = new URL(path);  
  6.     // 打开一个HttpURLConnection连接  
  7.     HttpURLConnection urlConn = (HttpURLConnection) url.openConnection();  
  8.     // 设置连接超时时间  
  9.     urlConn.setConnectTimeout(5 * 1000);  
  10.     // 开始连接  
  11.     urlConn.connect();  
  12.     // 判断请求是否成功  
  13.     if (urlConn.getResponseCode() == HTTP_200) {  
  14.         // 获取返回的数据  
  15.         byte[] data = readStream(urlConn.getInputStream());  
  16.         Log.i(TAG_GET, "Get方式请求成功,返回数据如下:");  
  17.         Log.i(TAG_GET, new String(data, "UTF-8"));  
  18.     } else {  
  19.         Log.i(TAG_GET, "Get方式请求失败");  
  20.     }  
  21.     // 关闭连接  
  22.     urlConn.disconnect();  
  23. }  

Post方式:

[java]  view plain  copy
  1. // Post方式请求  
  2. public static void requestByPost() throws Throwable {  
  3.     String path = "https://reg.163.com/logins.jsp";  
  4.     // 请求的参数转换为byte数组  
  5.     String params = "id=" + URLEncoder.encode("helloworld""UTF-8")  
  6.             + "&pwd=" + URLEncoder.encode("android""UTF-8");  
  7.     byte[] postData = params.getBytes();  
  8.     // 新建一个URL对象  
  9.     URL url = new URL(path);  
  10.     // 打开一个HttpURLConnection连接  
  11.     HttpURLConnection urlConn = (HttpURLConnection) url.openConnection();  
  12.     // 设置连接超时时间  
  13.     urlConn.setConnectTimeout(5 * 1000);  
  14.     // Post请求必须设置允许输出  
  15.     urlConn.setDoOutput(true);  
  16.     // Post请求不能使用缓存  
  17.     urlConn.setUseCaches(false);  
  18.     // 设置为Post请求  
  19.     urlConn.setRequestMethod("POST");  
  20.     urlConn.setInstanceFollowRedirects(true);  
  21.     // 配置请求Content-Type  
  22.     urlConn.setRequestProperty("Content-Type",  
  23.             "application/x-www-form-urlencode");  
  24.     // 开始连接  
  25.     urlConn.connect();  
  26.     // 发送请求参数  
  27.     DataOutputStream dos = new DataOutputStream(urlConn.getOutputStream());  
  28.     dos.write(postData);  
  29.     dos.flush();  
  30.     dos.close();  
  31.     // 判断请求是否成功  
  32.     if (urlConn.getResponseCode() == HTTP_200) {  
  33.         // 获取返回的数据  
  34.         byte[] data = readStream(urlConn.getInputStream());  
  35.         Log.i(TAG_POST, "Post请求方式成功,返回数据如下:");  
  36.         Log.i(TAG_POST, new String(data, "UTF-8"));  
  37.     } else {  
  38.         Log.i(TAG_POST, "Post方式请求失败");  
  39.     }  
  40. }  
  

org.apache.http包中的HttpGet和HttpPost类

Get方式:

[java]  view plain  copy
  1. // HttpGet方式请求  
  2. public static void requestByHttpGet() throws Exception {  
  3.     String path = "https://reg.163.com/logins.jsp?id=helloworld&pwd=android";  
  4.     // 新建HttpGet对象  
  5.     HttpGet httpGet = new HttpGet(path);  
  6.     // 获取HttpClient对象  
  7.     HttpClient httpClient = new DefaultHttpClient();  
  8.     // 获取HttpResponse实例  
  9.     HttpResponse httpResp = httpClient.execute(httpGet);  
  10.     // 判断是够请求成功  
  11.     if (httpResp.getStatusLine().getStatusCode() == HTTP_200) {  
  12.         // 获取返回的数据  
  13.         String result = EntityUtils.toString(httpResp.getEntity(), "UTF-8");  
  14.         Log.i(TAG_HTTPGET, "HttpGet方式请求成功,返回数据如下:");  
  15.         Log.i(TAG_HTTPGET, result);  
  16.     } else {  
  17.         Log.i(TAG_HTTPGET, "HttpGet方式请求失败");  
  18.     }  
  19. }  

Post方式:

[java]  view plain  copy
  1. // HttpPost方式请求  
  2. public static void requestByHttpPost() throws Exception {  
  3.     String path = "https://reg.163.com/logins.jsp";  
  4.     // 新建HttpPost对象  
  5.     HttpPost httpPost = new HttpPost(path);  
  6.     // Post参数  
  7.     List<NameValuePair> params = new ArrayList<NameValuePair>();  
  8.     params.add(new BasicNameValuePair("id""helloworld"));  
  9.     params.add(new BasicNameValuePair("pwd""android"));  
  10.     // 设置字符集  
  11.     HttpEntity entity = new UrlEncodedFormEntity(params, HTTP.UTF_8);  
  12.     // 设置参数实体  
  13.     httpPost.setEntity(entity);  
  14.     // 获取HttpClient对象  
  15.     HttpClient httpClient = new DefaultHttpClient();  
  16.     // 获取HttpResponse实例  
  17.     HttpResponse httpResp = httpClient.execute(httpPost);  
  18.     // 判断是够请求成功  
  19.     if (httpResp.getStatusLine().getStatusCode() == HTTP_200) {  
  20.         // 获取返回的数据  
  21.         String result = EntityUtils.toString(httpResp.getEntity(), "UTF-8");  
  22.         Log.i(TAG_HTTPGET, "HttpPost方式请求成功,返回数据如下:");  
  23.         Log.i(TAG_HTTPGET, result);  
  24.     } else {  
  25.         Log.i(TAG_HTTPGET, "HttpPost方式请求失败");  
  26.     }  
  27. }  

HttpUrlConnection

HttpUrlConnection是JDK里提供的联网API,我们知道Android SDK是基于Java的,所以当然优先考虑HttpUrlConnection这种最原始最基本的API,其实大多数开源的联网框架基本上也是基于JDK的HttpUrlConnection进行的封装罢了,掌握HttpUrlConnection需要以下几个步骤:

1将访问的路径转换成URL。

 

[java]  view plain  copy
  1. URL url = new URL(path);  

 

2,通过URL获取连接。

 

[java]  view plain  copy
  1. HttpURLConnection conn = (HttpURLConnection) url.openConnection();  

 

3,设置请求方式。

 

[java]  view plain  copy
  1. conn.setRequestMethod(GET);  

 

4,设置连接超时时间。

 

[java]  view plain  copy
  1. conn.setConnectTimeout(5000);  

 

5,设置请求头的信息。

 

[java]  view plain  copy
  1. conn.setRequestProperty(User-Agent, Mozilla/5.0 (compatible; MSIE 9.0; Windows NT 6.1; Trident/5.0));  

 

6,获取响应码

 

[java]  view plain  copy
  1. int code = conn.getResponseCode();  

 

7,针对不同的响应码,做不同的操作

7.1,请求码200,表明请求成功,获取返回内容的输入流

 

[java]  view plain  copy
  1. InputStream is = conn.getInputStream();  

 

7.2,将输入流转换成字符串信息

 

[java]  view plain  copy
  1. public class StreamTools {  
  2.     /** 
  3.      * 将输入流转换成字符串 
  4.      *  
  5.      * @param is 
  6.      *            从网络获取的输入流 
  7.      * @return 
  8.      */  
  9.     public static String streamToString(InputStream is) {  
  10.         try {  
  11.             ByteArrayOutputStream baos = new ByteArrayOutputStream();  
  12.             byte[] buffer = new byte[1024];  
  13.             int len = 0;  
  14.             while ((len = is.read(buffer)) != -1) {  
  15.                 baos.write(buffer, 0, len);  
  16.             }  
  17.             baos.close();  
  18.             is.close();  
  19.             byte[] byteArray = baos.toByteArray();  
  20.             return new String(byteArray);  
  21.         } catch (Exception e) {  
  22.             Log.e(tag, e.toString());  
  23.             return null;  
  24.         }  
  25.     }  
  26. }  

 

7.3,若返回值400,则是返回网络异常,做出响应的处理。

 

HttpUrlConnection发送GET请求

 

[java]  view plain  copy
  1. /** 
  2.      * 通过HttpUrlConnection发送GET请求 
  3.      *  
  4.      * @param username 
  5.      * @param password 
  6.      * @return 
  7.      */  
  8.     public static String loginByGet(String username, String password) {  
  9.         String path = http://192.168.0.107:8080/WebTest/LoginServerlet?username= + username + &password= + password;  
  10.         try {  
  11.             URL url = new URL(path);  
  12.             HttpURLConnection conn = (HttpURLConnection) url.openConnection();  
  13.             conn.setConnectTimeout(5000);  
  14.             conn.setRequestMethod(GET);  
  15.             int code = conn.getResponseCode();  
  16.             if (code == 200) {  
  17.                 InputStream is = conn.getInputStream(); // 字节流转换成字符串  
  18.                 return StreamTools.streamToString(is);  
  19.             } else {  
  20.                 return 网络访问失败;  
  21.             }  
  22.         } catch (Exception e) {  
  23.             e.printStackTrace();  
  24.             return 网络访问失败;  
  25.         }  
  26.     }  

 

HttpUrlConnection发送POST请求

[java]  view plain  copy
  1. /** 
  2.      * 通过HttpUrlConnection发送POST请求 
  3.      *  
  4.      * @param username 
  5.      * @param password 
  6.      * @return 
  7.      */  
  8.     public static String loginByPost(String username, String password) {  
  9.         String path = http://192.168.0.107:8080/WebTest/LoginServerlet;  
  10.         try {  
  11.             URL url = new URL(path);  
  12.             HttpURLConnection conn = (HttpURLConnection) url.openConnection();  
  13.             conn.setConnectTimeout(5000);  
  14.             conn.setRequestMethod(POST);  
  15.             conn.setRequestProperty(Content-Type, application/x-www-form-urlencoded);  
  16.             String data = username= + username + &password= + password;  
  17.             conn.setRequestProperty(Content-Length, data.length() + );  
  18.             // POST方式,其实就是浏览器把数据写给服务器  
  19.             conn.setDoOutput(true); // 设置可输出流  
  20.             OutputStream os = conn.getOutputStream(); // 获取输出流  
  21.             os.write(data.getBytes()); // 将数据写给服务器  
  22.             int code = conn.getResponseCode();  
  23.             if (code == 200) {  
  24.                 InputStream is = conn.getInputStream();  
  25.                 return StreamTools.streamToString(is);  
  26.             } else {  
  27.                 return 网络访问失败;  
  28.             }  
  29.         } catch (Exception e) {  
  30.             e.printStackTrace();  
  31.             return 网络访问失败;  
  32.         }  
  33.     }  

HttpClient

HttpClient是开源组织Apache提供的Java请求网络框架,其最早是为了方便Java服务器开发而诞生的,是对JDK中的HttpUrlConnection各API进行了封装和简化,提高了性能并且降低了调用API的繁琐,Android因此也引进了这个联网框架,我们再不需要导入任何jar或者类库就可以直接使用,值得注意的是Android官方已经宣布不建议使用HttpClient了,我们再开发的时候尽量少用吧,但是用了也无妨!

HttpClient发送GET请求

1, 创建HttpClient对象

2,创建HttpGet对象,指定请求地址(带参数)

3,使用HttpClient的execute(),方法执行HttpGet请求,得到HttpResponse对象

4,调用HttpResponse的getStatusLine().getStatusCode()方法得到响应码

5,调用的HttpResponse的getEntity().getContent()得到输入流,获取服务端写回的数据

[java]  view plain  copy
  1. /** 
  2.      * 通过HttpClient发送GET请求 
  3.      *  
  4.      * @param username 
  5.      * @param password 
  6.      * @return 
  7.      */  
  8.     public static String loginByHttpClientGet(String username, String password) {  
  9.         String path = http://192.168.0.107:8080/WebTest/LoginServerlet?username=  
  10.                 + username + &password= + password;  
  11.         HttpClient client = new DefaultHttpClient(); // 开启网络访问客户端  
  12.         HttpGet httpGet = new HttpGet(path); // 包装一个GET请求  
  13.         try {  
  14.             HttpResponse response = client.execute(httpGet); // 客户端执行请求  
  15.             int code = response.getStatusLine().getStatusCode(); // 获取响应码  
  16.             if (code == 200) {  
  17.                 InputStream is = response.getEntity().getContent(); // 获取实体内容  
  18.                 String result = StreamTools.streamToString(is); // 字节流转字符串  
  19.                 return result;  
  20.             } else {  
  21.                 return 网络访问失败;  
  22.             }  
  23.         } catch (Exception e) {  
  24.             e.printStackTrace();  
  25.             return 网络访问失败;  
  26.         }  
  27.     }  

HttpClient发送POST请求

1,创建HttpClient对象

2,创建HttpPost对象,指定请求地址

3,创建List,用来装载参数

4,调用HttpPost对象的setEntity()方法,装入一个UrlEncodedFormEntity对象,携带之前封装好的参数

5,使用HttpClient的execute()方法执行HttpPost请求,得到HttpResponse对象

6, 调用HttpResponse的getStatusLine().getStatusCode()方法得到响应码

7, 调用的HttpResponse的getEntity().getContent()得到输入流,获取服务端写回的数据

[java]  view plain  copy
  1. /** 
  2.      * 通过HttpClient发送POST请求 
  3.      *  
  4.      * @param username 
  5.      * @param password 
  6.      * @return 
  7.      */  
  8.     public static String loginByHttpClientPOST(String username, String password) {  
  9.         String path = http://192.168.0.107:8080/WebTest/LoginServerlet;  
  10.         try {  
  11.             HttpClient client = new DefaultHttpClient(); // 建立一个客户端  
  12.             HttpPost httpPost = new HttpPost(path); // 包装POST请求  
  13.             // 设置发送的实体参数  
  14.             List parameters = new ArrayList();  
  15.             parameters.add(new BasicNameValuePair(username, username));  
  16.             parameters.add(new BasicNameValuePair(password, password));  
  17.             httpPost.setEntity(new UrlEncodedFormEntity(parameters, UTF-8));  
  18.             HttpResponse response = client.execute(httpPost); // 执行POST请求  
  19.             int code = response.getStatusLine().getStatusCode();  
  20.             if (code == 200) {  
  21.                 InputStream is = response.getEntity().getContent();  
  22.                 String result = StreamTools.streamToString(is);  
  23.                 return result;  
  24.             } else {  
  25.                 return 网络访问失败;  
  26.             }  
  27.         } catch (Exception e) {  
  28.             e.printStackTrace();  
  29.             return 访问网络失败;  
  30.         }  
  31.     }  

其他开源联网框架

AsyncHttpClient

除了上述Android官方推荐的联网框架以外,在开源世界里关于联网框架真是太多太多了,例如afinal,xutils等等,都是一些开源大牛自己封装的联网框架,并且在GitHub开源社区中可以 下载 到,其实类似的开源联网框架基本上也是基于HttpUrlConnection的进一步封装,大大提高了性能,同时更加简化了使用方法,这里使用AsyncHttpClient作为案例,其他的联网框架大家可以去网上找,下载使用试试便可。 AsyncHttpClient是一个非常优秀的联网框架,不仅支持所有Http请求的方式,而且还支持文件的上传和下载,要知道用HttpUrlConnection写一个文件上传和下载健全功能是很需要花费一定时间和精力的,因为请求头实在是太多了,稍有不慎就会写错。但是AsyncHttpClient已经封装好了这些“麻烦”,我们只需要下载到AsyncHttpClient的jar包或者 源码 导入项目中,Http,上传,下载等等,只需要几个简单的api即可搞定。 AsyncHttpClient的GitHub主页:https://github.com/AsyncHttpClient/async-http-client/

AsyncHttpClient发送GET请求

1,将下载好的源码拷贝到src目录下

2,创建一个AsyncHttpClient的对象

3,调用该类的get方法发送GET请求,传入请求资源地址URL,创建AsyncHttpResponseHandler对象

4,重写AsyncHttpResponseHandler下的两个方法,onSuccess和onFailure方法

 

[java]  view plain  copy
  1. /** 
  2.      * 通过AsyncHttpClient发送GET请求 
  3.      */  
  4.     public void loginByAsyncHttpGet() {  
  5.         String path = http://192.168.0.107:8080/WebTest/LoginServerlet?username=zhangsan&password=123;  
  6.         AsyncHttpClient client = new AsyncHttpClient();  
  7.         client.get(path, new AsyncHttpResponseHandler() {  
  8.   
  9.             @Override  
  10.             public void onFailure(int arg0, Header[] arg1, byte[] arg2,  
  11.                     Throwable arg3) {  
  12.                 // TODO Auto-generated method stub  
  13.                 Log.i(TAG, 请求失败: + new String(arg2));  
  14.             }  
  15.   
  16.             @Override  
  17.             public void onSuccess(int arg0, Header[] arg1, byte[] arg2) {  
  18.                 // TODO Auto-generated method stub  
  19.                 Log.i(TAG, 请求成功: + new String(arg2));  
  20.             }  
  21.         });  
  22.     }  

 

AsyncHttpClient发送POST请求

1,将下载好的源码拷贝到src目录下

2,创建一个AsyncHttpClient的对象

3,创建请求参数,RequestParams对象

4,调用该类的post方法发POST,传入请求资源地址URL,请求参数RequestParams,创建AsyncHttpResponseHandler对象

5,重写AsyncHttpResponseHandler下的两个方法,onSuccess和onFailure方法

[java]  view plain  copy
  1. /** 
  2.      * 通过AsyncHttpClient发送POST请求 
  3.      */  
  4.     public void loginByAsyncHttpPost() {  
  5.         String path = http://192.168.0.107:8080/WebTest/LoginServerlet;  
  6.         AsyncHttpClient client = new AsyncHttpClient();  
  7.         RequestParams params = new RequestParams();  
  8.         params.put(username, zhangsan);  
  9.         params.put(password, 123);  
  10.         client.post(path, params, new AsyncHttpResponseHandler() {  
  11.   
  12.             @Override  
  13.             public void onFailure(int arg0, Header[] arg1, byte[] arg2,  
  14.                     Throwable arg3) {  
  15.                 // TODO Auto-generated method stub  
  16.                 Log.i(TAG, 请求失败: + new String(arg2));  
  17.             }  
  18.   
  19.             @Override  
  20.             public void onSuccess(int arg0, Header[] arg1, byte[] arg2) {  
  21.                 // TODO Auto-generated method stub  
  22.                 Log.i(TAG, 请求成功: + new String(arg2));  
  23.             }  
  24.         });  
  25.     }  

AsyncHttpClient上传文件

1,将下载好的源码拷贝到src目录下

2,创建一个AsyncHttpClient的对象

3,创建请求参数,RequestParams对象,请求参数仅仅包含文件对象即可,例如:

 

[java]  view plain  copy
  1. params.put(profile_picture, new File(/sdcard/pictures/pic.jpg));  

 

4,调用该类的post方法发POST,传入请求资源地址URL,请求参数RequestParams,创建AsyncHttpResponseHandler对象

5,重写AsyncHttpResponseHandler下的两个方法,onSuccess和onFailure方法

 

判断网络连接状态

很多时候对于手机或者平板电脑这样的手持设备,我们是不知道它们的网络连接状态的,在联网的时候我们必须得保证设备的网路是否正常,是否可以连接上互联网,或者我们在进行大量数据上传或者下载,例如下载网路视频,看网路电视等等,我们必须得为用户省钱,这样大数据的传输显然是不能使用用户昂贵的数据流量的,而是判断当前网络是不是在wifi下,使用WiFi来进行大数据的传输,会给用户更好的体验,那么下面这个工具类就是用来判断设备网络连接状态的,不仅判断了当前设置手机网络下还是WiFi环境下,而且如果手机网络下还需要设置运营商的代理IP和端口。

 

[java]  view plain  copy
  1. /** 
  2.  * 判断网络状态的工具类 
  3.  *  
  4.  */  
  5. public class NetworkUtil {  
  6.   
  7.     /* 代码IP */  
  8.     private static String PROXY_IP = null;  
  9.     /* 代理端口 */  
  10.     private static int PROXY_PORT = 0;  
  11.     /** 
  12.      * 判断当前是否有网络连接 
  13.      *  
  14.      * @param context 
  15.      * @return 
  16.      */  
  17.     public static boolean isNetwork(Context context) {  
  18.         boolean network = isWifi(context);  
  19.         boolean mobilework = isMobile(context);  
  20.         if (!network && !mobilework) { // 无网络连接  
  21.             Log.i(NetworkUtil, 无网路链接!);  
  22.             return false;  
  23.         } else if (network == true && mobilework == false) { // wifi连接  
  24.             Log.i(NetworkUtil, wifi连接!);  
  25.         } else { // 网络连接  
  26.             Log.i(NetworkUtil, 手机网路连接,读取代理信息!);  
  27.             readProxy(context); // 读取代理信息  
  28.             return true;  
  29.         }  
  30.         return true;  
  31.     }  
  32.   
  33.     /** 
  34.      * 读取网络代理 
  35.      *  
  36.      * @param context 
  37.      */  
  38.     private static void readProxy(Context context) {  
  39.         Uri uri = Uri.parse(content://telephony/carriers/preferapn);  
  40.         ContentResolver resolver = context.getContentResolver();  
  41.         Cursor cursor = resolver.query(uri, nullnullnullnull);  
  42.         if (cursor != null && cursor.moveToFirst()) {  
  43.             PROXY_IP = cursor.getString(cursor.getColumnIndex(proxy));  
  44.             PROXY_PORT = cursor.getInt(cursor.getColumnIndex(port));  
  45.         }  
  46.         cursor.close();  
  47.     }  
  48.   
  49.     /** 
  50.      * 判断当前网络是否是wifi局域网 
  51.      *  
  52.      * @param context 
  53.      * @return 
  54.      */  
  55.     public static boolean isWifi(Context context) {  
  56.         ConnectivityManager manager = (ConnectivityManager) context  
  57.                 .getSystemService(Context.CONNECTIVITY_SERVICE);  
  58.         NetworkInfo info = manager  
  59.                 .getNetworkInfo(ConnectivityManager.TYPE_WIFI);  
  60.         if (info != null) {  
  61.             return info.isConnected(); // 返回网络连接状态  
  62.         }  
  63.         return false;  
  64.     }  
  65.   
  66.     /** 
  67.      * 判断当前网络是否是手机网络 
  68.      *  
  69.      * @param context 
  70.      * @return 
  71.      */  
  72.     public static boolean isMobile(Context context) {  
  73.         ConnectivityManager manager = (ConnectivityManager) context  
  74.                 .getSystemService(Context.CONNECTIVITY_SERVICE);  
  75.         NetworkInfo info = manager  
  76.                 .getNetworkInfo(ConnectivityManager.TYPE_MOBILE);  
  77.         if (info != null) {  
  78.             return info.isConnected(); // 返回网络连接状态  
  79.         }  
  80.         return false;  
  81.     }  
  82. }  



  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值