java网络---再论URL & URI

关于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:joyfulmath@163.com");
        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

授权机构可以进一步分为:用户信息,主机,端口。

anmin@www.baidu.com: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必须是绝对路径。

原文地址:https://www.cnblogs.com/deman/p/5083082.html