HttpURLConnection类

本文详细介绍了如何使用HTTPURLConnection进行网络通信,包括基本使用方法、HTTPS安全连接的实现、响应处理、上传请求数据、性能优化技巧等内容。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

一)使用模式

HttpURLConnection 是一个HTTP协议的URLconnection,用来发送和接收网络上的数据。使用模式如下:

1. 调用 URL.openConnection()并强制转换结果为HTTPURLConnection类来获取一个新的HTTPURLConnection.

2. 准备请求数据。 请求的主要属性是URI, 请求头也可以包含证书, content types, 会话cookies等。

3. 上传请求数据(可选)。配置setDoOutput(true), 则可以上传请求数据。通过将请求数据写入getOutputstream()返回的流来实现。

4. 读取应答数据。 应答头通常都包含元数据,如应答主题的content type和长度, 修改时间和会话cookies等。 可以通过读取getInputStream()的返回值来获得应答主体。 如果应答主体为空,则返回空的数据流。

5. 断开连接。调用disconnect() 释放连接,该连接会被关闭或复用。

下述代码用来获取网页http://www.android.com/:

   URL url = new URL("http://www.android.com/");
   HttpURLConnection urlConnection = (HttpURLConnection) url.openConnection();
   try {
     InputStream in = new BufferedInputStream(urlConnection.getInputStream());
     readStream(in);
    finally {
     urlConnection.disconnect();
   }
 }

二)使用HTTPS实现安全的连接

使用“https"模式调用openConnection()打开URL,会返回一个HttpsURLConnection,它允许覆盖默认的HostnameVerifier和SSLSocketFatory. 从SSLContext中创建的SSLSokectFactory 会提供一个定制的X509TruestManager(用来验证证书链)和一个定制的X509KeyManager(提供客户端证书)。 具体见HttpsURLConnection

三)回复的处理

HttpURLConnection会跟踪5个HTTP跳转。 它会跟踪从原始服务器到另外服务器的跳转,但是无法从HTTPS到HTTP的跳转,或HTTP到HTTPS的跳转。

如果HTTP回复有错误发生,会抛出IOException, 使用getErrorStream()来读取异常。 正常情况下,使用getHeaderFields来读取头部数据。

四)上传请求数据

使用setDoOutput(true)配置连接。

为达到最好的性能,当数据长度确定时,可以调用setFixedLengthStreamingMode(int), 当数据不确定时,使用setChunkedStreamingMode(int). 否则,HttpURLConnection会在数据发送前,被迫缓冲完整的数据在内存中,浪费堆空间和增加不稳定性。

示例代码如下:

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

   try {
     urlConnection.setDoOutput(true);
     urlConnection.setChunkedStreamingMode(0);

     OutputStream out = new BufferedOutputStream(urlConnection.getOutputStream());
     writeStream(out);

     InputStream in = new BufferedInputStream(urlConnection.getInputStream());
     readStream(in);
    finally {
     urlConnection.disconnect();
   }
 }

五)性能

HTTPURLConnection返回的输入流和输出流不是缓存的。因此在调用需要使用BufferedInputStream或BufferedOutputStream来封装返回的数据流。 当从服务器上传或下载大量数据时, 使用流来限制内存中的数据大小。 除非你需要整个主体数据都在内存中,否则使用流来处理数据(而不是使用bytearray或string来存储完整的主体数据)。

该类会复用Socket来处理多个请求/回复。因此HTTP连接会比实际的需求持有更长时间。可以通过disconnect()来将socket返回到socket池中。 在发生HTTP请求前, 设置http.keepAlive属性为false会禁止上述行为。 http.maxConnection属性可以用来控制每个服务器持有的空闲连接的数量。

默认情况下,HTTPURLConnection会要求server端使用gzip压缩数据,在调用getInputStream()时会自动解压缩该数据。 这种情况下,回复头中的Content-Encoding 和Content-Length会被清理掉。可以通过如下设置来取消gzip压缩:

   urlConnection.setRequestProperty("Accept-Encoding", "identity"); 

getContentLength()返回传输的数据大小, 但是因为数据是压缩过的,不能用了预测getInputStream()中需要读出的数据大小。因此,应该使用read()函数返回值是-1来判断数据流的结束。

六)处理网络登录

有些WIFI网络需要用户登录后才连接互联网。这样的登录网页通常使用HTTP跳转来展示。 使用getURL()测试连接是否被跳转,该检查只有在回复头被接收后才有效, 可以通过调用getHeaderFields()或getInputStream()来确保回复头被接收。下面是检查回复是否被跳转的代码:

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

   try {
     InputStream in = new BufferedInputStream(urlConnection.getInputStream());
     if (!url.getHost().equals(urlConnection.getURL().getHost())) {
       // we were redirected! Kick the user out to the browser to sign on?
     
     ...
   } finally {
     urlConnection.disconnect();
   }
 }

七)HTTP 认证

HttpURLConnection 支持HTTP basic authentication. 使用Authenticator 来设置认证处理器:

   Authenticator.setDefault(new Authenticator() {

     protected PasswordAuthentication getPasswordAuthentication() {
       return new PasswordAuthentication(username, password.toCharArray());
     
   });
 }

除非配合HTTPS使用,这不是一个安全的用户认证机制。 用户名,密码,请求和回复手机都是明文传输的。

七)使用Cookies

为在客户端和服务端之间创建和维持一个长会话, HttpURLConnection 包含一个可扩展的cookie管理器。 使用CookieHandler 和 CookieManager 来创建cookie管理系统:

   CookieManager cookieManager = new CookieManager();
   CookieHandler.setDefault(cookieManager);
 

默认情况下,CookieManager 只接收原始服务器的cookie. 另外两个已经实现的策略是:ACCEPT_ALL 和 ACCEPT_NONE. 可以通过实现CookiePolicy 来定制策略。

默认CookieManager保存所有接收的cookie在内存总, 通过实现CookieStore可以定制cookie存储。

处理HTTP回复设置cookie外, 也可以通过代码来设置。cookie必现包含域和路径属性,以便包含在请求头中。

默认情况下,HttpCookie只支持符合RFC 2965 规范的服务器。很多网络服务器支持早期版本RFC 2109。 为保持兼容,设置cookie版本为0.

例如,接收法语版的www.twitter.com:

   HttpCookie cookie = new HttpCookie("lang", "fr");

   cookie.setDomain("twitter.com");
   cookie.setPath("/");
   cookie.setVersion(0);
   cookieManager.getCookieStore().add(new URI("http://twitter.com/"), cookie);
 

八)HTTP 方法

HttpURLConnection默认使用GET方法。 调用setDoOutput(true) 后默认使用POST方法。其他HTTP方法(OPTIONS, HEAD, PUT, DELETE 和TRACE)通过setRequestMethod(String)来设置。

九)代理

可以通过HTTP 或SOCKS 代理来连接。 使用URL.openConnection(Proxy)来创建使用代理的连接。

十)IPv6 支持

对同时有IPv4和IPv6的主机, 该类会试着连接两个地址直到连接建立。

十一)对回复的缓存

Android 4.0(Ice Cream Sandwich, API level 15)开始包含回复缓存。具体见android.net.http.HttpResponseCache。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值