• URL类


    java.net.URL类是对统一资源定位符(如http://www.lolcats.com)的抽象。它扩展了java.lang.Object,是一个final类。它采用策略模式,协议处理器(protocol handler)就是策略,URL类构成Context,通过它来选择不同的策略。

    URL是一个字符串,但是对于URL类而言,这个字符串会被分解为URL类中的各个属性。URL类中的属性包括协议,主机名,端口,路径,查询字符串和片段标识。在构造了一个URL对象后其字段不再改变,所以URL是线程安全的。

    构造URL对象

    通过字符串构造URL对象

    public URL(String url)

    try {
                URL u = new URL("http://www.xdysite.cn");
            } catch (MalformedURLException e) {
                System.out.println(e);
            }

    通过组成部分构造URL

    pulbic URL(String protocol, String hostname, String file)

    pulbic URL(String protocol, String hostname, int port String file)

    try {
                //采用默认端口构造
                URL u1 = new URL("http", "www.xdysite.cn","/index.php");
                //使用8000端口构造
                URL u2 = new URL("http", "www.xdysite.cn", 8000, "/index.php");
            } catch (MalformedURLException e) {
                System.out.println();
            }

     

    构造相对URL

    public URL(URL base, String relative)

    try {
                URL u1 = new URL("http://www.xdysite.cn/javafaq/index.xml");
                URL u2 = new URL(u1, "mailinglists.html");
            } catch (MalformedURLException e) {
                System.out.println();
            }

    如果有一个基础的URL(http://www.xdysite.cn/javafaq/index.html),通过上述方式可以构造出一个新的URL(http://www.xdysite.cn/javafaq/mailinglists.html)

     

    从URL获取数据

     

    直接打开流来获取数据

    public final InputStream openStream()

    该方法会直接从URL指向的资源中获取数据,如果资源是HTML页面,那么会直接获取页面的数据。并不会获取关于HTTP头部的信息。

    try {
                URL u = new URL("http://www.xdysite.cn/index.php");
                try(Reader r = new InputStreamReader(new BufferedInputStream(u.openStream()))){
                    int c;
                    while((c = r.read())!=-1){
                        System.out.print((char)c);
                    }
                }
            } catch (IOException e) {
                System.out.println(e);
            }

     

    获取一个具体的对象

    public final Object getContent()

    该方法会获取URL指向的数据,并尝试建立某种类型的对象。如果URL指示某种文本(HTML/XML),返回的对象通常是某种InputStream。如果URL指示一个图像(如GIF或JPEG),getContent()通常会返回一个java.awt.ImageProducer。

    try {
                URL u = new URL("http://www.xdysite.cn/index.html");
                try(Reader r = new InputStreamReader(new BufferedInputStream((InputStream)u.getContent()))){
                    int c;
                    while((c = r.read())!=-1){
                        System.out.print((char)c);
                    }
                }
            } catch (IOException e) {
                System.out.println(e);
            }

     

    URL编码问题

    由于在发明Web时Unicode编码还没有普及,使得URL中使用的字符必须来自于ASCII码中的一个固定的子集,确切的讲,包括:

  • 大写字母A-Z
  • 小写字母a-z
  • 数字0-9
  • 标点符号 – _ . ! ~ * ' ,
  • 特殊用途的字符 / & ? @ # ; $ + = %

    就目前的而言只有上面的字符才能出现在URL中.如果在URL中需要出现一些上面没有的字符时,需要对URL进行编码。

  • URLEncoder类

    可以使用该类对一个字符串进行编码,编码后会将将结果转为%和两个十六进制数。现在通用的编码机制是UTF-8

    try {
                System.out.println(URLEncoder.encode("This is a string", "UTF-8"));
                System.out.println(URLEncoder.encode("This/is/a/string", "UTF-8"));
                System.out.println(URLEncoder.encode("This"is"a"string", "UTF-8"));
                System.out.println(URLEncoder.encode("This_is.a-string*", "UTF-8"));
            } catch (UnsupportedEncodingException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }

    过度编码

    在URL中允许出现的字符是不需要进行编码的。但是使用URL类时,会对斜线(/),与号(&),等号(=)进行编码。我们知道在URL中斜线(/)表示下一级目录。如果对其进行编码会导致我们无法访问资源。这就是过度编码问题。为了解决这个问题,我们需要逐步分对URL进行编码,而不是对整个URL进行编码。

    try {
                String query = URLEncoder.encode("http://www.baidu.com/s?wd=火影&sp=on", "UTF-8");
                System.out.println(query);
            } catch (UnsupportedEncodingException e) {
                e.printStackTrace();
            }

    输出结果

    image

    我们看到URLEncoder对斜杠(/)都进行编码,这个不是我们想要的。我们只需要对“火影”进行编码即可。

    try {
                String query = "http://www.baidu.com/s?wd="+URLEncoder.encode("火影", "utf-8")+"&sp=on";
                System.out.println(query);
            } catch (UnsupportedEncodingException e) {
                e.printStackTrace();
            }

    输出结果

    image

    由于使用UTF-8对“火影”进行编码后需要6个字节进行存储(每个汉字三个字节),所以显示出来是%E7%81%AB%E5%BD%B1,每个%后是一个字节,用十六进制表示。

  • 相关阅读:
    IOS 微信 6.5.2 自动播放音乐 解决方案
    【转载】动态新增svg节点
    通过并行数据以及TS学习来增强ASR的鲁棒性
    针对领域不变训练的注意力对抗学习
    BLSTM的训练算法、解码算法以及模型的改进
    kaldi chain模型的序列鉴别性训练代码分析
    kaldi通用底层矩阵运算库——CUDA
    kaldi通用底层矩阵运算库——CBLAS
    Thrax-构建基于语法的语言模型工具
    gdb nnet3-compute
  • 原文地址:https://www.cnblogs.com/xidongyu/p/6119966.html
  • Copyright © 2020-2023  润新知