c5 URLs and URIs - The URL class
2014-04-27 09:49
633 查看
java.net.URL 是对Uniform Resource Locator的抽象,是个final类,即不能被继承,没有子类,它通过strategy design pattern,不同协议作strategy,URL是Context,在context中选择不同strategy。
URL是不可变的,一般一个URL对象创建完成,其field就不能再被修改,因此是线程安全的。
Creating New URLs
抛 MalformedURLException,当被创建的URL的协议不支持时,或者URL语法错误时。
vm支持哪些协议要看当前vm的情况。通用的支持的协议有http,https,file,jar,ftp等。
如果你想用的协议不支持,可以在vm上安装protocal handler,但麻烦,得不偿失,不建议使用。
construct a URL from a string
当前VM支持哪些协议?
output:
上面的VM是运行在Windows的 java 7。如果是Android Dalvik VM只支持http,https,file,gar,ftp.
constructing a URL from its componets parts
port 为 -1,即使用protocol的默认端口,注意file要以“/”开头的,包括path,filename,和可选的fragment identifier,
Constructing relative URLs
上面的u2指向的url是 http://www.ibiblio.org/javafaq/mailinglists.html.
other sources of URL objects
还有其他方式可以得到URL,比如
在applets中的,getDocumentBase(),getCodeBase()
在java.io.File的 toURL(),
classloader不仅可以加载类还可以加载资源,比如ClassLoader.getSystemResource(String name) ,返回一个指向资源的URL。
Retrieving Data from a URL
如果读的是ASCII text,那就是ASCII,
如果是HTML file,那就是raw HTML,.
如果是imgage file,那就是binary image data,
不包含http头和与协议有关的信息!和读取其他InputStream没有区别。
如大部分网络程序一样,稳定地关闭流需要花费点心思。在jdk6及之前,需要在try外面声明一个null的InputStream is,在finally中判断如果is不为null,那就关闭is。
但在jdk7中,引入了try-with-resource statement,即在try中声明InputStream is,系统会在结束前自动关闭流。
Program:Download a web page
URL指向的资源并不一定就是text,可能是gif ,jpeg image,可能是MP3 sound file,或者其他任何东西,即使是text,server和client端使用的charset也并不一定一样!
用URL读不到http的header,但用openConnection()返回的HttpConnection可以。http header中的charset和document真正使用的charset可能也不一样!编码问题是Web较棘手的问题。
例如下例中,server如果可以返回String,则返回,不可以则返回Reader,还不可以则返回InputStream。
Splitting a URL into Pieces
一个URL由5部分组成
getFile()返回一个String,从第一个“/”开始到“#”之前的。
getPath(),类似getFile(),但不包含query部分。
getUserInfo(),有些URL中还有userinfo,或者有的还有password,userinfo在scheme后,host前,用@和host分开,http://elharo@java.oreilly.com/,userinfo是elharo。
Equality and Comparison
URL的equaels()方法,当2个URL在同一host,port,path,有相同的fragment identifier和query string,即指向同一资源时,认为2个URL equael。
注意equaels()会连接DNS,意味着它是I/O blocking的,所以不可以将URL存放在HashMap等依赖equaels()方法的数据结构中。
另一个方面,equaels()并不会实际比较资源是否相同,比如,http://www.oreilly.com/ 和 http://
www.oreilly.com/index.html equaels时会不相等!(也即equaels要求2个URL的string必须完全相同)
sameFile()方法和equaels()基本一致,也要请求DNS,不一样的地方在:sameFile()不比较fragment identifier,比如 http://www.oreilly.com/index.html#p1 和 http://www.oreilly.com/index.html#q2 ,sameFile()返回true,equaels()返回false。
Conversion
URL有3个方法,可将instance转为其他形式
toExternalForm():返回一个human-readable String,代表URL
toURI():转成对应的URI。相对URL,URI提供更精确的(accurate),更特殊的(specification-conformant)的行为。绝对化(absolutization)和编码(encodeing)时应该用URI,当要使用hashtable等依赖equaels()方法的数据结构时,应该使用URI,当需要从server下载内容时使用URL。
URL是不可变的,一般一个URL对象创建完成,其field就不能再被修改,因此是线程安全的。
Creating New URLs
public URL(String url) throws MalformedURLException public URL(String protocol, String hostname, String file) throws MalformedURLException public URL(String protocol, String host, int port, String file) throws MalformedURLException public URL(URL base, String relative) throws MalformedURLException
抛 MalformedURLException,当被创建的URL的协议不支持时,或者URL语法错误时。
vm支持哪些协议要看当前vm的情况。通用的支持的协议有http,https,file,jar,ftp等。
如果你想用的协议不支持,可以在vm上安装protocal handler,但麻烦,得不偿失,不建议使用。
construct a URL from a string
try { URL u = new URL("http://www.audubon.org/"); } catch (MalformedURLException ex) { System.err.println(ex); }
当前VM支持哪些协议?
public static void main(String[] args) { // hypertext transfer protocol testProtocol("http://www.adc.org"); // secure http testProtocol("https://www.amazon.com/exec/obidos/order2/"); // file transfer protocol testProtocol("ftp://ibiblio.org/pub/languages/java/javafaq/"); // Simple Mail Transfer Protocol testProtocol("mailto:elharo@ibiblio.org"); // telnet testProtocol("telnet://dibner.poly.edu/"); // local file access testProtocol("file:///etc/passwd"); // gopher testProtocol("gopher://gopher.anc.org.za/"); // Lightweight Directory Access Protocol testProtocol( "ldap://ldap.itd.umich.edu/o=University%20of%20Michigan,c=US?postalAddress"); // JAR testProtocol( "jar:http://cafeaulait.org/books/javaio/ioexamples/javaio.jar!" + "/com/macfaq/io/StreamCopier.class"); // NFS, Network File System testProtocol("nfs://utopia.poly.edu/usr/tmp/"); // a custom protocol for JDBC testProtocol("jdbc:mysql://luna.ibiblio.org:3306/NEWS"); // rmi, a custom protocol for remote method invocation testProtocol("rmi://ibiblio.org/RenderEngine"); // custom protocols for HotJava testProtocol("doc:/UsersGuide/release.html"); testProtocol("netdoc:/UsersGuide/release.html"); testProtocol("systemresource://www.adc.org/+/index.html"); testProtocol("verbatim:http://www.adc.org/"); } private static void testProtocol(String url) { try { URL u = new URL(url); System.out.println(u.getProtocol() + " is supported"); } catch (MalformedURLException ex) { String protocol = url.substring(0, url.indexOf(':')); System.out.println(protocol + " is not supported"); } }
output:
http is supported https is supported ftp is supported mailto is supported telnet is not supported file is supported gopher is supported ldap is not supported jar is supported nfs is not supported jdbc is not supported rmi is not supported doc is not supported systemresource is not supported netdoc is supported verbatim is not supported
上面的VM是运行在Windows的 java 7。如果是Android Dalvik VM只支持http,https,file,gar,ftp.
constructing a URL from its componets parts
public URL(String protocol, String hostname, String file) throws MalformedURLException
port 为 -1,即使用protocol的默认端口,注意file要以“/”开头的,包括path,filename,和可选的fragment identifier,
public URL(String protocol, String host, int port, String file) throws MalformedURLException其它同上面的,port显示指明使用哪个端口。
Constructing relative URLs
try { URL u1 = new URL("http://www.ibiblio.org/javafaq/index.html"); URL u2 = new URL (u1, "mailinglists.html"); } catch (MalformedURLException ex) { System.err.println(ex); }
上面的u2指向的url是 http://www.ibiblio.org/javafaq/mailinglists.html.
other sources of URL objects
还有其他方式可以得到URL,比如
在applets中的,getDocumentBase(),getCodeBase()
在java.io.File的 toURL(),
classloader不仅可以加载类还可以加载资源,比如ClassLoader.getSystemResource(String name) ,返回一个指向资源的URL。
Retrieving Data from a URL
public InputStream openStream() throws IOException public URLConnection openConnection() throws IOException public URLConnection openConnection(Proxy proxy) throws IOException public Object getContent() throws IOException public Object getContent(Class[] classes) throws IOException
public final InputStream openStream() throws IOExceptionopenStream返回InputStream,从InputStream中可以读取数据,而读到的数据都是未经解析的原始内容:
如果读的是ASCII text,那就是ASCII,
如果是HTML file,那就是raw HTML,.
如果是imgage file,那就是binary image data,
不包含http头和与协议有关的信息!和读取其他InputStream没有区别。
try { URL u = new URL("http://www.lolcats.com"); InputStream in = u.openStream(); int c; while ((c = in.read()) != -1) System.out.write(c); in.close(); } catch (IOException ex) { System.err.println(ex); }
如大部分网络程序一样,稳定地关闭流需要花费点心思。在jdk6及之前,需要在try外面声明一个null的InputStream is,在finally中判断如果is不为null,那就关闭is。
InputStream in = null try { URL u = new URL("http://www.lolcats.com"); in = u.openStream(); int c; while ((c = in.read()) != -1) System.out.write(c); } catch (IOException ex) { System.err.println(ex); } finally { try { if (in != null) { in.close(); } } catch (IOException ex) { // ignore } }
但在jdk7中,引入了try-with-resource statement,即在try中声明InputStream is,系统会在结束前自动关闭流。
try { URL u = new URL("http://www.lolcats.com"); try (InputStream in = u.openStream()) { int c; while ((c = in.read()) != -1) System.out.write(c); } } catch (IOException ex) { System.err.println(ex); }
Program:Download a web page
public static void main(String[] args) { if (args.length > 0) { InputStream in = null; try { // Open the URL for reading URL u = new URL(args[0]); in = u.openStream(); // buffer the input to increase performance in = new BufferedInputStream(in); // chain the InputStream to a Reader Reader r = new InputStreamReader(in); int c; while ((c = r.read()) != -1) { System.out.print((char) c); } } catch (MalformedURLException ex) { System.err.println(args[0] + " is not a parseable URL"); } catch (IOException ex) { System.err.println(ex); } finally { if (in != null) { try { in.close(); } catch (IOException e) { // ignore } } } } }在chaining InputStream到InputStreamReader时,使用本地默认的charset!
URL指向的资源并不一定就是text,可能是gif ,jpeg image,可能是MP3 sound file,或者其他任何东西,即使是text,server和client端使用的charset也并不一定一样!
用URL读不到http的header,但用openConnection()返回的HttpConnection可以。http header中的charset和document真正使用的charset可能也不一样!编码问题是Web较棘手的问题。
public URLConnection openConnection() throws IOExceptionopenConnection()打开一个到指定URL的socket,并返回一个URLConnection对象。通过该方法,可以获取server发送的任何原始数据,和与协议有关的meta数据。
public URLConnection openConnection(Proxy proxy) throws IOException使用代理连接服务器,如果协议不支持代理,则忽略代理,尝试直接连接。
public final Object getContent() throws IOException从服务器获取数据,并且将其生成某种对象!
public final Object getContent(Class[] classes) throws IOException告诉server,按classes返回client需要的类别的对象。
例如下例中,server如果可以返回String,则返回,不可以则返回Reader,还不可以则返回InputStream。
URL u = new URL("http://www.nwu.org"); Class<?>[] types = new Class[3]; types[0] = String.class; types[1] = Reader.class; types[2] = InputStream.class; Object o = u.getContent(types);client要判断返回的类型
if (o instanceof String) { System.out.println(o); } else if (o instanceof Reader) { int c; Reader r = (Reader) o; while ((c = r.read()) != -1) System.out.print((char) c); r.close(); } else if (o instanceof InputStream) { int c; InputStream in = (InputStream) o; while ((c = in.read()) != -1) System.out.write(c); in.close(); } else { System.out.println("Error: unexpected type " + o.getClass()); }
Splitting a URL into Pieces
一个URL由5部分组成
• The scheme, also known as the protocol • The authority • The path • The fragment identifier, also known as the section or ref • The query string
http://www.ibiblio.org/javafaq/books/jnp/index.html?isbn=1565922069#toc
getFile()返回一个String,从第一个“/”开始到“#”之前的。
/javafaq/books/jnp/index.html?isbn=1565922069
getPath(),类似getFile(),但不包含query部分。
/javafaq/books/jnp/index.html
getUserInfo(),有些URL中还有userinfo,或者有的还有password,userinfo在scheme后,host前,用@和host分开,http://elharo@java.oreilly.com/,userinfo是elharo。
Equality and Comparison
URL的equaels()方法,当2个URL在同一host,port,path,有相同的fragment identifier和query string,即指向同一资源时,认为2个URL equael。
注意equaels()会连接DNS,意味着它是I/O blocking的,所以不可以将URL存放在HashMap等依赖equaels()方法的数据结构中。
另一个方面,equaels()并不会实际比较资源是否相同,比如,http://www.oreilly.com/ 和 http://
www.oreilly.com/index.html equaels时会不相等!(也即equaels要求2个URL的string必须完全相同)
sameFile()方法和equaels()基本一致,也要请求DNS,不一样的地方在:sameFile()不比较fragment identifier,比如 http://www.oreilly.com/index.html#p1 和 http://www.oreilly.com/index.html#q2 ,sameFile()返回true,equaels()返回false。
Conversion
URL有3个方法,可将instance转为其他形式
toString(); toExternalForm(); toURI();toString():输出URL的绝对路径,不常用,不直接使用
toExternalForm():返回一个human-readable String,代表URL
toURI():转成对应的URI。相对URL,URI提供更精确的(accurate),更特殊的(specification-conformant)的行为。绝对化(absolutization)和编码(encodeing)时应该用URI,当要使用hashtable等依赖equaels()方法的数据结构时,应该使用URI,当需要从server下载内容时使用URL。
相关文章推荐
- c5 URLs and URIs - The URI Class
- c5 URLs and URIs - Accessing Password-Protected Sites
- c5 URLs and URIs - Proxy
- A simple HTTP PHP class to crawl a URL for internal and external URLs
- c5 URLs and URIs - URIs
- c5 URLs and URIs - Communicating with Server-Side Programs Through GET
- c5 URLs and URIs - x-www-form-urlencoded
- What is the difference between NoClassDefFoundError and ClassNotFoundException?
- What is the HINSTANCE passed to CreateWindow and RegisterClass used for?
- UTL_HTTP Call a Web Service and Pass Parameters as Part of the URL
- myeclipse10 tomcat :the source attachment does not contain the source for the file URLClassPath.clas
- django提交表单提示"You called this URL via POST, but the URL doesn't end in a slash and you have APPEND_SL
- The study of Class and Instance in Python(20170918)
- The servlets named [A] and [B] are both mapped to the url-pattern [/servlet/]which is not permitted
- The Definitive Guide To Django 2 学习笔记(一) Views and UrL confsRL
- Why do many Collection classes in Java extend the abstract class and implement the interface as well
- [转]Use the IDA and LLDB explore WebCore C + + class inheritance
- [JavaScript]How to parse the URL and get the different fragments easily?
- UTL_HTTP Call a Web Service and Pass Parameters as Part of the URL
- parse and display a BMP image in the Flash Player using the ByteArray class