为了防止无良网站的爬虫抓取文章,特此标识,转载请注明文章出处。LaplaceDemon/SJQ。

http://www.cnblogs.com/shijiaqi1066/p/3753224.html

1. URLConnection概述

URLConnection是一个抽象类,表示指向URL指定资源的活动连接。

URLConnection类本身依赖于Socket类实现网络连接。一般认为,URLConnection类提供了比Socket类更易于使用、更高级的网络连接抽象。但实际上,大多数程序员都会忽略它。因为URLConnection太贴近HTTP协议。它假定传输的内容前面都有MIME首部或类似的东西。但大多数协议(如FTP和SMTP)并不使用MIME首部。

URLConnection继承树查看如下:

URLConnection类声明为抽象类,除了connect()方法,其他方法都已经实现。URLConnection的三个实现子类都位于sun.net.www包下。

URLConnection类的保护类型的构造方法:

protected URLConnection(URL url)

  构造一个到指定 URL 的 URL 连接。

connect()方法由子类实现本地与服务器的连接方式。一般使用TCP socket,但也可以使用其他其他机制来建立。

abstract  void connect()

  打开到此 URL 引用的资源的通信链接(如果尚未建立这样的连接)。

当派生URLConnection子类时,通常会覆盖URLConnection的其他方法,使其返回有意义的值。

1.1 读取首部

String getContentType()

  返回 Content-type 头字段的值。即数据的MIME内容类型。若类型不可用,则返回null。

  除了HTTP协议,极少协议会使用MIME首部。若内容类型是文本。则Content-type首部可能会包含一个标识内容编码方式的字符集。

例:Content-type:text/html; charset=UTF-8

int getContentLength()

  返回 Content-length 头字段的值。该方法获取内容的字节数。许多服务器只有在传输二进制文件才发送Content-length首部,在传输文本文件时并不发送。若没有该首部,则返回-1。

  若需要知道读取的具体字节数,或需要预先知道创建足够大的缓冲区来保存数据时,可以使用该方法。

String getContentEncoding()

  返回 Content-encoding 头字段的值。获取内容的编码方式。若内容无编码,则该方法返回null。

  注意:Content-encoding(内容编码)与字符编码不同。字符编码方式由Content-type首部或稳定内容的信息确定,它指出如何使用字节指定字符。内容编码方式则指出字节如何编码其他字节。

例:若编码格式为x-gzip,则可以使用java.util.zip.GZipInputStream来解码。

long getDate()

  返回 date 头字段的值。获取请求的发送时间。即自1900年1月1日子夜后过去的毫秒数。

  注意:这是从服务器的角度看到的发送时间。可能与本地时间不一致。若首部不包括Date字段,则返回0。

long getExpiration()

  返回 expires 头字段的值。获取Expires的值。若无该字段,则返回0。0即表示不过期,永远缓存。

  注意:该值是自1970年1月1日上午12:00后的毫秒数。

long getLastModified()

  返回 last-modified 头字段的值。该值是自1900年1月1日子夜后过去的毫秒数。若无该字段,则返回0。

1.2 获取任意首部字段

String getHeaderField(String name)

  返回指定的头字段的值。

Map<String,List<String>> getHeaderFields()

  返回头字段的不可修改的 Map。

String getHeaderFieldKey(int n)

  返回第 n 个头字段的键。

String getHeaderField(int n)

  返回第 n 个头字段的值。

long getHeaderFieldDate(String name, long Default)

  返回解析为日期的指定字段的值。

int getHeaderFieldInt(String name, int Default)

  返回解析为数字的指定字段的值。

1.3 配置连接

URLConnection类的保护类型字段如下:

protected  URL url

  该字段指定URLConnection连接的URL。构造函数会在创建URLConnection时设置,此后就不能再改变。

protected  boolean connected

  当连接打开时,该字段为true。若连接关闭,则为false。没有直接读取或改变connected值的方法。任何导致URLConnection连接的方法都会将此变量设为true,包括connect(),getInputStream(),和getOutputStream()。

  任何导致URLConnection断开的方法都会将此字段设为false。

  java.net.URLConnection没有断开方法,但一些子类,如java.net.HttpURLConnection中存在这样的方法。

protected  boolean allowUserInteraction

  该字段表示是否允许与用户交互。默认为false,即不允许交互。该值只能在URLConnection连接前设置。

例:Web浏览器可能需要访问用户名和口令。

protected  boolean doInput

  该字段在URLConnection可用于输入时为true,否则为false。默认为true。

protected  boolean doOutput

  该字段在URLConnection可用于输出时为true,否则为false。默认为false。

protected  long ifModifiedSince

  该字段指示了将放置If-Modified-Since首部字段中的日期(格林威治标准时间1970年1月1日子夜后的毫秒数)。

protected  boolean useCaches

  该字段指定了是否可以在缓存可用时使用缓存。默认为true,表示缓存将被使用;false表示缓存不被使用。

以上字段定义了客户端如何向服务器作出请求。这些字段只能在URLConnection连接前修改。否则抛出IllegalStateException异常。

每个字段都有一些相应的方法。

  • URL getURL()
  • void setDoInput(boolean doinput)
  • boolean getDoInput()
  • void setDoOutput(boolean dooutput)
  • boolean getDoOutput()
  • void setUseCaches(boolean usecaches)
  • boolean getUseCaches()
  • void setAllowUserInteraction(boolean allowuserinteraction)
  • boolean getAllowUserInteraction()
  • void setIfModifiedSince(long ifmodifiedsince)
  • long getIfModifiedSince()

还有一些方法,这些方法用于定义和获取URLConnection对象的默认行为:

  • static boolean getDefaultAllowUserInteraction()
  • boolean getDefaultUseCaches()
  • void setDefaultUseCaches(boolean defaultusecaches)
  • static void setDefaultAllowUserInteraction(boolean defaultallowuserinteraction)
  • static void setFileNameMap(FileNameMap map)
  • static FileNameMap getFileNameMap()

1.4 关于超时

Java 1.5增加了如下4个方法,允许查询和修改连接的超时值。即底层socket在抛出SocketTimeoutException异常前等待远端响应时间。

设置获取读取的超时值,单位为毫秒。

int getReadTimeout()

void setReadTimeout(int timeout)

  设置获取连接的超时值,单位为毫秒。

int getConnectTimeout()

void setConnectTimeout(int timeout)

  这四个方法将0解释为永不超时。如果超时值为负数。两个设置方法都会抛出IllegalArgumentException异常。

1.5 配置HTTP首部

客户端向服务器发送请求,不仅会发送请求行,还发送首部。Web服务器可以根据此信息向不同客户端提供不同的页面,获取和设置cookie,通过口令设置用户等等。通过在客户端发送和服务器响应的首部中放置不同的字段,就可以完成这些工作。

每个URLConnection的具体子类都在首部中设置一些默认的键值对(实际上只有HttpURLConnection这样做,因为HTTP是唯一以这种方式使用首部的主要协议。)

通过以下方法可以设置URLConnection在打开连接增加HTTP首部:

void setRequestProperty(String key, String value)

  此方法只在连接打开之前打开,将会抛出IllegalStateException异常。但该方法仅支持对一个首部设置一个值。

HTTP允许一个熟悉有多个值。各个值之间用逗号隔开。

例:cookie:username=sjq; session=hdfu23asdjf901j;

使用如下方法为首部增加值:

void addRequestProperty(String key, String value)

  该方法用于添加某个指定首部字段的值。

使用如下方法获取首部字段:

String getRequestProperty(String key)

Map<String,List<String>> getRequestProperties()

  以上方法用于获取URLConneciton所拥有HTTP首部。

1.6 使用URLConnection与服务器交互

InputStream getInputStream()

  返回从此打开的连接读取的输入流。

OutputStream getOutputStream()

  返回写入到此连接的输出流。

若只是向服务器请求数据,则为HTTP请求方法为GET。

若需要向服务器提交数据,必须在先调用setDoOutput(true)。当doOutput属性为true时,请求方法将由GET变为POST。

例:获URLConnection实例对象。

@Test
public void test(){
try {
URL url = new URL("http://www.baidu.com");
URLConnection uc = url.openConnection();
} catch (MalformedURLException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}

例:使用URLConnection请求Baidu首页。

该程序请求方法为get。使用getInputStream()方法输出的内容只有响应体,不包含响应的首部。

	@Test
public void testGetInputStream(){
InputStream in = null;
try {
//连接
URL url = new URL("http://www.baidu.com");
URLConnection uc = url.openConnection(); //获取读入流
in = uc.getInputStream();
//放入缓存流
InputStream raw = new BufferedInputStream(in);
//最后使用Reader接收
Reader r = new InputStreamReader(raw); //打印输出
int c;
while((c = r.read())>0){
System.out.print((char)c);
} } catch (MalformedURLException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
} finally{
try {
if(in!=null){
in.close();
}
} catch (IOException e) {
e.printStackTrace();
}
}
}

1.6 获得内容

Object getContent()

  该方法实质上与URL类的getContent()方法相同。使用该方法JVM需要识别和理解该内容类型。该方法只用于支持类似HTTP的协议,协议需要对MIME内容类型有较清楚的了解。若内容未知,或协议无法理解内容类型,getContent()会抛出一个UnknowServiceException异常。

Object getContent(Class[] classes)

  该方法可以选择将内容转换为哪个类对象,以提供数据的不同对象表示。该方法尝试以classes数组中某个类的形式返回内容。优先顺序就是数组的顺序。若任何一种请求类型都不可用,此方法会返回null。

1.7 ContentHandlerFactory

URLConnection类包括一个静态的ContentHandler。即内容处理器。通过以下方法设置内容处理器工厂。

static void setContentHandlerFactory(ContentHandlerFactory fac)

1.8 URLConnection的安全

建立网络连接、读写文件等等存在一些安全限制,URLConnection对象会受到这些安全限制的约束。

Permission getPermission()

  该方法返回Permission对象,指出连接此URL所需的许可权。如果没有所需的许可权(即没有适当的安全管理器),它就会返回null。

1.9 猜测MIME内容类型

static String guessContentTypeFromName(String fname)

  根据 URL 的指定 "file" 部分尝试确定对象的内容类型。

static String guessContentTypeFromStream(InputStream is)

  根据输入流的开始字符尝试确定输入流的类型。

2. HttpURLConnection

java.net.HttpURLConnection类是URLConnection的抽象子类;它提供了一些有助于专门操作http URL的额外方法。

sun.net.www.protocol.http包中也提供了一个HttpURLConnection类。该类实现了抽象的connect()方法。但一般很少直接访问该类。

2.1 获取HttpURLConnection对象

@Test
void testHttpURLConnection(){
try {
URL url = new URL("http:www.baidu.com");
URLConnection urlConnection = url.openConnection();
HttpURLConnection httpURLConnection = (HttpURLConnection)urlConnection;
} catch (MalformedURLException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}

2.2 请求方法

HTTP协议提供了7中请求方法:

  • GET
  • POST
  • HEAD
  • PUT
  • OPTIONS
  • DELETE
  • TRACE

通过以下方法设置请求方法:

void setRequestMethod(String method)

若请求不是7个方法的字符串,则会抛出java.net.ProtocolException异常。一般只设置请求方法是不够的,还需要调整HTTP首部,还要提供消息体。

以下方法获取HTTP请求方法

String getRequestMethod()

2.3 断开与服务器的连接

HTTP的Keep-Alive对Web连接的性能有所提升,允许多个请求和响应通过一个TCP连接连续发送。

客户端通过HTTP请求首部包含Connection字段及Keep-Alive,表示客户端愿意使用Keep-Alive:

  Connection: Keep-Alive

但当使用Keep-Alive时,服务器不再因为向客户端发送最后一个字节数据就关闭连接。毕竟客户端还可能发送另一个请求。因此客户端需要复杂关闭连接。

Java提供如下方法关闭连接,实际上很少使用该方法:

abstract  void disconnect()

2.4 获取请求

如果HTTP响应状态为4xx(客户端错误)或者5xx(服务器错误),你可以通过HttpUrlConnection.getErrorStream()来查看服务器发送过来的信息。

InputStream getErrorStream()

例:

InputStream error = ((HttpURLConnection) connection).getErrorStream();

如果HTTP响应状态为-1,就是出现了连接错误。HttpURLConnection会保持连接一直可用,如果你想关闭这个特性,需要把http.keepAlive设置为false:

System.setProperty("http.keepAlive", "false");

2.5 Http响应码

HTTP响应的第一行被称为消息响应。该信息不会被URLConnection的getHeaderFiled()方法读取。

String getResponseMessage()

  返回消息响应。如:HTTP/1.1 404 Not Found

int getResponseCode()

  返回消息响应码。如:404。

HttpURLConnection类提供了常见响应码常量。具体请参考JDK文档。

2.6 重定向

默认情况下,HttpURLConnection类会跟踪重定向。但HttpURLConnection有两个静态方法,可以确定是否跟随重定向。

static void setFollowRedirects(boolean set)

static boolean getFollowRedirects()

  若跟随,则为true,否则为false。

这两个是静态方法,它们会改变该方法后构造的所有HttpURLConnection对象的行为。若安全管理器不允许其改变,则会抛出SecurityException异常。

也可以对某个HttpURLConnection实例设置是否重定向。

void setInstanceFollowRedirects(boolean followRedirects)

boolean getInstanceFollowRedirects()

2.7 代理

HttpURLConnection可以得知请求是否通过了代理服务器。

使用如下方法:

abstract  boolean usingProxy()

2.8 流模式

每个发送给HTTP服务器的请求都有HTTP首部。首部中有一个Content-type字段;即请求体中的字节数。首部位于主体的前面。但是,为了写入首部,需要知道主体的长度,而在写首部的时候可能还不知道主题的长度。一般情况下Java对此两难境地的解决办法是,对于从HttpURLConnection获取的OutputStream,缓存写入到此OutputStream中的所有内容,直到流被关闭。到这时,它就知道了主题中有多少字节,

在请求发送之前,HttpURLConnetion会把所有需要发送的数据放到缓冲区里,不管你是否使用connection.setRequestProperty("Content-Length", contentLength);设置了contentLength,当你并行发送大量的POST请求时,这可能会引起OutOfMemoryExceptions 异常,为了避免这个问题,需要使用如下方法:

void setFixedLengthStreamingMode(int contentLength)

  此方法用于在预先已知内容长度时启用没有进行内部缓冲的 HTTP 请求正文的流。

例:

httpConnection.setFixedLengthStreamingMode(contentLength);

但是如果不能事先知道内容的长度,可以使用HttpURLConnection.setChunkedStreamingMode()方法设置为块状流模式。在块状流模式的情况下,放在块里的内容将会被强行发送出去。下边的例子将会把发送的内容按照每块1KB的大小发送出去。

void setChunkedStreamingMode(int chunklen)

  此方法用于在预先不知道内容长度时启用没有进行内部缓冲的 HTTP 请求正文的流。

例:

httpConnection.setChunkedStreamingMode(1024);

2.9 缓存

默认情况下,Java 1.5不返回任何数据。但通过派生java.net.ResponseCache类的子类,并安装为系统默认值,就可以创建自己的缓存。无论系统合适尝试通过协议处理器加载新的URL,它将首先在缓存中查找,若缓存找到了所需的内容,就不需要连接远程服务器了。若缓存数据不存在,则下载相应数据,并将其放入缓存中。

为了防止无良网站的爬虫抓取文章,特此标识,转载请注明文章出处。LaplaceDemon/SJQ。

http://www.cnblogs.com/shijiaqi1066/p/3753224.html

URLConnection类详解的更多相关文章

  1. URLConnection类详解-转

    转-http://www.cnblogs.com/shijiaqi1066/p/3753224.html 1. URLConnection概述 URLConnection是一个抽象类,表示指向URL指 ...

  2. 【通信】JDK中的URLConnection参数详解

    JDK中的URLConnection参数详解 来自:http://www.blogjava.net/supercrsky/articles/247449.html 针对JDK中的URLConnecti ...

  3. java之StringBuffer类详解

    StringBuffer 线程安全的可变字符序列. StringBuffer源码分析(JDK1.6): public final class StringBuffer extends Abstract ...

  4. java之AbstractStringBuilder类详解

    目录 AbstractStringBuilder类 字段 构造器 方法   public abstract String toString() 扩充容量 void  expandCapacity(in ...

  5. java之StringBuilder类详解

    StringBuilder 非线程安全的可变字符序列 .该类被设计用作StringBuffer的一个简易替换,用在字符串缓冲区被单个线程使用的时候(这种情况很普遍).如果可能,建议优先采用该类,因为在 ...

  6. Java String类详解

    Java String类详解 Java字符串类(java.lang.String)是Java中使用最多的类,也是最为特殊的一个类,很多时候,我们对它既熟悉又陌生. 类结构: public final ...

  7. QAction类详解:

    先贴一段描述:Qt文档原文: Detailed Description The QAction class provides an abstract user interface action tha ...

  8. JAVAEE学习——struts2_01:简介、搭建、架构、配置、action类详解和练习:客户列表

    一.struts2是什么 1.概念 2.struts2使用优势以及历史 二.搭建struts2框架 1.导包 (解压缩)struts2-blank.war就会看到 2.书写Action类 public ...

  9. Struts2-整理笔记(二)常量配置、动态方法调用、Action类详解

    1.修改struts2常量配置(3种) 第一种 在str/struts.xml中添加constant标签 <struts> <!-- 如果使用使用动态方法调用和include冲突 - ...

随机推荐

  1. 共享式以太网与交换式以太网的性能比较(OPNET网络仿真实验)

      一.实验目的 比较共享式以太网和交换式以太网在不同网络规模下的性能. 二.实验方法 使用opnet来创建和模拟网络拓扑,并运行分析其性能. 三.实验内容 3.1   实验设置(网络拓扑.参数设置. ...

  2. 使用Style自定义ListView快速滑动图标

    一.显示ListView快速滑动块图标 设想这样一个场景,当ListView的内容有大于100页的情况下,如果想滑动到第80页,用手指滑动到指定位置,无疑是一件很费时的事情,如果想快速滑动到指定的位置 ...

  3. jsp的url后跟中文参数传参出现乱码

    ①重新编码:String urlParam= request.getParameter("urlParam");  urlParam= new String(urlParam.ge ...

  4. 迅雷创始人程浩:创业公司5招做好内部创新(组建小型敢死队:一共3个人,一个产品经理,两个研发;腾讯做不做这个项目是一个伪命题;让用户来验证,而不是相反 good)

    欢迎关注“创事记”的微信订阅号:sinachuangshiji 文/程浩 编者按:本文首发于微信公众号“浩哥说”(ID:haogetalks),作者程浩,迅雷创始人.内容为作者在混沌AI成长营上的演讲 ...

  5. Linux iconv使用

    iconv [选项]文件 输入/输出格式规范:-f, --from-code=名称 原始文本编码-t, --to-code=名称 输出编码 信息:-l, --list 列举所有已知的字符集 输出控制: ...

  6. java 表格项的删除、编辑、增加 修改版

    修改之后的java 代码: package com.platformda.optimize; import java.awt.BorderLayout; import java.awt.Button; ...

  7. 【POJ】2117 Electricity

    无向图求割点和连通块. /* POJ2117 */ #include <iostream> #include <vector> #include <algorithm&g ...

  8. bzoj1391

    很像最大权闭合子图的题目s向每个工作连边,流量为收益每个工序,由工作i向对应机器连边,流量为租用费每个机器向t连边,流量为购买费显然跑最小割,ans=总收益-mincut ; type node=re ...

  9. 【Mongous】write after end

    执行1(---) 执行2(----) 完成1(POST) 执行3(---)

  10. MySQL中的类Decode用法

    SELECT DISTINCT ( CASE ' THEN '关羽' ' THEN ' 张飞' ' THEN ' 赵云' ' THEN ' 马超' ' THEN ' 黄忠' ' THEN ' 魏延' ...