一、URL类简介
类URL表示统一资源定位器,即指向万维网上“资源”的指针。资源可以是文件或目录这样简单的东西,也可以是对更复杂对象的引用,例如对数据库或搜索引擎的查询。有关URL类型及其格式的更多信息,请访问:URL类型
一般来说,URL可以分为几个部分。考虑以下示例:
http://www.example.com/docs/resource1.html
上面的URL表示要使用的协议是http(超文本传输协议),并且信息位于名为www.example.com的主机上。该主机上的信息名为/docs/resource1.html。此名称在主机上的确切含义取决于协议和主机。信息通常存在于文件中,但也可以动态生成。URL的这个组件称为路径组件。
URL可以选择指定一个“端口”,这是在远程主机上进行TCP连接的端口号。如果未指定端口,则使用协议的默认端口。例如,http的默认端口是80。可以将替代端口指定为:
http://www.example.com:1080/docs/resource1.html
URL的语法由RFC 2396定义:统一资源标识符(URI):通用语法,由RFC 2732修订:URL中的IPv6地址格式。Literal IPv6地址格式也支持scope_ids。这里介绍scope_ids的语法和用法。
URL可能附加了一个“片段”,也称为“ref”或“reference”。碎片由尖锐的符号字符“#”表示,后面跟着更多的字符。例如
http://java.sun.com/index.html#chapter1
从技术上讲,这个片段不是URL的一部分。相反,它表示在检索到指定的资源后,应用程序对文档中附加了标记chapter1的部分特别感兴趣。标记的含义是特定于资源的。
应用程序还可以指定一个“相对URL”,其中只包含相对于另一个URL访问资源所需的足够信息。HTML页面中经常使用相对URL。例如,如果URL的内容:
http://java.sun.com/index.html
其中包含相对URL:
FAQ.html
它将是以下内容的简写:
相对URL不需要指定URL的所有组件。如果缺少协议、主机名或端口号,则该值将从完全指定的URL继承。必须指定文件组件。可选片段不是继承的。
URL类本身不根据RFC2396中定义的转义机制对任何URL组件进行编码或解码。调用方负责对调用URL之前需要转义的任何字段进行编码,并对从URL返回的任何转义字段进行解码。此外,由于URL不知道URL转义,它无法识别同一URL的编码或解码形式之间的等效性。例如,两个URL:
http://foo.com/hello世界/和http://foo.com/hello%20world
将被认为彼此不相等。
注意,在某些情况下,URI类确实执行其组件字段的转义。管理URL编码和解码的推荐方法是使用URI,并使用toURI()和URI.toURL()在这两个类之间进行转换。
URLEncoder和URLDecoder类也可以使用,但仅用于HTML表单编码,这与RFC2396中定义的编码方案不同。
二、URLConnection类简介
抽象类URLConnection是表示应用程序和URL之间的通信链接的所有类的超类。此类的实例既可以用于从URL引用的资源中读取,也可以用于写入URL所引用的资源。通常,创建到URL的连接是一个多步骤的过程:
openConnection() |
connect() |
操作影响与远程资源连接的参数。 |
与资源交互;查询头字段和内容。 |
---------------------------->
时间
- 连接对象是通过调用URL上的openConnection方法创建的。
- 设置参数和常规请求属性将被操作。
- 使用connect方法建立到远程对象的实际连接。
- 远程对象变为可用。可以访问远程对象的头字段和内容。
使用以下方法修改设置参数:
- setAllowUserInteraction
- setDoInput
- setDoOutput
- setIfModifiedSince
- setUseCaches
设置使用缓存
并且使用以下方法修改一般请求属性:
- setRequestProperty
AllowUserInteraction和UseCaches参数的默认值可以使用方法setDefaultAllowUserInteractions和setDefaultUseCaches设置。
上面的每个set方法都有一个相应的get方法来检索参数或通用请求属性的值。适用的特定参数和一般请求属性是特定于协议的。
连接到远程对象后,使用以下方法访问头字段和内容:
- getContent
- getHeaderField
- getInputStream
- getOutputStream
某些标题字段经常被访问。方法:
- getContentEncoding
- getContentLength
- getContentType
- getDate
- getExpiration
- getLastModifed
提供对这些领域的方便访问。getContent方法使用getContentType方法来确定远程对象的类型;子类可能会发现覆盖getContentType方法很方便。
在常见情况下,可以忽略所有预连接参数和一般请求属性:预连接参数及请求属性默认为合理值。对于这个接口的大多数客户端,只有两个有趣的方法:getInputStream和getContent,它们通过方便的方法镜像在URL类中。
有关http连接的请求属性和标头字段的更多信息,请访问:
http://www.ietf.org/rfc/rfc2616.txt
在请求后调用URLConnection的InputStream或OutputStream上的close()方法可能会释放与此实例相关的网络资源,除非特定的协议规范为其指定了不同的行为。
三、利用URL和URLConnection获取网页HTML内容
import java.io.*;
import java.net.URL;
import java.net.URLConnection;
public class WebCrawler {
public static void main(String[] args) throws IOException {
// 网址字符串
String urlStr = "https://www.sina.com.cn/";
// 创建资源符对象
URL url = new URL(urlStr);
// 创建连接
URLConnection conn = url.openConnection();
// 获取输入流
InputStream inputStream = conn.getInputStream();
// 缓冲区,读取输入流内容,512KB
char[] buffer = new char[1024 * 512];
int len;
StringBuilder sb = new StringBuilder();
// 转换为字符流
InputStreamReader isr = new InputStreamReader(inputStream);
// 循环读取
while ((len = isr.read(buffer)) != -1){
sb.append(buffer, 0, len);
}
//System.out.println(sb.toString());
str2Text(sb.toString(), new File("files/sina.txt"));
// 关闭资源
inputStream.close();
isr.close();
}
/**
* 将str存入本地
* @param str 要保存的字符串
* @param destFileName 要保存的文件地址
* @throws IOException IO异常
*/
public static void str2Text(String str, File destFileName) throws IOException{
// 1.判断传入的文件是否存在,不存在则创建
if (!destFileName.exists()){
destFileName.createNewFile();
}
// 2.创建输出流,保存字符串
FileWriter fw = new FileWriter(destFileName);
// 写出数据
fw.write(str);
fw.flush();
// 关闭资源
fw.close();
}
}