url无法获取,使用URL类来获取网络资源

1. 什么是URL
统一资源定位符(URL,英文Uniform Resource Locator的缩写),它是指向互联网“资源”的指针。资源可以是简单的文件或目录,也可以是更为复杂的对象的引用,例如对数据库或搜索引擎的查询。URL的一般格式为(带方括号的为可选项):
protocol://hostname[:port]/path/[;parameters][?query]#fragment
在上述的格式中,我们可以看到有以下的几个部分
1.1. Protocol(协议),指定使用的传输协议,其中最常用的是HTTP协议,它是目前WWW中应用最广的协议。下面列出了常见的值:
File 表示资源是本地计算机上面的文件。 格式file://
ftp 通过FTP访问资源。格式 ftp://
http 通过http访问该资源。格式http://
https 通过安全的https访问该资源。格式http://
Mailto 资源为电子邮件地址,通过SMTP访问。格式mailto://
1.2. Hostname(主机名),指存放资源的服务器的域名,在这里也可能包含需要连接到服务器所需的用户名和密码。
1.3. Port(端口号):是一个整数在0-65535之间,可选。如果省略这个部分,那么会使用方案的默认端口,各种传输协议都有默认的端口号,比如http默认使用80端口。
1.4. Path(路径):由零个或多个"/"符号隔开的字符串,一般用来表示主机上的一个地址或文件夹。
1.5. ;parameters(参数):这是用于指定特定参数的可选项。
1.6. ?query(查询):可选,主要用于给动态网页传递参数,可以有多个参数,中间用“&”分开,每个参数的名字与值用“=”隔开。
1.7. Fragment(信息片段),字符串,用于指定网络资源中的片段。
2. java.net.URL类
java.net.URL类是对于URL的抽象以及封装。它记录了上述的protocol, hostname, port, path等信息。由于这些字段都是非可见的,java.net.URL类提供了这些属性的get方法(getProtocol(),getHost())来进行操作。需要注意的是,URL类中有两个set的方法,不过这两个方法都是protected,也就是说,用户的代码不能对他进行设置,只能通过构造函数初始化的时候进行设置。
java.net.URL一共有六个构造函数,如下:
URL(String spec)
URL(String protocol,String host,int port,String file)
URL(String protocol,String host,int port,String file,URLStreamHandler handler)
URL(String protocol,String host,String file)
URL(URL context,String spec)
URL(URL content,String spec,URLStreamHandler handler)
在这六个构造函数中,最常用的是URL(String spec),只需要将URL的String地址传入即可。注意当输入了错误的URL获取找不到对应的合法协议,这些构造函数会抛出
MalformedURLException.下面的例子展示了如何用这个构造函数来获取URL的信息。
package org.dakiler.javanet.chapter2;
import java.net.URL;
/**
* to show the usage of URL(String spec)
* @author Dakiler
*
*/
public class Example1
{
public static void main(String args[])throws Exception
{
URL url=new URL("http://www.baidu.com/s?wd=java");
System.out.println("protocol: "+url.getProtocol());
System.out.println("host: "+url.getHost());
System.out.println("path: "+url.getPath());
System.out.println("query: "+url.getQuery());
}
}
这个例子首先通过URL(String spec)构造一个URL对象,然后在命令行分别打印出url.getProtocol(),url.getHost()等信息,结果如下:
protocol: http
host: www.baidu.com
path: /s
query: wd=java
在这些构造函数中,还有一个比较常用的构造函数是URL(URL context,String spec),它并不是直接根据String指定URL,而是根据已经存在的URL上下文来构建。这里根据上下文来创建类似于java.io.File类的构造,如果spec是以/开头,那么这个路径是绝对的,并且用spec中的路径代替上下文中的路径,否则这个路径会被视为相对路径,将会被添加到上下文中路径。下面的例子指定了如何使用这个构造函数来创建URL对象:
URL url=new URL("http://www.XXX.com/a.html","b.html");这个url对象等同于new URL(http://www.XXX.com/b.html)。
3. 使用URL获取资源
java.net.URL除了提供getHost(),getProtocol()方法以为,还提供了获取资源的方法:openConnection(),返回的是一个URLConnection的对象实例,主要有以下的getter方法:
boolean getAllowUserInteraction() 返回是否允许用户交互
int getConnectTimeout() 返回连接超时,以毫秒为单位
String getContentEncoding() 返回该资源内容的编码方式,如果编码方式未知,返回null
int getContentLength() 返回内容的长度
String getContentType() 返回content-type
InputStream getInputStream() 打开到这个资源的InputStream.
下面这个例子,我们将展示如何使用URL,URLConnection类来获取一个特定网址的内容:
package org.dakiler.javanet.chapter2;
import java.io.BufferedReader;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.net.URL;
import java.net.URLConnection;
public class Example2
{
public static void main(String args[])throws Exception
{
URL url=new URL("http://www.baidu.com");
URLConnection urlc=url.openConnection();
System.out.println("AllowUserInteraction: "+urlc.getAllowUserInteraction());
System.out.println("Timeout: "+urlc.getConnectTimeout());
System.out.println("ContentEncoding: "+urlc.getContentEncoding());
System.out.println("ContentLength: "+urlc.getContentLength());
System.out.println("ContentType: "+urlc.getContentType());
InputStream is=urlc.getInputStream();
InputStreamReader reader=new InputStreamReader(is);
BufferedReader in=new BufferedReader(reader);
String input=null;
while((input=in.readLine())!=null)
{
System.out.println(input);
}
}
}
在这个例子中,我们首先创建一个URL对象,指向的资源的网址是www.baidu.com,
然后通过url.openConnection()对象获取URLConnection对象。URLConnection类有许多get方法,中间的一段System.out.println()方法将会打印出这些结果。
获取了URLConnection的实例以后,我们通过URLConnection的getInputStream()方法获取到了输入流,然后根据字节流InputStream来创建InputStreamReader,InputStreamReader 是字节流通向字符流的桥梁,它使用了默认的字符编码来读取字节并且将其解码为字符,接下来用BufferedReader 来进行包装,这样能提高效率。最后通过一个循环,从BufferedReader中读取一行数据,并且打印到命令行中。结果如下:
AllowUserInteraction: false
Timeout: 0
ContentEncoding: null
ContentLength: 3520
ContentType: text/html;charset=gb2312
......(以下是网页的内容)
在输出结果中,我们看到ContentEncoding值为null,而ContentType中包含了字符编码的信息,使用的是gb2312。
Tags: 

延伸阅读

最新评论

发表评论