关于URL 和URI的关系,在本系列的第二篇:java网络---基本web概念 中已经简述了。
这里重复一点,就是URI包含URL,或者说URI是父类,URL就是子类的概念。
本篇再来详述这2个概念。
一:URL
java/net/URL.java
public final class URL implements Serializable { private static final long serialVersionUID = -7627629688361524110L; private static URLStreamHandlerFactory streamHandlerFactory; /** Cache of protocols to their handlers */ private static final Hashtable<String, URLStreamHandler> streamHandlers = new Hashtable<String, URLStreamHandler>(); private String protocol; private String authority; private String host; private int port = -1; private String file; private String ref;
一个URL就是长的这样样子:http://home.cnblogs.com/u/deman/
所以我们可以使用String简单的描述一个URL。
但考虑URL为一个类可能更有用一些。
这个对象包括,模式,主机名,端口,路径,标识符(ref)。看看上面的源码,就是这些东西!
看看虚拟机支持那些协议,可以编写如下测试程序:
public class ProtocolTester implements IOperator { @Override public void start() { testProtocol("http://www.adc.org"); testProtocol("https://www.amazon.com"); testProtocol("ftp://metalab.unc.edu"); testProtocol("telent://dibner.poly.edu/"); testProtocol("mailto:[email protected]"); testProtocol("file:///etc/passwd"); testProtocol("gopher://gopher.anc.org.za"); testProtocol("ladp://ldap.itd.umich.edu"); testProtocol("jar:http://ldap.itd.umich.edu.jar"); testProtocol("nfs://utopia.poly.edu"); testProtocol("jdbc:mysql:/utopia.poly.edu"); } private void testProtocol(String url) { try { URL u = new URL(url); TraceLog.i(u.getProtocol()+" is supported"); } catch (MalformedURLException e) { // e.printStackTrace(); // TraceLog.w(e.getMessage()); String protocol = url.substring(0,url.indexOf(‘:‘)); TraceLog.w(protocol+ " is not supported"); } }
URL组成:
URL有五部分组成,
模式,也称为协议
授权机构
路径
片段标示符,ref
查询字符串
给点URL http://www.ibiblio.org/javafaq/books/jnp/index.html?isbn=1565229#toc
模式 http
授权机构 www.ibiblio.org
路径 javafaq/books/jnp/index.html
片段标示符,ref toc
查询字符串 isbn=1565229
授权机构可以进一步分为:用户信息,主机,端口。
[email protected]:8080
public class UrlValueTester implements ITestOperator { @Override public void startTest() { try { URL u = new URL("http://tieba.baidu.com/f/fdir?fd=%E7%A7%91%E5%AD%A6%E6%8A%80%E6%9C%AF&ie=utf-8&sd=%E8%AE%A1%E7%AE%97%E6%9C%BA%E8%BD%AF%E4%BB%B6"); method(u); } catch (MalformedURLException e) { e.printStackTrace(); } catch (IllegalAccessException e) { e.printStackTrace(); } catch (InvocationTargetException e) { e.printStackTrace(); } } public void method(URL u) throws InvocationTargetException, IllegalAccessException { Class cls = u.getClass(); Method[] methods = cls.getDeclaredMethods(); for(Method m:methods) { try{ if(m.getName().contains("get")) { TraceLog.i(m.getName()); TraceLog.i(":"+m.invoke(u)); } }catch (Exception e) { TraceLog.w(m.getName()); } } }
通过反射,获取所有get方法,然后依次获取各个属性。
二:URLEncoder & URLDecoder
URL使用如下字符:
大写字母
小写字母
数字0-9
标点-_.!~*‘
字符/ & ? @ # ; $ + = % 用于特殊目的。
其他的内容都需要编码,URL默认不进行编码
public class EncoderTester implements ITestOperator{ public static final String DEFAULT_ENCODE = "UTF-8"; @Override public void startTest() { try { String str = URLEncoder.encode("This is a + base string 我 吃 饭",DEFAULT_ENCODE); TraceLog.i(str); str = URLDecoder.decode(str, DEFAULT_ENCODE); TraceLog.i(str); } catch (UnsupportedEncodingException e) { e.printStackTrace(); } } }
12-28 16:47:20.915 23343-23433/com.joyfulmath.sample.javanetwork I/EncoderTester: startTest: This+is+a+%2B+base+string+%E6%88%91+%E5%90%83+%E9%A5%AD [at (EncoderTester.java:20)] 12-28 16:47:20.916 23343-23433/com.joyfulmath.sample.javanetwork I/EncoderTester: startTest: This is a + base string 我 吃 饭 [at (EncoderTester.java:22)]
如上,空格会编码成+,所以 非给定的字符,都需要编码!
而特殊符号,则需要看情况,确定是否编码!
三.URI
URI是纯字符串的内容,是URL的相对内容。
URI格式分为三部分:
scheme:sheeme-part:fragment
URI top = new URI("http://www.example.com/"); URI relative = new URI("image/logo.png"); URI resolved = top.resolve(relative); output: http://www.example.com/image/logo.png"
URI可以做绝对路径和相对路径的转化,但是URL必须是绝对路径。