概述: URLConnection
URLConnection
是一个抽象类,表示指向URL【指定资源】的活动连接
URLConnection
可以检查服务器发送的首部,并相应地做出响应。- 它可以设置客户端请求中使用的首部字段。
URLConnection
可以用POST、PUT和其他HTTP请求方法向服务器发回数据;URLConnection
类是Java
的协议处理器机制的一部分
URLConnection 的7种URL协议实现
-
URL对象通过
openConnection()
可以获得的URLConnection
的子类实现的连接对象 -
URL对象支持7种协议————子类实现:
FileURLConnection
FtpURLConnection
HttpURLConnection
HttpsURLConnection
JarURLConnection
MailToURLConnection
这几种连接对象,都在包
sun.net.www.protocol
包下面。
区别: URL vs. URLConnection
- URL和URLConnection这两个类最大的不同在于:
- URLConnection提供了对HTTP首部的访问;
- URLConnection可以配置发送给服务器的请求参数;
- URLConnection除了读取服务器数据外,还可以向服务器写入数据;
打开 URLConnection : openConnection()
- 直接使用URLConnection类的程序遵循以下基本步骤:
- 构造一个URL对象;
- 调用这个URL对象的openConnection()获取一个对应该URL的URLConnection对象;
- 配置这个URLConnection;
- 读取首部字段;
- 获得输入流并读取数据;
- 获得输出流并写入数据;
- 关闭连接;
注:并不一定执行所有这些步骤。看你需不需要!
URLConnection
类仅有的一个构造函数为protected
类型:
protected URLConnection(URL url)
String urlPath = "http://www.baidu.com"; //"file://d:/xx/yy/demo.txt" , "ftp://dd/gg/jh/demo.txt"
try {URL url = new URL(urlPaht);URLConnection connection = url.openConnection();//从URL读取...
} catch (Exception e) {// TODO: handle exception
}
读取服务器的数据
- 下面是使用
URLConnection
对象从一个URL获取数据所需的最起码的步骤:
- 构造一个URL对象;
- 调用这个URL对象的openConnection()方法,获取对应该该URL的URLConnection对象;
- 调用这个URLConnection的getInputStream()方法;
- 使用通常的流API读取输入流;
- getInputStream()方法返回一个通用InputStream,可以读取和解析服务器发送的数据:
public class Test {public static void main(String[] args) {try {//打开URLConnection进行读取URL url = new URL("http://www.baidu.com");URLConnection connection = url.openConnection();try (InputStream in = connection.getInputStream()){ //带资源的try-catch语句,自动关闭InputStream buffer = new BufferedInputStream(in);//将InputStream串链到一个ReaderReader reader = new InputStreamReader(buffer);int c;while ((c = reader.read())!= -1) {System.out.print((char)c);}} catch (MalformedURLException e) {}} catch (IOException e) {}}
}
读取指定的首部字段
- 可以获取请求首部中特定的常用字段的方法:
- Content-Type
- Content-Length
- Content-encoding
- Date
- Last-modified
- Expires
public String getContentType()
- getContentType()
返回响应主体的MIME内容类型。如果没有提供内容类型,它不会抛出异常,而是返回null;
public int getContentLength()
- getContentLength()
告诉你内容中有多少字节。如果没有Content-Length首部,getContentLength()就返回-1;
public long getContentLengthLong()
Java7增加的
与getContentLength()类似,只不过它会返回一个long而不是int,这样就可以处理更大的资源;
public String getContentEncoding()
- getContentEncoding()
返回一个String,指出内容是如何编码的。如果发送的内容没有编码,这个方法就返回null;
public long getDate()
- getDate()方法
返回一个long,指出文档何时发送;
public long getExpiration()
-
有些文档有基于服务器的过期日期,指示应当何时从缓存中删除文档,并从服务器重新下载。
-
如果HTTP首部没有包括Expiration字段,getExpiration()就返回0,这表示文档不会过期,将永远保留在缓存中;
public long getLastModified()
返回文档的最后修改日期;
Test .java
import java.io.IOException;
import java.net.MalformedURLException;
import java.net.URL;
import java.net.URLConnection;public class Test {public static void main(String[] args) {try {URL url = new URL("http://www.baidu.com");URLConnection connection = url.openConnection();System.out.println("Content-Type: " + connection.getContentType());System.out.println("Content-Length: " + connection.getContentLength());System.out.println("Content-LengthLong: " + connection.getContentLengthLong());System.out.println("Content-encoding: " + connection.getContentEncoding());System.out.println("Date: " + connection.getDate());System.out.println("Expires: " + connection.getExpiration());System.out.println("Last-modified: " + connection.getLastModified());} catch (IOException e) {throw new RuntimeException(e);}}
}
out.log
Content-Type: text/html
Content-Length: 2381
Content-LengthLong: 2381
Content-encoding: null
Date: 1735307608000
Expires: 0
Last-modified: 0
获取任意首部字段
public String getHeaderField(String name)
getHeaderField()
返回指定首部字段的值。首部的名不区分大小写,也不包含结束冒号;
URL url = new URL("http://www.baidu.com");
URLConnection connection = url.openConnection();
System.out.println(connection.getHeaderField("Content-Type"));
System.out.println(connection.getHeaderField("last-modified"));//输出
text/html
Mon, 23 Jan 2017 13:27:36 GMT
public String getHeaderFieldKey(int n)
- getHeaderFieldKey(int n)
返回第n个首部字段的键(即字段名)。请求方法本身是第0个首部,它的键为null。第一个首部即编号为1
System.out.println(connection.getHeaderFieldKey(5)); //输出Content-Type
public String getHeaderField(int n)
返回第n个首部字段的值,包含请求方法和路径的起始行是第0个首部字段,实际的第一个首部编号为1
Test.java : 循环显示整个HTTP首部
public class Test {public static void main(String[] args) {try {URL url = new URL("http://www.baidu.com");URLConnection connection = url.openConnection();for (int i = 1; ; i++) {String header = connection.getHeaderField(i);if (header == null) {break;}System.out.println(connection.getHeaderFieldKey(i)+": "+header); }} catch (IOException e) {}}
}//输出
Accept-Ranges: bytes
Cache-Control: private, no-cache, no-store, proxy-revalidate, no-transform
Connection: Keep-Alive
Content-Length: 2381
Content-Type: text/html
Date: Thu, 04 Oct 2018 13:14:20 GMT
Etag: "588604ec-94d"
Last-Modified: Mon, 23 Jan 2017 13:28:12 GMT
Pragma: no-cache
Server: bfe/1.0.8.18
Set-Cookie: BDORZ=27315; max-age=86400; domain=.baidu.com; path=/
public long getHeaderFieldDate(String name, long Default)
这个方法首先获取由name参数指定的首部字段,然后尝试将这个字符串转换为一个long;
public long getHeaderFieldInt(String name, int Default)
这个方法获取首部字段name的值,尝试将其转换为int;
X 推荐文献
- [Java SE/JDK/网络] 核心源码精讲:java.net.HttpURLConnection - 博客园/千千寰宇
- [Java SE] Java-文件系统-常用文件路径的获取方法 - 博客园/千千寰宇