网络开发(详)


一.网络管理

ConnectivityManager类来监控网络连接的状态,,配置错误处理等

1.检查网络状态

ConnectivityManager cm =
        (ConnectivityManager)context.getSystemService(Context.CONNECTIVITY_SERVICE);
 
NetworkInfo activeNetwork = cm.getActiveNetworkInfo();
boolean isConnected = activeNetwork.isConnectedOrConnecting();

 

2.检查网络类型

boolean isWiFi = activeNetwork.getType() == ConnectivityManager.TYPE_WIFI;

 

3.监控网络状态

<action android:name="android.net.conn.CONNECTIVITY_CHANGE"/>

 

 

二.HTTP通信

1.Http协议

一、HTTP协议详解之请求

 

//请求行POST /reg.jsp HTTP/ (CRLF)       

1.User-Agent

1.1什么是User-Agent

示例

谷歌Android
"Mozilla/5.0 (Linux; U; Android 2.2; en-us; Nexus One Build/FRF91) AppleWebKit/533.1 (KHTML, like Gecko) Version/4.0 Mobile Safari/533.1"

苹果iPhone 4
"Mozilla/5.0 (iPhone; CPU iPhone OS 5_0_1 like Mac OS X) AppleWebKit/534.46 (KHTML, like Gecko) Mobile/9A405"

苹果iPad 2
"Mozilla/5.0 (iPad; CPU OS 5_0_1 like Mac OS X) AppleWebKit/534.46 (KHTML, like Gecko) Mobile/9A405"

诺基亚N97
"Mozilla/5.0 (SymbianOS/9.4; Series60/5.0 NokiaN97-1/20.0.019; Profile/MIDP-2.1 Configuration/CLDC-1.1) AppleWebKit/525 (KHTML, like Gecko) BrowserNG/7.1.18124"

更多款手机的User-Agenthttp://www.zytrax.com/tech/web/mobile_ids.html

 

 

User-AgentHttp协议中的一部分,属于头域的组成部分,User Agent也简称UA。用较为普通的一点来说,是一种向访问网站提供你所使用的浏览器类型、操作系统及版本、CPU 类型、浏览器渲染引擎、浏览器语言、浏览器插件等信息的标识。UA字符串在每次浏览器 HTTP 请求时发送到服务器!

浏览器UA 字串的标准格式为: 浏览器标识 (操作系统标识加密等级标识浏览器语言渲染引擎标识 版本信息

操作系统标识

  FreeBSD

  X11; FreeBSD (version no.) i386

  X11; FreeBSD (version no.) AMD64

  Linux

  X11; Linux ppc

  X11; Linux ppc64

  X11; Linux i686

  X11; Linux x86_64

  Mac

  Macintosh; PPC Mac OS X

  Macintosh; Intel Mac OS X

  Solaris

  X11; SunOS i86pc

  X11; SunOS sun4u

  Windows:

  Windows NT 6.1 对应操作系统 windows 7

  Windows NT 6.0 对应操作系统 windows vista

  Windows NT 5.2 对应操作系统 windows 2003

  Windows NT 5.1 对应操作系统 windows xp

  Windows NT 5.0 对应操作系统 windows 2000

  Windows ME

  Windows 98

加密等级标识

  N: 表示无安全加密

  I: 表示弱安全加密

  U: 表示强安全加密

浏览器语言

  在首选项 常规 语言中指定的语言

渲染引擎

  浏览器 使用 Presto 渲染引擎,格式为: Presto/版本号

版本信息

  显示 浏览器 真实版本信息,格式为: Version/版本号

 

1.2、User-Agent的历史

1993年,NCSA 发布了首款 web 浏览器 Mosaic。它的 user-agent 字串非常简洁:

  Mosaic/0.9虽然当时由于它对操作系统和平台的依赖性,但是基本格式还是很简单明了。在文本中,斜杠前面是产品名称(可能会显示为 NCSA Mosaic 或是其他类似的字),斜杠后面是产品版本号。

  Netscape Communications 开发了 web 浏览器 Mozilla(当时号称Mosaic 杀手)。他们首款公开发行版本: Netscape Navigator 2 user-agent 字串具有如下格式:

  Mozilla/Version [Language] (Platform; Encryption)Netscape 按之前的做法在 user-agent 字串的前半部分使用了产品名称和产品版本,但在后面增加了下列信息:

  Language - 表示应用程序用的是哪个语言 Platform - 表示应用程序是在什么操作系统和/或平台中运行 Encryption - 表示应用程序包含了什么安全加密类型。其中的值可能是U(128位加密)I(40位加密)N(没加密)。 Netscape Navigator 2 user-agent 字串的示例:

  Mozilla/2.02 [fr] (WinNT; I)上面的字串指: Netscape Navigator 2.02 、法语 、Windows NT 40位加密。在当时,通过user-agent 字串中的产品名称,可以正确判断使用的是哪个 web 浏览器。Netscape Navigator 3 Internet Explorer 31996年,Netscape Navigator 3 发布,它远远超过 Mosaic 成为当时最流行的 web 浏览器。而user-agent 字串只有些小的变化:去掉了语言部分,多了个放操作系统或CPU的可选信息。格式如下:

  Mozilla/Version (Platform; Encryption [; OS-or-CPU description])在 Windows 系统中 Netscape Navigator 3 user-agent 字串的示例:

  Mozilla/3.0 (Win95; U)上面的字串指:Netscape Navigator 3 Windows 95 128 位加密。在 Windows 系统中,字串里面不会显示 OS 或 CPU 的信息。

  Netscape Navigator 3 发布不久,微软公布了它的首款 web 浏览器: IE 3 ¹,但是 Netscape 是当时首选浏览器,大多数服务器在加载页面前都会检查 user-agent 是否为该款浏览器。IE 如果不兼容Netscape user-agent 字串,使用 IE 的用户就根本打不开这些页面,于是造就了如下格式:

  Mozilla/2.0 (compatible; MSIE Version; Operating System)在 Windows 95 中 IE 3.02 user-agent 字串的示例:

  Mozilla/2.0 (compatible; MSIE 3.02; Windows 95)由于当时的浏览器嗅探只查 user-agent 字串中的产品名称部分,结果 IE 摇身一变被识别成了 Mozilla,伪装成 Netscape Navigator。这个做法引发了对浏览器识别的争论。从此以后,浏览器真正的版本埋没在了字串的中间。Netscape Communicator 4 Internet Explorer 4819978月,Netscape Communicator 4 发布(发布的名称中 Navigator 换成了 Communicator),它的 user-agent 字串格式与 版本一致。Windows 98 中 版本的user-agent 字串如下:

  Mozilla/4.0 (Win98; I)Netscape 浏览器在更新时,版本也相应增加。4.79 版本的 user-agent 字串如下:

  Mozilla/4.79 (Win98; I)微软发布 IE 4 时,user-agent 字串更新了版本,格式如下:

  Mozilla/4.0 (compatible; MSIE Version; Operating System)在 Windows 98 中 IE 4 user-agent 字串的示例:

  Mozilla/4.0 (compatible; MSIE 4.0; Windows 98)可以看出,Mozilla 的版本与 IE 实际的版本一致,这样就可以识别第4代浏览器了。但遗憾的是,不久 IE 4.5 马上就发布了(只在 Mac 平台),虽然 Mozilla 版本仍是 4,但是 IE 的版本改成如下:

  Mozilla/4.0 (compatible; MSIE 4.5; Mac_PowerPC)此后,IE 的版本一直到 都沿用了这个模式。

  而 IE 8 的 user-agent 字串添加了呈现引擎(rendering engine)版本:

  Mozilla/4.0 (compatible; MSIE 8.0; Windows NT 5.1; Trident/4.0)新增的呈现引擎非常重要!这样 IE8 以 MSIE 7.0 兼容模式运行时,Trident 版本保持不变,而原先 IE7 user-agent 字串不包括 Trident 版本。这样可以区分 IE7 与 IE8 运行的兼容模式。

  注意:别指望能从 Mozilla 版本中得到什么靠谱的信息。

Gecko

  Gecko 是 Firefox 的呈现引擎。Gecko 首次开发是作为 Mozilla 浏览器 Netscape 6 的一部分。Netscape 6 user-agent 字串的结构是面向未来的,新版本反应出从 4.x 版本的简单变得较为复杂,它的格式如下:

  Mozilla/MozillaVersion (Platform; Encryption; OS-or-CPU; Language; PrereleaseVersion)Gecko/GeckoVersion ApplicationProduct/ApplicationProductVersion为了更好的理解上面的 Geckouser-agent 字串格式,下面来看看各种从基于 Gecko 浏览器中取得的字串。

  在 Windows XP 中的 Netscape 6.21

  Mozilla/5.0 (Windows; U; Windows NT 5.1; en-US; rv:0.9.4) Gecko/20011128 Netscape6/6.2.1在 Linux 中的 SeaMonkey 1.1a:

  Mozilla/5.0 (X11; U; Linux i686; en-US; rv:1.8.1b2) Gecko/20060823 SeaMonkey/1.1a在 Windows XP 中的 Firefox 2.0.0.11 :

  Mozilla/5.0 (Windows; U; Windows NT 5.1; en-US; rv:1.8.1.11) Gecko/20071127 Firefox/2.0.0.11Mac OS X 中的 Camino 1.5.1:

  Mozilla/5.0 (Macintosh; U; Intel Mac OS X; en; rv:1.8.1.6) Gecko/20070809 Camino/1.5.1上面都是基于 Gecko 的浏览器所取得的user-agent 字串,区别只是版本有所不同。Mozilla 版本 5.0 是自从首款基于 Gecko 发布后就一直不变,而且以后有可能也不会变²

WebKit

  2003年,Apple 宣布发布首款他们自主开发的 web 浏览器:Safari。它的呈现引擎叫 WebKit。它是 Linux 中的 web 浏览器 Konqueror 呈现引擎 KHTML 的一个分支,几年后,WebKit 的开源吸引了呈现引擎的开发人员。

  这款新浏览器和呈现引擎的开发人员也遇到了曾经 IE 3.0 类似的问题:怎样才能溶入主流而不被踢出局?答案是:在 user-agent 字串中放详尽的信息,以便骗取网站的信任使它与其它流行的浏览器兼容。user-agent字串格式如下:

  Mozilla/5.0 (Platform; Encryption; OS-or-CPU; Language) AppleWebKit/AppleWebKitVersion (KHTML, like Gecko) Safari/SafariVersion下面是示例:

  Mozilla/5.0 (Macintosh; U; PPC Mac OS X; en) AppleWebKit/124 (KHTML, like Gecko) Safari/125.1这又是个挺长的user-agent 字串,其中包括的信息既有 Apple WebKit 的版本,也有 Safari 的版本。凡是基于 WebKit 的浏览器都将自己伪装成了 Mozilla 5.0,与基于 Gecko 浏览器完全一样。但 Safari 的版本是浏览器的构建版本号(build number)Safari 1.25 user-agent 字串中号为 125.1(如上所示)Safari 版本 user-agent 字串包括了实际的 Safari 版本:

  Mozilla/5.0 (Macintosh; U; PPC Mac OS X; en) AppleWebKit/522.15.5 (KHTML, like Gecko) Version/3.0.3 Safari/522.15.5其中的(KHTML, like Gecko)在 Safari 1.0 预览版本中就有了,这字串部分是最耐人寻味又饱受诟病。Apple 的野心是为了让开发人员把 Safari 当成 Gecko,所以采取了当初微软 IEuser-agent 的类似做法:Safari 是兼容 Mozilla 的,否则 Safari 用户会认为用的浏览器不受支持。

  而其它基于 WebKit 的浏览器与 Safari 不同的是,没有上面说的这个情况,所以检测断定浏览器是否基于 WebKit 比看有没有明确标 Safari 更有用。

Konqueror

  Konqueror 是款在 KDE Linux 桌面环境中的浏览器,基于 KHTML 开源呈现引擎。它只发布了在 Linux 的版本,但是拥有活跃的用户群。为了兼容性最大化,user-agent 字串的格式也紧跟 IE 的后尘:

  Mozilla/5.0 (compatible; Konqueror/Version; OS-or-CPU)Konqueror 3.2 为了与 WebKituser-agent 字串变化保持一致,它将 KHTML 作为它的标识:

  Mozilla/5.0 (compatible; Konqueror/Version; OS-or-CPU) KHTML/KHTMLVersion (like Gecko)如下所示:

  Mozilla/5.0 (compatible; Konqueror/3.5; SunOS) KHTML/3.5.0 (like Gecko)Konqueror 和 KHTML 的版本号比较一致,唯一的区别就是下点处不同,比如Konquerer 3.5KHTML 3.5.1

Chrome

  Google Chrome 浏览器以 WebKit 作为呈现引擎,JavaScript 引擎却用了另一种。最初发布的版本是 0.2,它的 user-agent 字串格式是在 webKit 信息的基础上又增加了如下:

  Mozilla/5.0 (Platform; Encryption; OS-or-CPU; Language) AppleWebKit/AppleWebKitVersion (KHTML, like Gecko) Chrome/ChromeVersion Safari/SafariVersionChrome 0.2user-agent 信息的示例如下:

  Mozilla/5.0 (Windows; U; Windows NT 5.1; en-US) AppleWebKit/525.13 (KHTML, like Gecko) Chrome/0.2.149.29 Safari/525.13虽我不敢完全保证,但很可能 WebKit 版本和 Safari 版本总会保持同步。

Opera

  Opera 浏览器默认 user-agent 字串是现代浏览器中最合理的--正确的标识了它自己及其版本。 在 Opera 8.0 前,它的user-agent 字串格式如下:

  Opera/Version (OS-or-CPU; Encryption) [Language]在 Windows XP 中 Opera 7.54 user-agent 字串示例:

  Opera/7.54 (Windows NT 5.1; U) [en]Opera 8 user-agent 字串的语言部分移到了括号内。

  Opera/Version (OS-or-CPU; Encryption; Language)在 Windows XP 中 Opera 8 user-agent 字串示例:

  Opera/8.0 (Windows NT 5.1; U; en)当时 Opera 做为主流浏览器之一,它的 user-agent 字串是唯一使用产品名称和版本完全真实的标识了它自己。但是由于大量的浏览器嗅探代码在 Internet 上像蝗虫飞过般只吃标 Mozilla 产品名的user-agent 字串,造成了 Opera user-agent 字串发生了完全的改变。

  Opera 9 user-agent 字串有两种修改的方式:一种方式是将自己标识为 Firefox 或 IE 浏览器。在这种方式下,user-agent 字串与 Firefox 或 IE 的几乎一样,只不过末尾附加了Opera及版本号。如下所示:

  Mozilla/5.0 (Windows NT 5.1; U; en; rv:1.8.1) Gecko/20061208 Firefox/2.0.0 Opera 9.50Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1; en) Opera 9.50前一字串将 Opera 9.5 标识为 Firefox 2。后一字串将 Opera 9.5 标识为 IE 6,在两个字串中都带有 Opera 版本信息。虽然这种方式是作为 Firefox 或 IE 打开的,但也能识别出 Opera。另一种方法则是浏览器 user-agent 字串标识伪装成 Firefox 或 IE,同时也找不到Opera字串及其版本信息。这样从字面上去区分 Opera 浏览器便成了不可能完成的任务

结论

user-agent 字串史可以说明曾对 user-agent 嗅探说不的原因:IE 想要将自己识别为 Netscape 4Konqueror 和 WebKit 想要识别为 FirefoxChrome 想要识别为 Safari。这样使得除 Opera 外所有浏览器的user-agent 嗅探区别很小,想要从一堆茫茫浏览器海洋中找出有用的标识太少了。关于嗅探要记住:一款浏览器与其它浏览器是兼容的,这样造成了不能完全准确的断定是哪款浏览器。

  比如说 Chrome ,它声称任何可以在 Safari 3 访问的网站 Chrome 也都可以访问,但是对检测 Chrome 没有一点用。为了浏览器的兼容--这便是这个声明的理由。

 

1.3user-agent作用

根据前面介绍的user-agent的历史我们知道,通过user-agent不能完全准确的判断是属于那款浏览器。由于UA字符串在每次浏览器HTTP 请求时发送到服务器,所以服务器就可以根据它来做好多事。

比如:

1、统计用户浏览器使用情况。有些浏览器说被多少人使用了,实际上就可以通过判断每个IPUA来确定这个IP是用什么浏览器访问的,以得到使用量的数据。

2、根据用户使用浏览器的不同,显示不同的排版从而为用户提供更好的体验。有些网站会根据这个来调整打开网站的类型,如是手机的就打开wap,显示非手机的就打开pc常规页面。用手机访问谷歌和电脑访问是不一样的,这些是谷歌根据访问者的UA来判断的。 

既然知道了UA的作用,那么其实客户端也可以使用UA来做一些神奇的事。

比如:伪装 user agent 来回避某些侦测特定浏览器才能读取的网站。

如果使用Firefox浏览器插件User agent switcher,用户就可以轻松地在不同UA之间切换,把自己伪装成其他浏览器。这样就可以在PC上预览WAP或移动格式的网页,比如专门为iPhone设计的页面

 

1.4、获得user-agent的值

既然已经知道user-agenthttp的头域,那我们在编程的时候就可以获得它。

在 ASP.NET 中使用 Request.Header["User-Agent"] 得到浏览器的 User Agent,也可以使用 Request.UserAgent 来获取;
Java 中使用 request.getHeader(User-Agent来获得;
PHP 中相应使用:$_SERVER[HTTP_USER_AGENT]

JS中则使用navigator.userAgent来获得(是否记得在客户端经常使用它来做浏览器兼容呢)。

 

//消息报头Accept:image/gif,image/x-xbitmap,image/jpeg,application/x-shockwave-flash,application/vnd.ms-excel,application/vnd.ms-powerpoint,application/msword,*/*(CRLF)

Accept-Language:zh-cn (CRLF)

Accept-Encoding:gzip,deflate (CRLF)

If-Modified-Since:Wed,05 Jan 2007 11:21:25 GMT (CRLF)

If-None-Match:W/"80b1a4c018f3c41:8317" (CRLF)

User-Agent:Mozilla/4.0(compatible;MSIE6.0;Windows NT 5.0) (CRLF)

Host:www.guet.edu.cn (CRLF)

Connection:Keep-Alive (CRLF)

(CRLF)

 

//请求正文

user=jeffrey&pwd=1234 

     以上是http请求的三部:请求行、消息报头、请求正文。

 

     请求行以一个方法符号开头,以空格分开,后面跟着请求的URI和协议的版本,格式如下:

Method Request-URI HTTP-Version CRLF  
     其中 Method表示请求方法(POSTGETPUTDELETE)Request-URI是一个统一资源标识符;HTTP-Version表示请求的HTTP协议版本;CRLF表示回车和换行。

 

二、HTTP协议详解之响应篇

//状态行HTTP/1.1 200 OK (CRLF)

 

//消息报头Cache-Control: private, max-age=30

Content-Type: text/html; charset=utf-8

Content-Encoding: gzip

Expires: Mon, 25 May 2009 03:20:33 GMT

Last-Modified: Mon, 25 May 2009 03:20:03 GMT

Vary: Accept-Encoding

Server: Microsoft-IIS/7.0

X-AspNet-Version: 2.0.50727

X-Powered-By: ASP.NET

Date: Mon, 25 May 2009 03:20:02 GMT

Content-Length: 12173

 

//响应正文

     HTTP响应也是由三个部分组成,分别是:状态行、消息报头、响应正文

     状态行格式如下:
          HTTP-Version Status-Code Reason-Phrase CRLF
     其中,HTTP-Version表示服务器HTTP协议的版本;Status-Code表示服务器发回的响应状态代码;Reason-Phrase表示状态代码的文本描述。

常见状态代码、状态描述、说明:
200 OK      //客户端请求成功
400 Bad Request  //客户端请求有语法错误,不能被服务器所理解
401 Unauthorized //请求未经授权,这个状态代码必须和WWW-Authenticate报头域一起使用 
403 Forbidden  //服务器收到请求,但是拒绝提供服务
404 Not Found  //请求资源不存在,eg:输入了错误的URL
500 Internal Server Error //服务器发生不可预期的错误
503 Server Unavailable  //服务器当前不能处理客户端的请求,一段时间后可能恢复正常

 

三、HTTP协议详解之消息报头

        HTTP消息由客户端到服务器的请求和服务器到客户端的响应组成。请求消息和响应消息都是由开始行(对于请求消息,开始行就是请求行;对于响应消息,开始行就是状态行),消息报头(可选),空行(只有CRLF的行),消息正文(可选)组成。

        HTTP消息报头包括普通报头、请求报头、响应报头、实体报头。每一个报头域都是由名字++空格+值 组成,消息报头域的名字是大小写无关的。

1、请求报头
     请求报头允许客户端向服务器端传递请求的附加信息以及客户端自身的信息。


常用的请求报头

Accept请求报头域用于指定客户端接受哪些类型的信息。
Accept-Charset请求报头域用于指定客户端接受的字符集。
Accept-Encoding请求报头域类似于Accept,但是它是用于指定可接受的内容编码。
Accept-Language请求报头域类似于Accept,但是它是用于指定一种自然语言。
Authorization请求报头域主要用于证明客户端有权查看某个资源。

Host请求报头域主要用于指定被请求资源的Internet主机和端口号,它通常从HTTP URL中提取出来的。User-Agent请求报头域允许客户端将它的操作系统、浏览器和其它属性告诉服务器。

2、响应报头

     响应报头允许服务器传递不能放在状态行中的附加响应信息,以及关于服务器的信息和对Request-URI所标识的资源进行下一步访问的信息。


常用的响应报头
Location响应报头域用于重定向接受者到一个新的位置。Location响应报头域常用在更换域名的时候。
Server响应报头域包含了服务器用来处理请求的软件信息

3. 实体报头

请求和响应消息都可以传送一个实体。


常用的实体报头
Content-Encoding指示已经被应用到实体正文的附加内容的编码。

Content-Language实体报头域描述了资源所用的自然语言。

Content-Length实体报头域用于指明实体正文的长度,以字节方式存储的十进制数字来表示。
Content-Type实体报头域用语指明发送给接收者的实体正文的媒体类型。
Last-Modified实体报头域用于指示资源的最后修改日期和时间。
Expires实体报头域给出响应过期的日期和时间。

 

四、补充

1HTTP协议Content Lenth限制漏洞导致拒绝服务攻击
使用POST方法时,可以设置ContentLenth来定义需要传送的数据长度,例如ContentLenth:999999999,在传送完成前,内 存不会释放,攻击者可以利用这个缺陷,连续向WEB服务器发送垃圾数据直至WEB服务器内存耗尽。这种攻击方法基本不会留下痕迹。
2、为了提高用户使用浏览器时的性能,现代浏览器还支持并发的访问方式,浏览一个网页时同时建立多个连接,以迅速获得一个网页上的多个图标,这样能更快速完成整个网页的传输。HTTP1.1中提供了这种持续连接的方式,而下一代HTTP协议:HTTP-NG更增加了有关会话控制、丰富的内容协商等方式的支持,来提供更高效率的连接。

 

.Java利用HTTP协议实现联网和下载

Url的请求连接(Get方式)

String currentUrl=http://www.myWeb.com/login.jsp?userName='Devin'&passWord='mypassword'; //URL ?后面的内容为HTTP请求的正文

URL url = new URL(currentUrl);

 

HttpURLConnection httpurlconnection = url.openConnection();

//下面的设置对应HTTP请求中的消息报头

httpurlconnection.setRequestProperty("User-Agent",CommonValues.User_Agent);

httpurlconnection.setRequestProperty("Accept",CommonValues.Accept);

httpurlconnection.setRequestProperty("Accept-Charset",CommonValues.Accept_Charset);

httpurlconnection.setRequestProperty("Accept-Language",CommonValues.Accept_Language);

httpurlconnection.setRequestProperty("Connection",CommonValues.Connection);

httpurlconnection.setRequestProperty("Keep-Alive",CommonValues.Keep_Alive);

httpurlconnection.setConnectTimeout(CommonValues.ConnectionTimeOut);

httpurlconnection.setReadTimeout(CommonValues.ReadTimeOut);

             

httpurlconnection.connect();

            

int responsecode = httpurlconnection.getResponseCode();

             

if(responsecode == HttpURLConnection.HTTP_OK) //对应HTTP响应中状态行的响应码

{

//操作请求流,这里对应HTTP响应中的响应正文

}

             

if (httpurlconnection != null

{

   httpurlconnection.disconnect();

}

 

 

HTTP请求:GETPOST方法的区别

  HTTP 定义了与服务器交互的不同方法,最基本的方法是 GET 和 POST

  1.Get是从服务器上获取数据,Post是向服务器传送数据。GET 用于信息获取,是安全的和幂等的。安全的意味着该操作用于获取信息而非修改信息,幂等的意味着对同一 URL 的多个请求应该返回同样的结果。完整的定义并不像看起来那样严格。

  2.GET请求请提交的数据放置在HTTP请求协议头中,附加在url之后,以?分开与url分开;而POST提交的数据则放在实体数据中,即在HTML HEADER内提交。

  3.GET方式提交的数据最多只能有1024字节,而POST则没有此限制。

  4.安全性问题。使用 Get 的时候,参数会显示在地址栏上,而 Post 不会。所以,如果这些数据是中文数据而且是非敏感数据,那么使用 get;如果用户输入的数据不是中文字符而且包含敏感数据,那么还是使用 post为好。

  5GetForm的默认方法。

 

 

Android网络连接之HttpURLConnectionHttpClient

1.概念      

      HTTP 协议可能是现在 Internet 上使用得最多、最重要的协议了,越来越多的 Java 应用程序需要直接通过 HTTP 协议来访问网络资源。在 JDK 的 java.net 包中已经提供了访问 HTTP 协议的基本功能:HttpURLConnection。但是对于大部分应用程序来说,JDK 库本身提供的功能还不够丰富和灵活。

      除此之外,在Android中,androidSDK中集成了ApacheHttpClient模块,用来提供高效的、最新的、功能丰富的支持 HTTP 协议工具包,并且它支持 HTTP 协议最新的版本和建议。使用HttpClient可以快速开发出功能强大的Http程序。

2.区别

HttpClient是个很不错的开源框架,封装了访问http的请求头,参数,内容体,响应等等,

HttpURLConnectionjava的标准类,什么都没封装,用起来太原始,不方便,比如重访问的自定义,以及一些高级功能等。

 

URLConnection

HTTPClient

Proxies and SOCKS

Full support in Netscape browser, appletviewer, and applications (SOCKS: Version 4 only); no additional limitations from security policies.

Full support (SOCKS: Version 4 and 5); limited in applets however by security policies; in Netscape can't pick up the settings from the browser.

Authorization

Full support for Basic Authorization in Netscape (can use info given by the user for normal accesses outside of the applet); no support in appletviewer or applications.

Full support everywhere; however cannot access previously given info from Netscape, thereby possibly requesting the user to enter info (s)he has already given for a previous access. Also, you can add/implement additional authentication mechanisms yourself.

Methods

Only has GET and POST.

Has HEAD, GET, POST, PUT, DELETE, TRACE and OPTIONS, plus any arbitrary method.

Headers

Currently you can only set any request headers if you are doing a POST under Netscape; for GETs and the JDK you can't set any headers.  Under Netscape 3.0 you can read headers only if the resource was returned with a Content-length header; if no Content-length header was returned, or under previous versions of Netscape, or using the JDK no headers can be read.

Allows any arbitrary headers to be sent and received.

Automatic Redirection Handling

Yes.

Yes (as allowed by the HTTP/1.1 spec).

Persistent Connections

No support currently in JDK; under Netscape uses HTTP/1.0 Keep-Alive's.

Supports HTTP/1.0 Keep-Alive's and HTTP/1.1 persistence.

Pipelining of Requests

No.

Yes.

Can handle protocols other than HTTP

Theoretically; however only http is currently implemented.

No.

Can do HTTP over SSL (https)

Under Netscape, yes. Using Appletviewer or in an application, no.

No (not yet).

Source code available

No.

Yes.

3.案例

URLConnection

    String urlAddress = "http://192.168.1.102:8080/AndroidServer/login.do";  

    URL url;  

    HttpURLConnection uRLConnection;  

    public UrlConnectionToServer(){  

  

    } 

   //向服务器发送get请求

    public String doGet(String username,String password){  

        String getUrl = urlAddress + "?username="+username+"&password="+password;  

        try {  

            url = new URL(getUrl);  

            uRLConnection = (HttpURLConnection)url.openConnection();  

            InputStream is = uRLConnection.getInputStream();  

            BufferedReader br = new BufferedReader(new InputStreamReader(is));  

            String response = "";  

            String readLine = null;  

            while((readLine =br.readLine()) != null){  

                //response = br.readLine();                  response = response + readLine;  

            }  

            is.close();  

            br.close();  

            uRLConnection.disconnect();  

            return response;  

        } catch (MalformedURLException e) {  

            e.printStackTrace();  

            return null;  

        } catch (IOException e) {  

            e.printStackTrace();  

            return null;  

        }  

    }  

      

    //向服务器发送post请求

    public String doPost(String username,String password){  

        try {  

            url = new URL(urlAddress);  

            uRLConnection = (HttpURLConnection)url.openConnection();  

            uRLConnection.setDoInput(true);  

            uRLConnection.setDoOutput(true);  

            uRLConnection.setRequestMethod("POST");  

            uRLConnection.setUseCaches(false);  

            uRLConnection.setInstanceFollowRedirects(false);  

            uRLConnection.setRequestProperty("Content-Type", "application/x-www-form-urlencoded");  

            uRLConnection.connect();  

              

            DataOutputStream out = new DataOutputStream(uRLConnection.getOutputStream());  

            String content = "username="+username+"&password="+password;  

            out.writeBytes(content);  

            out.flush();  

            out.close();  

              

            InputStream is = uRLConnection.getInputStream();  

            BufferedReader br = new BufferedReader(new InputStreamReader(is));  

            String response = "";  

            String readLine = null;  

            while((readLine =br.readLine()) != null){  

                //response = br.readLine();                  response = response + readLine;  

            }  

            is.close();  

            br.close();  

            uRLConnection.disconnect();  

            return response;  

        } catch (MalformedURLException e) {  

            e.printStackTrace();  

            return null;  

        } catch (IOException e) {  

            e.printStackTrace();  

            return null;  

        }  

    } 

HTTPClient

String urlAddress = "http://192.168.1.102:8080/qualityserver/login.do";  

public HttpClientServer(){  

          

 }  

      

public String doGet(String username,String password){  

    String getUrl = urlAddress + "?username="+username+"&password="+password;  

    HttpGet httpGet = new HttpGet(getUrl);  

    HttpParams hp = httpGet.getParams();  

    hp.getParameter("true");  

    //hp.  

    //httpGet.setp      HttpClient hc = new DefaultHttpClient();  

    try {  

        HttpResponse ht = hc.execute(httpGet);  

        if(ht.getStatusLine().getStatusCode() == HttpStatus.SC_OK){  

            HttpEntity he = ht.getEntity();  

            InputStream is = he.getContent();  

            BufferedReader br = new BufferedReader(new InputStreamReader(is));  

            String response = "";  

            String readLine = null;  

            while((readLine =br.readLine()) != null){  

                //response = br.readLine();                  response = response + readLine;  

            }  

            is.close();  

            br.close();  

              

            //String str = EntityUtils.toString(he);              System.out.println("========="+response);  

            return response;  

        }else{  

            return "error";  

        }  

    } catch (ClientProtocolException e) {  

        // TODO Auto-generated catch block          e.printStackTrace();  

        return "exception";  

    } catch (IOException e) {  

        // TODO Auto-generated catch block          e.printStackTrace();  

        return "exception";  

    }      

}  

  

public String doPost(String username,String password){  

    //String getUrl = urlAddress + "?username="+username+"&password="+password;      HttpPost httpPost = new HttpPost(urlAddress);  

    List params = new ArrayList();  

    NameValuePair pair1 = new BasicNameValuePair("username", username);  

    NameValuePair pair2 = new BasicNameValuePair("password", password);  

    params.add(pair1);  

    params.add(pair2);  

      

    HttpEntity he;  

    try {  

        he = new UrlEncodedFormEntity(params, "gbk");  

        httpPost.setEntity(he);  

          

    } catch (UnsupportedEncodingException e1) {  

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

    }   

      

    HttpClient hc = new DefaultHttpClient();  

    try {  

        HttpResponse ht = hc.execute(httpPost);  

        //连接成功          if(ht.getStatusLine().getStatusCode() == HttpStatus.SC_OK){  

            HttpEntity het = ht.getEntity();  

            InputStream is = het.getContent();  

            BufferedReader br = new BufferedReader(new InputStreamReader(is));  

            String response = "";  

            String readLine = null;  

            while((readLine =br.readLine()) != null){  

                //response = br.readLine();                  response = response + readLine;  

            }  

            is.close();  

            br.close();  

              

            //String str = EntityUtils.toString(he);              System.out.println("=========&&"+response);  

            return response;  

        }else{  

            return "error";  

        }  

    } catch (ClientProtocolException e) {  

        // TODO Auto-generated catch block          e.printStackTrace();  

        return "exception";  

    } catch (IOException e) {  

        // TODO Auto-generated catch block          e.printStackTrace();  

        return "exception";  

    }     

servletjson转化: 

        resp.setContentType("text/json");  

        resp.setCharacterEncoding("UTF-8");  

        toDo = new ToDo();  

        List<UserBean> list = new ArrayList<UserBean>();  

        list = toDo.queryUsers(mySession);  

        String body;  

 

        //设定JSON          JSONArray array = new JSONArray();  

        for(UserBean bean : list)  

        {  

            JSONObject obj = new JSONObject();  

            try  

            {  

                 obj.put("username", bean.getUserName());  

                 obj.put("password", bean.getPassWord());  

             }catch(Exception e){}  

             array.add(obj);  

        }  

        pw.write(array.toString());  

        System.out.println(array.toString()); 

android端接收:

String urlAddress = "http://192.168.1.102:8080/qualityserver/result.do";  

        String body =   

            getContent(urlAddress);  

        JSONArray array = new JSONArray(body);            

        for(int i=0;i<array.length();i++)  

        {  

            obj = array.getJSONObject(i);  

            sb.append("用户名:").append(obj.getString("username")).append("\t");  

            sb.append("密码:").append(obj.getString("password")).append("\n");  

              

            HashMap<String, Object> map = new HashMap<String, Object>();  

            try {  

                userName = obj.getString("username");  

                passWord = obj.getString("password");  

            } catch (JSONException e) {  

                e.printStackTrace();  

            }  

            map.put("username", userName);  

            map.put("password", passWord);  

            listItem.add(map);  

              

        }  

          

        } catch (Exception e) {  

            // TODO Auto-generated catch block              e.printStackTrace();  

        }  

          

        if(sb!=null)  

        {  

            showResult.setText("用户名和密码信息:");  

            showResult.setTextSize(20);  

        } else  

            extracted();  

   

       //设置adapter           SimpleAdapter simple = new SimpleAdapter(this,listItem,  

                android.R.layout.simple_list_item_2,  

                new String[]{"username","password"},  

                new int[]{android.R.id.text1,android.R.id.text2});  

        listResult.setAdapter(simple);  

          

        listResult.setOnItemClickListener(new OnItemClickListener() {  

            @Override  

            public void onItemClick(AdapterView<?> parent, View view,  

                    int position, long id) {  

                int positionId = (int) (id+1);  

                Toast.makeText(MainActivity.this, "ID"+positionId, Toast.LENGTH_LONG).show();  

              

            }  

        });  

    }  

    private void extracted() {  

        showResult.setText("没有有效的数据!");  

    }  

    //和服务器连接      private String getContent(String url)throws Exception{  

        StringBuilder sb = new StringBuilder();  

        HttpClient client =new DefaultHttpClient();  

        HttpParams httpParams =client.getParams();  

          

        HttpConnectionParams.setConnectionTimeout(httpParams, 3000);  

        HttpConnectionParams.setSoTimeout(httpParams, 5000);  

        HttpResponse response = client.execute(new HttpGet(url));  

        HttpEntity entity =response.getEntity();  

          

        if(entity !=null){  

            BufferedReader reader = new BufferedReader(new InputStreamReader  

                    (entity.getContent(),"UTF-8"),8192);  

            String line =null;  

            while ((line= reader.readLine())!=null){  

                sb.append(line +"\n");  

            }  

            reader.close();  

        }  

        return sb.toString();  

    } 

 

 

 

 

 

androidHttpURLConnection

1.HttpURLConnection连接URL1)创建一个URL对象

URL url = new URL(http://www.baidu.com/);

2)利用HttpURLConnection对象从网络中获取网页数据

HttpURLConnection conn = (HttpURLConnection) url.openConnection();

3)设置连接超时

conn.setConnectTimeout(6*1000);

4)对响应码进行判断

if (conn.getResponseCode() != 200)    //Internet获取网页,发送请求,将网页以流的形式读回来

throw new RuntimeException("请求url失败");

5)得到网络返回的输入流

InputStream is = conn.getInputStream();
6)String result = readData(is, "GBK"); //文件流输入出文件用outStream.write
7)conn.disconnect();

总结:--记得设置连接超时,如果网络不好,Android系统在超过默认时间会收回资源中断操作.
--返回的响应码200,是成功.
--Android中对文件流的操作和JAVA SE上面是一样的.
--在对大文件的操作时,要将文件写到SDCard上面,不要直接写到手机内存上.
--操作大文件是,要一遍从网络上读,一遍要往SDCard上面写,减少手机内存的使用.这点很重要,面试经常会被问到.
--对文件流操作完,要记得及时关闭.


2.Internet发送请求参数
步骤:
1)创建URL对象:URL realUrl = new URL(requestUrl);
2)通过HttpURLConnection对象,向网络地址发送请求

HttpURLConnection conn = (HttpURLConnection) realUrl.openConnection();
3)设置容许输出:conn.setDoOutput(true);
4)设置不使用缓存:conn.setUseCaches(false);
5)设置使用POST的方式发送:conn.setRequestMethod("POST");
6)设置维持长连接:conn.setRequestProperty("Connection", "Keep-Alive");
7)设置文件字符集:conn.setRequestProperty("Charset", "UTF-8");
8)设置文件长度:conn.setRequestProperty("Content-Length", String.valueOf(data.length));
9)设置文件类型:conn.setRequestProperty("Content-Type","application/x-www-form-urlencoded");
10)以流的方式输出.
总结:--发送POST请求必须设置允许输出
--不要使用缓存,容易出现问题.
--在开始用HttpURLConnection对象的setRequestProperty()设置,就是生成HTML文件头.


3.Internet发送xml数据XML格式是通信的标准语言,Android系统也可以通过发送XML文件传输数据.
1)将生成的XML文件写入到byte数组中,并设置为UTF-8:byte[] xmlbyte = xml.toString().getBytes("UTF-8");
2)创建URL对象,并指定地址和参数:URL url = new URL(http://localhost:8080/itcast/contanctmanage.do?method=readxml);
3)获得链接:HttpURLConnection conn = (HttpURLConnection) url.openConnection();
4)设置连接超时:conn.setConnectTimeout(6* 1000);
5)设置允许输出conn.setDoOutput(true);
6)设置不使用缓存:conn.setUseCaches(false);
7)设置以POST方式传输:conn.setRequestMethod("POST");           
8)维持长连接:conn.setRequestProperty("Connection", "Keep-Alive");
9)设置字符集:conn.setRequestProperty("Charset", "UTF-8");
10)设置文件的总长度:conn.setRequestProperty("Content-Length", String.valueOf(xmlbyte.length));
11)设置文件类型:conn.setRequestProperty("Content-Type", "text/xml; charset=UTF-8");
12)以文件流的方式发送xml数据:outStream.write(xmlbyte);
总结:
--我们使用的是用HTML的方式传输文件,这个方式只能传输一般在5M一下的文件.
--传输大文件不适合用HTML的方式,传输大文件我们要面向Socket编程.确保程序的稳定性--将地址和参数存到byte数组中:byte[] data = params.toString().getBytes();

 

(一)Java接口

主要类:

URL:资源定位符类

 

URLConnection:资源连接

 

HttpURLConnectiion:继承自URLConnection                 

  

// 设置是否向httpUrlConnection输出,因为这个是post请求,参数要放在   

  // http正文内,因此需要设为true, 默认情况下是false;   

  httpUrlConnection.setDoOutput(true);   

   

  // 设置是否从httpUrlConnection读入,默认情况下是true;   

  httpUrlConnection.setDoInput(true);   

   

  // Post 请求不能使用缓存   

  httpUrlConnection.setUseCaches(false);   

   

  // 设定传送的内容类型是可序列化的java对象   

  // (如果不设此项,在传送序列化对象时,WEB服务默认的不是这种类型时可能抛java.io.EOFException)   

  httpUrlConnection.setRequestProperty("Content-type", "application/x-java-serialized-object");   

   

  // 设定请求的方法为"POST",默认是GET   

  httpUrlConnection.setRequestMethod("POST");   

   

  // 连接,从上述第2条中url.openConnection()至此的配置必须要在connect之前完成,   

          httpUrlConnection.connect();

注:

a:) HttpURLConnectionconnect()函数,实际上只是建立了一个与服务器的tcp连接,并没有实际发送http请求。 

    无论是post还是gethttp请求实际上直到HttpURLConnectiongetInputStream()这个函数里面才正式发送出去。 
       b:) 在用POST方式发送URL请求时,URL请求参数的设定顺序是重中之重, 
    对connection对象的一切配置(那一堆set函数) 
    都必须要在connect()函数执行之前完成。而对outputStream的写操作,又必须要在inputStream的读操作之前。 
    这些顺序实际上是由http请求的格式决定的。 
    如果inputStream读操作在outputStream的写操作之前,会抛出例外: 
    java.net.ProtocolException: Cannot write output after reading input....... 
       
       c:) http请求实际上由两部分组成, 
    一个是http头,所有关于此次http请求的配置都在http头里面定义, 
           一个是正文content。 
    connect()函数会根据HttpURLConnection对象的配置值生成http头部信息,因此在调用connect函数之前, 
    就必须把所有的配置准备好。 
       d:) http头后面紧跟着的是http请求的正文,正文的内容是通过outputStream流写入的, 
    实际上outputStream不是一个网络流,充其量是个字符串流,往里面写入的东西不会立即发送到网络, 
    而是存在于内存缓冲区中,待outputStream流关闭时,根据输入的内容生成http正文。 
    至此,http请求的东西已经全部准备就绪。在getInputStream()函数调用的时候,就会把准备好的http请求 
    正式发送到服务器了,然后返回一个输入流,用于读取服务器对于此次http请求的返回信息。由于http 
    请求在getInputStream的时候已经发送出去了(包括http头和正文),因此在getInputStream()函数 
    之后对connection对象进行设置(对http头的信息进行修改)或者写入outputStream(对正文进行修改) 
    都是没有意义的了,执行这些操作会导致异常的发生。 

 

 

一般下载器

URL url = new URL(urlname);

HttpURLConnection con =(HttpURLConnection) url.openConnection();

con.setDoOutput(true);   

con.setDoInput(true);   

con.setUseCaches(false);  

con.setReadTimeout(2*60*1000);

//con.setRequestProperty("Content-type", "application/x-java-serialized-object");   

con.connect();

InputStream is = con.getInputStream();

 

BufferedReader br = new BufferedReader(new InputStreamReader(is));

StringBuffer sb = new StringBuffer();

String content ;

while((content=br.readLine())!=null){

//content = new String(content.getBytes(),"gbk");

sb.append(content);

}

 

(二)Apache接口

HttpClient:Http客户端类(抽象类),可有DefaultHttpClient获得

 

HttpGet/HttpPost:实现抓取网页的信息

 

Execute():开始抓取网页

 

HttpResponse类的getEntity()方法可获取网页内容

 

关于Post抓取网页

需设置以下内容----设置字符集----设置实体

 

private void initHttpClient() {

HttpGet get = new HttpGet(httpUrl);//抓取http服务器上的信息

HttpClient client = new DefaultHttpClient();

HttpResponse response = client.execute(get);//执行抓取网页信息,返回一个HttpResponse类的对象一测试是否抓取成功

if((response.getStatusLine().getStatusCode())==HttpStatus.SC_OK){

//抓取成功,可有抓取网页成功后返回的HttpResponse对象获取网页内容

result = EntityUtils.toString(response.getEntity());//获取网页内容,返回的是Entity(实体类)类,

2.Android http请求设置网络超时

HttpParams params = new BasicHttpParams();
        HttpConnectionParams . setConnectionTimeout ( params , 3000 ); 
    HttpConnectionParams . setSoTimeout ( params , 3000 );

HttpClient client = new DefaultHttpClient(params);

3.实例代码

String weatherUrl = "http://113.108.239.107/data/"+cityCode+".html";

//设置超时

HttpParams params  =new BasicHttpParams();

HttpConnectionParams.setConnectionTimeout(params, 2*60*1000);

HttpConnectionParams.setSoTimeout(params, 2*60*1000);

HttpGet get = new HttpGet(weatherUrl);

HttpResponse response=null;

HttpClient client = new DefaultHttpClient(params);

try{

response = client.execute(get);

}catch(Exception e){

//出现连接超时等意外网络情况则继续5次

Log.e(tag, e.toString());

}

if(response!=null&&response.getStatusLine().getStatusCode()==HttpStatus.SC_OK){

try {

content = EntityUtils.toString(response.getEntity());

JSONParser(content);

catch (ParseException e) {

// TODO Auto-generated catch block

Log.e(tag, e.toString());

}finally{

}

}

else{

return false;

}

return true;

}

 

二、Socket通信

(一)Android接口

封装了Http并有Socket---Wifi----Uri

主要类

(1).Socket----Wifi------Uri

(2).ExecutorService:

1.Socket

ServerSocket:服务器端

    ServerSocket server ;

    public void initServer() throws IOException{

        server = new ServerSocket(1034);//服务器端的特定端口(Port>1023

        Socket s = server.accept();//等待发出请求的客户端的socket

        //获取客户的请求,即客户所输出的输出流

        OutputStream os = s.getOutputStream();

        //变为数据输出流,筛选

        DataOutputStream dos = new DataOutputStream(os);

        dos.writeUTF("服务端已经收到消息");//向客户端写消息

注:此处只要获取了客户端的请求,再将输出流变为一个可写流,调用write可向客户端写消息

        //接受客户端信息

       InputStream is = s.getInputStream();

       BufferedReader dis = new BufferedReader(new InputStreamReader(is));

      //注:要接收客户端消息必须要获得服务端Socket的输入流,相当于要在服务器端读取客户端的消息

        server.close();//关闭服务器

总结:服务器端要向客户端接收,发送消息,必须与获得的Socket对象建立起一个通信通道:即InputStreamOutputStream/可如此理解服务器要写,所以要获取客户端的可写入流,服务器要读则要获取客户端的可读入流其中的流可理解为一个通道

 

Socket:客户端

//向服务器请求并读取服务器信息

Socket s = new Socket("118.124.6.164", 1034);//建立连接服务器的客户端

//BufferedReader os = new BufferedReader(new InputStreamReader(s.getInputStream()));//获取服务器信息

//result = os.readLine();

//showText.setText(result);

//向服务器写信息

DataOutputStream dos = new DataOutputStream(s.getOutputStream());

dos.writeChars("client send message");

//PrintWriter out = new PrintWriter(new BufferedWriter(new OutputStreamWriter(s.getOutputStream())), true);

s.close();

 

注:和服务器端一样,要向服务器写则需获取客户端Socket的可写入流。要读取服务器的消息则需要获取客户端Socket的可读入流

 

注:客户端和服务器端的输入输出要对应才行

 

2.实现多线程

ExecutorService:创建一个线程池

(1)获取线程池

Executors类的newFixedThreadPool(2)可创建一个指定容量的线程池

 newCachedThreadPool()创建一个缓冲线程池

(2)执行线程:executeRunnable)参数为一个Runnable对象

四.设置代理

1.HttpUrlConnetion

//当我们使用的是中国移动的手机网络时,下面方法可以直接获取得到10.0.0.17280端口

String host=android.net.Proxy.getDefaultHost();//通过andorid.net.Proxy可以获取默认的代理地址

int port =android.net.Proxy.getDefaultPort();//通过andorid.net.Proxy可以获取默认的代理端口

SocketAddress sa=new InetSocketAddress(host,port);

//定义代理,此处的Proxy是源自java.net

Proxy proxy=new Proxy(java.net.Proxy.Type.HTTP,sa);

URL getUrl = new URL(www.baidu.com); 

HttpURLConnection con = (HttpURLConnection) getUrl.openConnection(proxy);//设置代理

2.HttpClient

DefaultHttpClient httpClient=new DefaultHttpClient();

String host=Proxy.getDefaultHost();//此处Proxy源自android.net

int port = Proxy.getPort(context);//同上

HttpHost httpHost = new HttpHost(host, port); 

//设置代理

httpClient.getParams().setParameter(ConnRouteParams.DEFAULT_PROXY,httpHost);

HttpGet httpGet=new HttpPost("<a href="http://www.baidu.com">www.baidu.com</a>");

HttpResponse response=httpClient.execute(httpGet);

3.实例

DefaultHttpClient httpClient=new DefaultHttpClient();

//网络检测

ConnectivityManager cm = (ConnectivityManager) context.getSystemService(Context.CONNECTIVITY_SERVICE);

if(cm!=null){

NetworkInfo  ni = cm.getActiveNetworkInfo();

if(ni!=null){

if(!ni.getTypeName().equals("WIFI")){

//设置代理

String host=Proxy.getDefaultHost();

int port = Proxy.getPort(context);  

HttpHost httpHost = new HttpHost(host, port); 

httpClient.getParams().setParameter(ConnRouteParams.DEFAULT_PROXY,httpHost);

}

}

}

五.常见问题

1.二级域名无法访问

将域名换成ip

三.非阻塞IO

四.网络编程前的准备

1.使用Chrome浏览器的Http头分析插件分析HttpRequestResponse信息

Status

HTTP/1.1 200 OK

RequestAccept

text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8

Accept-Encoding

gzip,deflate,sdch

Accept-Language

zh-CN,zh;q=0.8,en;q=0.6

Cookie

lzstat_uv=32461900962640612022|3266776@2993663;
ASP.NET_SessionId=kuitmryyygrwt345l32mpj45

Referer

http://www.suse.edu.cn/

User-Agent

Mozilla/5.0 (Windows NT 6.1) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/33.0.1750.146 Safari/537.36

ResponseCache-Control

no-cache

Content-Encoding

gzip

Content-Length

10911

Content-Type

text/html; charset=utf-8

Date

Thu, 27 Mar 2014 12:16:47 GMT

Expires

-1

Pragma

no-cache,no-cache

Server

Microsoft-IIS/7.5

Vary

Accept-Encoding

X-AspNet-Version

2.0.50727

X-Powered-By

ASP.NET

2.不能获取html网页信息时的解决

使用con.setRequestProperty("User-Agent""Mozilla/5.0 (Linux; U; Android %s)");设置相关的http请求头

五.网络错误

1.不能连接到网站,总是出现连接超时

LogCat提示错误:

org.jsoup.HttpStatusException: HTTP error fetching URL. Status=404, URL=http://61.139.105.130:8080/zzxy/marks/index!list.action/?query=Java

解决办法

查看所使用的url是否正确,如下

如果使用的Url是:http://rwxy.suse.edu.cn/images/Maincn.asp/

去掉最后的”/”反斜杠,http://rwxy.suse.edu.cn/images/Maincn.asp

设置相应的属性

1)请求参数

2)User-Agent

3)Cookie

4)auth

JSoup.get().data("query","Java")//请求参数

.userAgent("Mozilla")//设置USER-AGENT

.cookie("auth""token")//设置cookie

2.不同网络下的网络访问方式导致的错误

 

详见

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值