URL
一:理论
URL是最常见的URI,即统一资源标识符(uniform resource Identifier)
URI是采用一种特定语法标识一个资源的字符串.所标识的资源可以是文件,邮件地址,新闻信息,图书,人名,Internet主机或其它内容
URI的语法由一个模式和一个模式的特定部分组成,模式和特定部分用一个冒号相隔:例如
模式:模式特定部分
模式特定部分的语法取决于所用的模式,当前的包括:
data 链接中直接包含的Base64编码数据,参见RFC2379
file 本地磁盘上的文件
ftp FTP服务器
http 使用超文本传输协议的国际互联网服务器
mailto 电子邮件地址
magnet 可以通过对等网络(如BitTorrent) 下载的资源
telnet 与基于telnet的服务的连接
urn 统一资源名(Uniform resource Name, URN)
java特有的非标准定制模式: rmi , jar ,jndi ,doc 和content
URL是一个URI,除了标识资源,还会为资源提供一个特定的网络位置,客服端可以用它来获取这个资源的一个表示.
URI可以告诉你一个资源是什么,但无法告诉你在哪里.
java.net.URI 只标识资源
java.net.URL 既能标识资源,又能获取资源
URL的语法: protocol://userInfo@host:port/path?query#fragment
protocol:模式 ,可以是file,http ,ftp等
userInfo; 用户登录信息(可选),其中包含一个用户名,或还会有一个密码
host: 主机名
port: 端口,如果是默认端口(80),可以不需要这部分
path: 指服务器上一个特定目录
query: 查询字符串,一般只在http URL中使用,其中包含表达数据
fragment: 片段指向远程资源的摸个特定部分.如果是HTML,那么片段标识符将指向HTML文档中的一个anchor(锚),如果是XML那么这个片段标识符石一个XPointer,
片段标识符(fragment)在HTML文档中用属性创建,例如:
<h3 id = "xtocid1902914">Comments</h3>
http://www.cafeaulait.org/javafaq.html#xtocid1902914
URL是最常见的URI,即统一资源标识符
二:
URL类:
URL是最常见的URI,即统一资源标识符,它扩展了java.lang.Object类,是一个final类,不能对其派生子类
url是不可变的,构造一个URL对象后,其字段不再改变,这可以保证线程安全
测试虚拟机支持那些协议
import java.net.*; public class Url { public static void testProtocol(String url){ try{ URL u = new URL(url); System.out.println(u.getProtocol() + "is supported"); }catch( MalformedURLException e){ String protocol = url.substring(0,url.indexOf(":")); System.err.println(protocol + " is not supported"); } } public static void main(String[] args){ testProtocol("http://www.adc.org"); testProtocol("https://www.adc.org"); testProtocol("ftp://ibiblio.org/pub/languages/java/javafaq/"); testProtocol("mailto:elharo@ibiblio.org"); testProtocol("telnet://diibner.poly.edu/"); testProtocol("file:///etc/passwd"); testProtocol("gopher://gopher.anc.org.za/"); testProtocol("ldap://ldap.td.umich.wdu/o=University%20of%20Michigan,c=US?postalAddress"); testProtocol("jar:http://cafeeaulait.org/books/javaio/ioexamples/javaio.jar!" + "/com/macfaq/io/StreamCopier.class"); testProtocol("nfs://utopia.poly.edu/user/tmp/"); testProtocol("jdbc:mysql://luna.ibiblio.org:3306/NEWS");//JDBC的定制协议 testProtocol("rmi://ibiblio.org/RenderEngine");//远程方法调用的定制协议 //Hotjava的定制协议 testProtocol("doc:/UsersGuide/release.html"); testProtocol("netdoc:/UsersGuide/release.html"); testProtocol("systemresource://www.adc.org/+/index.html"); testProtocol("verbatim:http:www.adc.org/"); } }
URL构造方法
public URL(String url) throws MalformedURLException public URL(String protocol, String host,String file) throws MalformedURLException
//从指定的protocol名称, host名称和file名称创建一个URL。 使用指定协议的默认端口。 此方法等效于
调用带参数是四个参数的构造函数protocol , host , -1和file 。
示例: URL u = new URl("http","www.eff.org", "/blueribbon.html#info"); public URL(String protocol, String host,int port, URLStreamHandler handler)
throws MalformedURLException //创建URL从指定对象protocol , host , port数,
file和handler 。 指定port号-1表明URL应使用的默认端口的协议。
示例: URL u = new URl("http", "fourier.dur.ac.uk", 8000,"/~dma3mjh/jsci/");
构造相对URL
public URL(URL base,String relative) throws MalformedURLException //将文件名从base中除去,追加新文件名relative URL u1 = new URL("http://www.ibiblio.org/javafaq/index.html"); URL u2 - new URL(u1,"mailinglists.html");
从URL获取数据
java中有几个方法可以从URL中获取数据
public InputStream openStream() //打开与此 URL ,并返回一个 InputStream ,以便从该连接读取。 //不要直接用openSteam,它的默认超时时间是0,也就是不会超时,会阻塞线程 public URLConnection openConnection() throws IOException//openConetcion()方法为指定的URL打开一个socket,并发回URLConnection对象,URLConnection表示一个网络资源的打开,与服务器通讯应当使用这个方法 public URLConnection openConnection(Proxy proxy) throws IOException//可以指定哪个代理服务器传递连接,如果协议处理器不支持,这个参数将被忽略 public final Object getContent() throws IOException //获取此URL的内容 getContent()不能判断文件的类型可以用instanceof判断
public fianl Object getConnect(Class[] classes) throws IOException //该URL的内容对象是类数组中指定的类型的第一个匹配项。 如果不支持请求的类型,则为null。
URL u1 = new URL("http://www.pptbz.com/pptpic/UploadFiles_6909/201203/2012031220134655.jpg"); try { //InputStream in = u1.openStream();//不要直接用openSteam,它的默认超时时间是0,也就是不会超时 /*URLConnection uc = u1.openConnection(); InputStream in = uc.getInputStream();*/ /* Object o = u1.getContent(); if(o instanceof ImageProducer) System.out.println(o.getClass().getName()); */ Class<?>[] type = new Class[4]; type[0] = String.class; type[1] = Reader.class; type[2] = InputStream.class; type[3] = ImageProducer.class; Object o = u1.getContent(); if(o instanceof Reader){ int c; Reader r = (Reader)o; while((c = r.read())!= -1) System.out.println(c); r.close(); }else if(o instanceof InputStream){ int c; InputStream in = (InputStream)o; while((c = in.read())!= -1) System.out.println(c); in.close(); }else if(o instanceof String){ System.out.println(o); }else if( o instanceof ImageProducer){ int c; ImageProducer im = (ImageProducer)o; System.out.println(im); }else{ System.out.println("Error: unexpected type" + o.getClass()); } } catch (IOException e) { // TODO 自动生成的 catch 块 e.printStackTrace(); }
分解URL
URL由以下5部分组成:
- 模式,也称为协议
- 授权机构
- 路径
- 片段标识符,也称为段或ref
- 参训字符串
例如在 URL http://www.ibiblio.org/javafaq/books/jnp/index.html?isbn=1565922069#toc中
模式是http,授权机构是www.ibiblio.org,路径是javafaq/books/jnp/index.html, 片段标识符石toc,查询字符串是isbn=1565922069
九个公共方法提供了URL这些部分的只读访问:
public String getProtocol() //获取此URL的协议(或模式)名称(如http,https,file等) public String getHost() //获取此URL的主机名(如适用)。 public int getPort() //获取此 URL的端口号。 public int getDefaultPort() //获取与此 URL的协议的默认端口号。如果没有默认端口,返回-1 public String getFile() //获取此 URL的文件名。从主机名后的第一个斜线(/)到#之前的字符,都被认为是文件部分,如果有文件部分返回null public String getPath() //获取此 URL的路径部分,与getFile()类似,但不包括查询字符串 public String getRef() //返回URL的片段标识符部分,如果没有片段标识符则返回null public String getQuery() //获取此 URL的查询部分。如没有则返null public String getUserInfo() //获取该 URL的userInfo部分。这些信息位于模式之后,而且在主机名之前,用一个@符合将用户信息和主机分开 public String getAuthority() //获取此的授权机构部分URL 。
URLde equals()可能阻塞I/O的操作,出于这个原因,应当避免将URL存储在依赖equals()的数据结构中,例如java.util.HashMap. 可以转换成java.net.URI,可以再必要时将URI转换陈URL
要比较两个URL是否执行同一个资源,可以用 public boolean sameFIle(URL other)方法