android中URLConnection和HttpURLConnection

一.URLConnection

 读或写的一个URL的一个连接。文档的HTTP连接,请参阅HttpURLConnection HTTP-specific特性。

例如,要检索ftp://mirror.csclub.uwaterloo.ca/index.html
URL url = new URL("ftp://mirror.csclub.uwaterloo.ca/index.html");
   URLConnection urlConnection = url.openConnection();
   InputStream in = new BufferedInputStream(urlConnection.getInputStream());
   try {
     readStream(in);
   } finally {
     in.close();
   }
URLConnection必须配置在连接到远程资源之前。 URLConnection实例不重用:你必须使用不同的实例为每个连接到一个资源。

超时

URLConnection支持两种超时:连接超时,读取超时。默认情况下,操作永远不会超时。

内置协议

  • File
    从本地文件系统可以加载使用文件:URIs。文件连接只能用于输入。
  • FTP
    支持文件传输协议(RFC 959),但是没有公共子类。FTP连接可用于输入或输出而不是两者都是。

    默认情况下,使用FTP连接将使用匿名用户名和密码为空字符串。指定可选的用户名和密码在URL:ftp://username:password@host /路径。

  • HTTP and HTTPS
    参考HttpURLConnection和HttpsURLConnection子类。
  • Jar
    参考JarURLConnection子类。

Registering Additional Protocols

使用URL.setURLStreamHandlerFactory(java.net.URLStreamHandlerFactory)注册来处理其他协议。

HttpURLConnection

适用于HTTP(RFC 2616)的URLConnection,用于在网络上发送和接受数据。这个类可以用来发送或者接受那些事先不知道长度的流式数据。

可以采用如下方式使用这个类:

1.通过调用URL.openConnection()方法,再执行强制类型转换获取HttpURLConnection实例。

2.准备请求。一个网络请求的主要组成部分就是URI,请求头也可能包含凭证、首选内容类型、Session Cookies等数据。

3.请求体是可选的上传内容,一个HttpURLConnection对象要想携带请求体必须设置setDoOutput(true)。通过写入getOutputStream()返回的流来传输数据。

4.读取响应。响应数据的头部通常包含有例如数据内容类型、长度、修改日期以及Session Cookies等元数据。响应数据可以通过getInputStream()返回的流来读取。如果没有响应数据,这个方法会返回一个空的流。

5.断开连接。一旦返回的数据读取完毕,HttpURLConnection应该通过调用disconnect()被关闭。断开连接会释放连接使用的资源,以使这些资源被关闭或回收。

例如,获取http://www.android.com/的网页数据代码如下:

1 URL url = new URL("http://www.android.com/");
2    HttpURLConnection urlConnection = (HttpURLConnection) url.openConnection();
3    try {
4      InputStream in = new BufferedInputStream(urlConnection.getInputStream());
5      readStream(in);
6     finally {
7      urlConnection.disconnect();
8    }
9  }

HTTPS安全通信

调用openConnection()时如果URL前缀是https可以获得一个HttpsURLConnection实例,可以重写默认的HostnameVerifier和SSLSocketFactory。一个应用程序提供的从SSLConext创建出的SSLSocketFactory可以提供一个自定义用于验证证书链的X509TrustManager和一个自定义用于提供终端证书的X509KeyManager。详细内容会在HttpsURLConnection中介绍。

处理响应

HttpURLConnection至多会支持五次HTTP重定向,能够跟随重定向从一个原始服务器指向另一个服务器。但是不支持从HTTPS到HTTP的重定向,反之亦然。

如果HTTP响应显示发生错误,getInputStream()会抛出IOException异常。通过getErrorStream()可以读取错误信息。头部数据通常可以通过getHeaderFields()读取。

发送数据

要上传数据到web服务器,需要通过setDoOutput(true)将connection设置为用于输出。

为了达到最佳的性能,你应该:

如果数据长度已知,设置setFixedLengthStreamingMode(int)

如果数据长度未知,设置setChunkStramingMode(int)

否则,HttpURLConnection会强制在传输数据前将整个请求体缓存于内存中,浪费(或有可能耗尽)堆空间并且增大延迟。

上传数据的示例代码如下:

 1 HttpURLConnection urlConnection = (HttpURLConnection) url.openConnection();
 2    try {
 3      urlConnection.setDoOutput(true);
 4      urlConnection.setChunkedStreamingMode(0);
 5 
 6      OutputStream out = new BufferedOutputStream(urlConnection.getOutputStream());
 7      writeStream(out);
 8 
 9      InputStream in = new BufferedInputStream(urlConnection.getInputStream());
10      readStream(in);
11     finally {
12      urlConnection.disconnect();
13    }
14  }

 性能

通过本类获取的输入和输出流不会被缓存。大多数调用时都应该通过BufferedInputStream或BufferedOutputStream来封装返回的原始流。批量读取或写入的调用或可忽略缓存。

当与服务器有大量数据传输时,应使用流来限制内存中同一时间内数据量。除非你需要一次性将所有数据存入内存,将其按照一整个流来处理(而不是将数据视为byte或字符串数组来排序)。

为了减少延迟,HttpURLConnection可以在处理多种请求/响应时使用相同的底层Socket。这导致的结果就是HTTP连接的开启时间可能会比需要的更长。调用disconnect()可能将这个socket返回至一个存有已连接Socket的池中。为了避免这种现象,可以在发出任何HTTP请求前将系统属性http.keepAlive设置为false。http.maxConnections可以用来控制针对每一个服务器会有多少闲置连接被保持。

默认情况下,HttpURLConnection的这种实现会要求服务器使用gzip压缩。所以,虽然getContentLength()能够返回传输的比特数,但你不应依赖这个方法来预计从getInputStream()可以获得的字节数。相反地,你应该一直从流中读取数据直到读完为止,也就是当read()返回-1时。Gzip压缩可以在请求头部的accept encoding出进行设置以禁用:

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

处理网络登录

有些Wi-Fi网络需要用户登录才能提供正常服务。此类登录页面通常通过HTTP重定向实现。你可以通过getURL()来测试你的连接是否被异常重定向。在请求的头部数据被接收到之前,这个方法是无效的,你可以通过getHeaderFields()或getInputStream()来触发头部数据被接收的操作。

下面是一段检测请求是否被重定向至其他主机的代码:

 1 HttpURLConnection urlConnection = (HttpURLConnection) url.openConnection();
 2    try {
 3      InputStream in = new BufferedInputStream(urlConnection.getInputStream());
 4      if (!url.getHost().equals(urlConnection.getURL().getHost())) {
 5        // we were redirected! Kick the user out to the browser to sign on?
 6      
 7      ...
 8    } finally {
 9      urlConnection.disconnect();
10    }
11  }

HTTP认证

HttpURLConnection支持Http基础认证。使用Authenticator来设置VM级的认证处理器:

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

除非与HTTPS搭配使用,这并不是一种安全的用户认证机制。特别需要注意的是,通过网络传输的用户名、密码、请求数据和响应数据都是未加密的。


Sessions with Cookies

建立并维护一个潜在的长期的客户端和服务器之间的会话,HttpURLConnection包括一个可扩展的cookie管理。vm-wide cookie管理使用CookieHandler和CookieManager:
CookieManager cookieManager = new CookieManager();
   CookieHandler.setDefault(cookieManager);
默认情况下,CookieManager只接受从原始服务器的cookie 其他两个策略包括:CookiePolicy. ACCEPT_ALL CookiePolicy.ACCEPT_NONE。 实现CookiePolicy定义一个自定义的政策。
在内存中CookieManager默认保持所有接受饼干。它会忘记这些饼干当虚拟机退出。实现CookieStore定义一个自定义的cookie存储。
除了HTTP响应的cookie,你可以以编程方式设置cookie。包含在HTTP请求头,cookie有域和路径属性设置。
默认情况下,新HttpCookie实例只支持RFC 2965的cookie的服务器许多web服务器只支持旧的规范RFC 2109。兼容大多数web服务器,将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 Methods

HttpURLConnection默认使用GET方法。 如果使用post方式,则必须设置setDoOutput(true)。 其他HTTP方法(OPTIONS, HEAD, PUT, DELETE and TRACE)可以用setRequestMethod(java.lang.String)设置。

Proxies

默认情况下,这个类将直接连接到原始服务器。 它也可以通过HTTP或SOCKS代理连接。 使用一个代理,在创建连接时使用URL.openConnection(代理)。

IPv6 Support

对于IPv4和IPv6地址的主机,它将尝试连接到每个主机的地址,直到建立连接。

Response Caching

Android 4.0包括一个响应缓存。详情见android.net.http.HttpResponseCache说明在应用程序中启用HTTP缓存。

Avoiding Bugs In Earlier Releases

Android 2.2(Froyo)之前,这个类有一些令人沮丧的bug。特别是,调用close()一个可达的InputStream可能会败坏连接池。解决这个通过禁用连接池:
private void disableConnectionReuseIfNecessary() {
   // Work around pre-Froyo bugs in HTTP connection reuse.
   if (Integer.parseInt(Build.VERSION.SDK) < Build.VERSION_CODES.FROYO) {
     System.setProperty("http.keepAlive", "false");
   }
 }
HttpURLConnection的每个实例可以使用一对请求/响应。 这个类的实例并不是线程安全的。




  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Android Studio,可以使用HttpURLConnection类来进行网络连接和数据传输。以下是一个简单的示例代码,展示如何使用HttpURLConnection发送GET请求并接收响应: ```java import java.io.BufferedReader; import java.io.IOException; import java.io.InputStream; import java.io.InputStreamReader; import java.net.HttpURLConnection; import java.net.URL; public class MainActivity { public static void main(String[] args) { HttpURLConnection connection = null; BufferedReader reader = null; try { URL url = new URL("https://www.example.com/api/data"); // 设置要请求的URL connection = (HttpURLConnection) url.openConnection(); connection.setRequestMethod("GET"); // 发送请求 int responseCode = connection.getResponseCode(); if (responseCode == HttpURLConnection.HTTP_OK) { // 读取响应 InputStream inputStream = connection.getInputStream(); reader = new BufferedReader(new InputStreamReader(inputStream)); StringBuilder response = new StringBuilder(); String line; while ((line = reader.readLine()) != null) { response.append(line); } System.out.println(response.toString()); } else { System.out.println("Error: " + responseCode); } } catch (IOException e) { e.printStackTrace(); } finally { if (connection != null) { connection.disconnect(); } if (reader != null) { try { reader.close(); } catch (IOException e) { e.printStackTrace(); } } } } } ``` 这段代码通过创建一个URL对象,并将其传递给HttpURLConnection来建立连接。然后设置请求方法为GET,并发送请求。通过检查响应码来确定是否成功接收响应,并通过输入流和缓冲读取器来读取响应数据。 请注意,在Android开发,网络请求应该在后台线程执行,以避免阻塞主线程。上述示例仅用于演示目的,实际使用应将代码放置在适当的位置,例如异步任务或单独的线程
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值