Java中URL的处理方法详解

Java
283
0
0
2023-05-26
目录
  • 前言
  • URL 类方法
  • URLConnections 类方法
  • 方法实例

前言

URL(Uniform Resource Locator)中文名为统一资源定位符,有时也被俗称为网页地址。表示为互联网上的资源,如网页或者 FTP 地址。URL 可以分为如下几个部分:

protocol://host:port/path?query#fragment

其中 protocol 表示协议,可以是 HTTP、HTTPS、FTP 和 File;host 表示主机名;port 表示端口号;path 表示文件路径及文件名。

一个 Http 协议的 URL 实例如下:

http://www.runoob.com/index.html?language=cn#j2se

该 URL 实例 可以被解析为:

  • 协议为(protocol):http
  • 主机为(host:port):www.runoob.com
  • 端口号为(port): 80 ,以上URL实例并未指定端口,因为 HTTP 协议默认的端口号为 80。
  • 文件路径为(path):/index.html
  • 请求参数(query):language=cn
  • 定位位置(fragment):j2se,定位到网页中 id 属性为 j2se 的 HTML 元素位置 。

URL 类方法

在java.net包中定义了URL类,该类用来处理有关URL的内容。java.net.URL提供的 URL 构建方式如下:

序号

方法描述

1

public URL(String protocol, String host, int port, String file) throws MalformedURLException,通过给定的参数(协议、主机名、端口号、文件名)创建URL

2

public URL(String protocol, String host, String file) throws MalformedURLException,使用指定的协议、主机名、文件名创建URL,端口使用协议的默认端口

3

public URL(String url) throws MalformedURLException,通过给定的URL字符串创建URL

4

public URL(URL context, String url) throws MalformedURLException,使用基地址和相对URL创建

URL类中包含了很多方法用于访问URL的各个部分,具体方法及描述如下:

序号

方法描述

1

public String getPath(),返回URL路径部分

2

public String getQuery(),返回URL查询部分

3

public String getAuthority(),获取此 URL 的授权部分

4

public int getPort(),返回URL端口部分

5

public int getDefaultPort(),返回协议的默认端口号

6

public String getProtocol(),返回URL的协议

7

public String getHost(),返回URL的主机

8

public String getFile(),返回URL文件名部分

9

public String getRef(),获取此 URL 的锚点(也称为"引用")

10

public URLConnection openConnection() throws IOException,打开一个URL连接,并运行客户端访问资源

URLConnections 类方法

URL 的 openConnection() 方法返回一个 java.net.URLConnection,该实例表示与URL 引用的远程对象的连接。例如:

  • 如果你连接HTTP协议的URL, openConnection() 方法返回 HttpURLConnection 对象。
  • 如果你连接的URL为一个 JAR 文件, openConnection() 方法将返回 JarURLConnection 对象。
  • 等等...

URLConnection 方法列表如下:

序号

方法描述

1

Object getContent() ,检索URL链接内容

2

Object getContent(Class[] classes) ,检索URL链接内容

3

String getContentEncoding() ,返回头部 content-encoding 字段值

4

int getContentLength() ,返回头部 content-length字段值

5

String getContentType() ,返回头部 content-type 字段值

6

int getLastModified() ,返回头部 last-modified 字段值

7

long getExpiration() ,返回头部 expires 字段值

8

long getIfModifiedSince() ,返回对象的 ifModifiedSince 字段值

9

public void setDoInput(boolean input),URL 连接可用于输入和/或输出。如果打算使用 URL 连接进行输入,则将 DoInput 标志设置为 true;如果不打算使用,则设置为 false。默认值为 true

10

public void setDoOutput(boolean output),URL 连接可用于输入和/或输出。如果打算使用 URL 连接进行输出,则将 DoOutput 标志设置为 true;如果不打算使用,则设置为 false。默认值为 false

11

public InputStream getInputStream() throws IOException,返回URL的输入流,用于读取资源

12

public OutputStream getOutputStream() throws IOException,返回URL的输出流, 用于写入资源

13

public URL getURL(),返回 URLConnection 对象连接的URL

方法实例

获取URL的各个部分参数

public class Test {
    public static void main(String[] args) {
        try
        {
            URL url = new URL("http://www.juejin.cn/index.html?language=cn#j2se");
            System.out.println("URL 为:" + url.toString());
            System.out.println("协议为:" + url.getProtocol());
            System.out.println("验证信息:" + url.getAuthority());
            System.out.println("文件名及请求参数:" + url.getFile());
            System.out.println("主机名:" + url.getHost());
            System.out.println("路径:" + url.getPath());
            System.out.println("端口:" + url.getPort());
            System.out.println("默认端口:" + url.getDefaultPort());
            System.out.println("请求参数:" + url.getQuery());
            System.out.println("定位位置:" + url.getRef());
        }catch(IOException e)
        {
            e.printStackTrace();
        }
    }
}

​​​​​​​// 以上程序执行结果为:
// URL 为:http://www.juejin.cn/index.html?language=cn#j2se
// 协议为:http
// 验证信息:www.juejin.cn
// 文件名及请求参数:/index.html?language=cn
// 主机名:www.juejin.cn
// 路径:/index.html
// 端口:-1
// 默认端口:80
// 请求参数:language=cn
// 定位位置:j2se

URL采用了HTTP 协议时,openConnection 返回HttpURLConnection对象

public class Test {
    public static void main(String[] args) {
        try {
            URL url = new URL("https://juejin.cn");
            URLConnection urlConnection = url.openConnection();
            HttpURLConnection connection = null;
            if(urlConnection instanceof HttpURLConnection) {
                connection = (HttpURLConnection) urlConnection;
            } else {
                System.out.println("请输入 URL 地址");
                return;
            }
            BufferedReader in = new BufferedReader(
                    new InputStreamReader(connection.getInputStream()));
            String urlString = "";
            String current;
            while((current = in.readLine()) != null) {
                urlString += current;
            }
            System.out.println(urlString);
        }catch(IOException e) {
            e.printStackTrace();
        }
    }
}

// 以上程序执行结果为:
// <!doctype html><html data-n-head-ssr lang="zh" data-n-head="%7B%22lang%22:%7B%22ssr%22:%22zh%22%7D%7D">  <head >    <title>稀土掘金</title>...

获取远程文件大小

public class Test {
    public static void main(String[] args) throws Exception {
        int size;
        URL url = new URL("https://juejin.cn");
        // 获取 URLConnection 实例
        URLConnection conn = url.openConnection();
        // 获取头部 content-length 字段值
        size = conn.getContentLength();
        if (size < 0)
            System.out.println("无法获取文件大小。");
        else {
            System.out.println("文件大小为:" + size + " bytes");
        }
        // 关闭输入流
        conn.getInputStream().close();
    }
}

​​​​​​​// 以上程序执行结果为:
// 文件大小为:84127 bytes

网页抓取

public class Test {
    public static void main(String[] args) throws Exception {
        URL url = new URL("https://juejin.cn");
        // 打开一个到此 URL 的连接,并返回一个 InputStream,将 InputStream 转为缓冲字符输入流
        BufferedReader reader = new BufferedReader
                (new InputStreamReader(url.openStream()));
        // 创建指定文件的字符输出流
        BufferedWriter writer = new BufferedWriter
                (new FileWriter("data.html"));
        String line;
        // 将读取内容写入文件
        while ((line = reader.readLine()) != null) {
            System.out.println(line);
            writer.write(line);
            writer.newLine();
        }
        // 关闭流
        reader.close();
        writer.close();
    }
}
​​​​​​​// 以上程序执行结果为:
// 网页的源代码,存储在当前目录下的 data.html 文件中

获取 URL 响应头的日期信息

public class Test {
    public static void main(String[] args) throws Exception {
        URL url = new URL("https://juejin.cn");
        HttpURLConnection httpCon =
                (HttpURLConnection) url.openConnection();
        // 获取头部日期字段的值
        long date = httpCon.getDate();
        if (date == 0) {
            System.out.println("无法获取信息。");
        } else {
            System.out.println("Date: " + new Date(date));
        }
    }
}

// 以上程序执行结果为:
// Date: Thu May 11 22:32:04 CST 2023

获取 URL 响应头信息

public class Test {
    public static void main(String[] args) throws Exception {
        URL url = new URL("http://www.runoob.com");
        URLConnection conn = url.openConnection();
        // 获取头部字段的不可修改映射
        Map headers = conn.getHeaderFields();
        // 遍历头部字段映射键值
        Set<String> keys = headers.keySet();
        for( String key : keys ){
            String val = conn.getHeaderField(key);
            System.out.println(key+"    "+val);
        }
        System.out.println( conn.getLastModified() );
    }
}

​​​​​​​// 以上程序执行结果为:
// null    HTTP/1.1 302 Moved Temporarily
// X-Cache-Status    MISS
// Server    JSP3/2.0.14
// Connection    keep-alive
// Content-Length    144
// Date    Thu, 11 May 2023 14:37:51 GMT
// Location    https://www.runoob.com/
// Content-Type    text/html
// 0

查看主机指定文件的最后修改时间

public class Test {
    public static void main(String[] args) throws Exception {
        URL u = new URL("https://static.runoob.com/assets/upvotejs/dist/upvotejs/upvotejs.vanilla.js");
        URLConnection uc = u.openConnection();
        SimpleDateFormat ft = new SimpleDateFormat ("yyyy-MM-dd hh:mm:ss");
        // 将此 URLConnection 的 useCaches 字段的值设置为 false 以忽略缓存
        uc.setUseCaches(false);
        // 获取文件最后修改时间
        long timestamp = uc.getLastModified();
        System.out.println("vanilla.js 文件最后修改时间 :" + ft.format(new Date(timestamp)));
    }
}
// 以上程序执行结果为:
// vanilla.js 文件最后修改时间 :2019-08-01 06:23:35