转-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实例对象。
1 2 3 4 5 6 7 8 9 10 11 | @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()方法输出的内容只有响应体,不包含响应的首部。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 | @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对象
1 2 3 4 5 6 7 8 9 10 11 12 | @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,它将首先在缓存中查找,若缓存找到了所需的内容,就不需要连接远程服务器了。若缓存数据不存在,则下载相应数据,并将其放入缓存中。
URLConnection类详解
为了防止无良网站的爬虫抓取文章,特此标识,转载请注明文章出处。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实例对象。
1 2 3 4 5 6 7 8 9 10 11 | @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()方法输出的内容只有响应体,不包含响应的首部。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 | @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对象
1 2 3 4 5 6 7 8 9 10 11 12 | @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
昵称:
订阅评论
[Ctrl+Enter快捷键提交]
公告
| ||||||
日 | 一 | 二 | 三 | 四 | 五 | 六 |
---|---|---|---|---|---|---|
31 | 1 | 2 | 3 | 4 | 5 | 6 |
7 | 8 | 9 | 10 | 11 | 12 | 13 |
14 | 15 | 16 | 17 | 18 | 19 | 20 |
21 | 22 | 23 | 24 | 25 | 26 | 27 |
28 | 29 | 30 | 1 | 2 | 3 | 4 |
5 | 6 | 7 | 8 | 9 | 10 | 11 |
搜索
我的标签
- 时间序列数据库(1)
随笔分类
- Android(1)
- AngularJS(1)
- Apache Ant(2)
- C/C++编程基础
- Docker
- Git
- Hadoop(4)
- HBase(1)
- HTML5(2)
- IDE应用(1)
- Java Guava
- Java 网络编程(8)
- Java并发编程(24)
- Java基础(5)
- JQuery(1)
- JVM(5)
- Linux C编程(3)
- Linux基础(7)
- Linux运维(2)
- Luncen(1)
- MySQL研发
- MySQL运维(8)
- Netty(6)
- Node.js(2)
- NoSQL
- Scala编程(16)
- Spring
- Windows(2)
- ZooKeeper(6)
- 编码、加密、压缩(2)
- 分布式系统(3)
- 计算机网络(5)
- 进阶之路(3)
- 软件架构(2)
- 设计模式(2)
- 数据结构
- 序列化框架
随笔档案
- 2019年3月 (2)
- 2018年7月 (1)
- 2018年4月 (1)
- 2018年3月 (2)
- 2018年2月 (1)
- 2017年6月 (1)
- 2017年4月 (1)
- 2017年2月 (2)
- 2017年1月 (1)
- 2016年12月 (2)
- 2016年11月 (3)
- 2016年10月 (5)
- 2016年9月 (1)
- 2016年8月 (10)
- 2016年7月 (1)
- 2016年6月 (1)
- 2016年2月 (27)
- 2016年1月 (12)
- 2015年12月 (2)
- 2015年10月 (2)
- 2015年9月 (10)
- 2015年8月 (7)
- 2015年7月 (11)
- 2015年6月 (5)
- 2015年3月 (2)
- 2015年2月 (2)
- 2014年11月 (2)
- 2014年10月 (1)
- 2014年8月 (2)
- 2014年7月 (11)
- 2014年6月 (4)
- 2014年5月 (4)
- 2014年1月 (1)
- 2013年12月 (3)
- 2013年11月 (15)
- 2013年10月 (4)
- 2013年9月 (5)
- 2012年10月 (1)
最新评论
- 1. Re:Ant学习笔记(1) 基础知识
- 很好!
- --wd1995
- 2. Re:Java泛型总结
- 牛! 看了好久,累死了。
- --wanxiaowei
- 3. Re:Linux进程管理
- 谢谢
- --紫色飞猪
- 4. Re:Linux软件安装,RPM与YUM
- 很详细,转了!
- --hz_pythoner
- 5. Re:权限系统与RBAC模型概述
- 非常全面仔细,找了好久,这个感觉最全面了。作者应该也是总结了好久。感谢
- --芊度
- 6. Re:iptables学习笔记
- 写的很好,感谢分享,转载了
- --小杜比亚
- 7. Re:MySQL用户与权限管理
- 非常不错的文档。如果方便的话,把测试时候所用的Mysql版本加上去会更严谨些。毕竟Mysql不同版本之间是有很多差别的。比如Password 就不再是Password 而是...
- --wenluderen
- 8. Re:Genymotion无法启动Virtual Box
- 问题解决了,感谢!
- --Mr.郑
- 9. Re:理解领域模型
- 充血模型的service或model中的方法容易重复。
业务实体,数据实体,消息传输实体的属性重复。。。
重复劳动太多,不知如何解决?
- --罗里罗嗦夫斯基
阅读排行榜
- 1. 使用PuTTY在Windows中向Linux上传文件(27231)
- 2. 使用SBT构建Scala项目(15702)
- 3. URLConnection类详解(14774)
- 4. 在AngularJS的controller外部直接获取$scope(12611)
- 5. 权限系统与RBAC模型概述(10317)
- 6. Java并发——线程池Executor框架(9599)
- 7. C++调用C函数(9245)
- 8. Linux编译安装MySQL5.6(9063)
- 9. Eclipse配置使用web.xml(8787)
- 10. 给Chrome和Firefox添加js脚本作为插件的方法(7176)
- 11. CGLIB学习笔记(6478)
- 12. Java并发——Fork/Join框架与ForkJoinPool(6271)
- 13. Linux进程管理(5652)
- 14. Ant学习笔记(2) 在Eclipse中使用Ant(4757)
- 15. Java并发——线程安全、线程同步、线程通信(4186)
- 16. 使用WebSocket构建实时WEB(3953)
- 17. Linux软件安装,RPM与YUM(3837)
- 18. Java泛型总结(3572)
- 19. Express 4.x Node.js的Web框架(2537)
- 20. 任务管理器设置相关性(2454)
推荐排行榜
- 1. Java泛型总结(2)
- 2. Linux软件安装,RPM与YUM(2)
- 3. 权限系统与RBAC模型概述(2)
- 4. 使用PuTTY在Windows中向Linux上传文件(1)
- 5. Socket.IO 概述(1)
- 6. Java并发——线程池Executor框架(1)
- 7. 配置SSH免密码验证(1)
- 8. 使用SBT构建Scala项目(1)
- 9. HTML5 Canvas 2D绘图(1)
- 10. Java并发——Fork/Join框架与ForkJoinPool(1)
- 11. Java 并发——多线程基础(1)
- 12. Java Socket 学习笔记(1)
- 13. MySQL用户与权限管理(1)
- 14. Ant学习笔记(2) 在Eclipse中使用Ant(1)
- 15. Ant学习笔记(1) 基础知识(1)