java.net.URL 类将 URL 地址进行了封装,并提供了解析 URL 地址的基本方法,比如获取 URL 的主机名和端口号。java.net.URLConnection 则代表了应用程序和 URL 之间的通信链接,可用于读取和写入此 URL 引用的资源。

URLConnection 看起来只是比 URL 多了一个 Connection,它们之间的关系也仅限于此吗?

01、什么是 URL

为了搞清楚什么是 URL,需要引入另外两个概念 URI 和 URN。

什么鬼,URL 都没搞清楚,又来两个搞不清楚的?别担心,我能像变了魔法一样让大家把三个都搞清楚。

  • URI = Universal Resource Identifier,中文释义为统一资源标志符
  • URL = Universal Resource Locator,中文释义为统一资源定位符
  • URN = Universal Resource Name,中文释义为统一资源名称

它们之间的关系如下图所示:

这图啥意思啊,怎么办呢?张小敬有问题就去问葛佬,咱不会就去问“维基百科”啊。

URI 可以分为 URL 和 URN,或者是 URL 和 URN 的结合体(同时具备 Locator 和 Name)。URN 就好像一个人的名字,URL 就像一个人的地址。换句话说:URN 确定了身份,URL 提供了找到它的方式。

概念清晰了吧?URI 是一个纯粹的句法结构,用于指定标识 Web 资源的字符串的各个不同部分。URL 是 URI 的一个特例,包含了定位 Web 资源的足够多的信息。URI 是统一资源标识符,而 URL 是统一资源定位符。URL 是 URI 的一种,比如:http://www.itmind.net/。但不是所有的 URI 都是 URL,因为 URI 可能包括一个子集,即统一资源名称 (URN,命名了资源但不指定如何定位资源),比如说:mailto:qing_gee@163.com。

吧啦吧啦说这么多挺累的,来一发实例吧,用于获取 URL 的主机名和端口号。

URL url = new URL("http://www.itmind.net/category/payment-selection/zhishixingqiu-jingxuan/");

System.out.println("host: " + url.getHost());
System.out.println("port: " + url.getPort());
System.out.println("uri_path: " + url.getPath()); // 输出
// host: www.itmind.net
// port: -1
// uri_path: /category/payment-selection/zhishixingqiu-jingxuan/

1)创建 java.net.URL 对象的方法非常简单,只需要一行代码。

URL url = new URL(URL地址);

URL 对象是不可变的,因为 URL 类是 final 类型的,这样的好处就是保证它是"线程安全"的。

2)有了 java.net.URL 对象后,就可以获取 URL 相关的主机名、端口、路径等等。

url.getHost()
url.getPort()
url.getPath()

02、什么是 URLConnection

URLConnection 是一个抽象类,代表应用程序和 URL 之间的通信链接。它的实例可用于读取和写入此 URL 引用的资源。该类提供了比 Socket 类更易于使用、更高级的网络连接抽象。

怎么获取 URLConnection 对象呢?通过 URL 对象的 openConnection() 方法,示例如下。

URL url = new URL("http://www.itmind.net");
URLConnection connection = url.openConnection();

如果 URL 协议为 HTTP 的话,返回的连接为 URLConnection 的子类 HttpURLConnection。

有了 URLConnection 对象后,可以通过 getInputStream() 返回一个 InputStream,由此读取 URL 所引用的资源数据(如果读取 ASCII 文本则为 ASCII;如果读取 HTML 文件则为原始 HTML,如果读取图像文件则为二进制图片数据等)。

我们来尝试读取一下小白学堂首页的内容,代码示例如下。

URL url = new URL("http://www.itmind.net");
URLConnection connection = url.openConnection(); try (InputStream in = connection.getInputStream();) {     ByteArrayOutputStream output = new ByteArrayOutputStream();
    byte[] buffer = new byte[1024];
    int len = -1;
    while ((len = in.read(buffer)) != -1) {
        output.write(buffer, 0, len);
    }     System.out.println(new String(output.toByteArray())); } catch (IOException e) {
    e.printStackTrace();
}

可以使用 try-with-resource 获取 InputStream,该类实现了 AutoCloseable 接口,可以在内容读取完毕后自动关闭输入流。

打印的内容如下图所示(部分):

如果你想读取某个 URL 的内容,上述方法是一个不错的方案,赶快去试试吧!

03、URL 和 URLConnection 的不同

URL 和 URLConnection 最大的不同在于:

  • URLConnection 提供了对 HTTP 头部的访问;
  • URLConnection 可以配置发送给某个 URL 的请求参数;
  • URLConnection 不仅可以读取 URL 定位的资源,还可以向其写入数据。

获取 HTTP 头部的方法有以下一些:

  • getContentType,返回 Content-type 头字段的值,即数据的 MIME 内容类型。若类型不可用,则返回 null。如果内容类型是文本,则 Content-type 首部可能会包含一个标识内容编码方式的字符集,例如:Content-type:text/html; charset=UTF-8

  • getContentLength(),返回 Content-length 头字段的值,即内容的字节数。

  • getContentEncoding(),返回 Content-encoding 头字段的值,即内容的编码方式(不同于字符编码方式),例如:x-gzip。

  • getDate(),返回 date 头字段的值,即请求的发送时间。

  • getExpiration(),返回 expires(过期时间) 头字段的值。如果返回 0,表示不过期,永远缓存。

  • getLastModified(),返回 last-modified(上次修改日期) 头字段的值。

代码示例如下。

URL url = new URL("http://www.itmind.net");
URLConnection connection = url.openConnection();
System.out.println(connection.getContentType());
System.out.println(connection.getContentLength());
System.out.println(connection.getContentEncoding());
System.out.println(connection.getDate());
System.out.println(connection.getExpiration());
System.out.println(connection.getLastModified()); // 输出
// text/html; charset=UTF-8
// -1
// null
// 1566886980000
// 0
// 0

Java 网络编程:必知必会的 URL 和 URLConnection的更多相关文章

  1. Java网络编程(二)IP、URL和HTTP

    一.IP InetAddress类有一些静态工厂方法,可以连接到DNS服务器来解析主机名. 示例1:InetAddress address = InetAddress.getByName(" ...

  2. 脑残式网络编程入门(三):HTTP协议必知必会的一些知识

    本文原作者:“竹千代”,原文由“玉刚说”写作平台提供写作赞助,原文版权归“玉刚说”微信公众号所有,即时通讯网收录时有改动. 1.前言 无论是即时通讯应用还是传统的信息系统,Http协议都是我们最常打交 ...

  3. 迈向高阶:优秀Android程序员必知必会的网络基础

    1.前言 网络通信一直是Android项目里比较重要的一个模块,Android开源项目上出现过很多优秀的网络框架,从一开始只是一些对HttpClient和HttpUrlConnection简易封装使用 ...

  4. 第4节:Java基础 - 必知必会(中)

    第4节:Java基础 - 必知必会(中) 本小节是Java基础篇章的第二小节,主要讲述抽象类与接口的区别,注解以及反射等知识点. 一.抽象类和接口有什么区别 抽象类和接口的主要区别可以总结如下: 抽象 ...

  5. 第3节:Java基础 - 必知必会(上)

    第3节:Java基础 - 必知必会(上) 本篇是基础篇的第一小节,我们从最基础的java知识点开始学习.本节涉及的知识点包括面向对象的三大特征:封装,继承和多态,并且对常见且容易混淆的重要概念覆盖和重 ...

  6. 必知必会之Java注解

    必知必会之Java注解 目录 不定期更新中-- 元注解 @Documented @Indexed @Retention @Target 常用注解 @Deprecated @FunctionalInte ...

  7. Java面试必知必会(扩展)——Java基础

    float f=3.4;是否正确? 不正确 3.4是双精度,将双精度赋值给浮点型属于向下转型,会造成精度损失: 因此需要强制类型转换: 方式一:float f=(float)3.4 方式二:float ...

  8. python网络爬虫,知识储备,简单爬虫的必知必会,【核心】

    知识储备,简单爬虫的必知必会,[核心] 一.实验说明 1. 环境登录 无需密码自动登录,系统用户名shiyanlou 2. 环境介绍 本实验环境采用带桌面的Ubuntu Linux环境,实验中会用到桌 ...

  9. 第5节:Java基础 - 必知必会(下)

    第5节:Java基础 - 必知必会(下) 本小节是Java基础篇章的第三小节,主要讲述Java中的Exception与Error,JIT编译器以及值传递与引用传递的知识点. 一.Java中的Excep ...

  10. Java并发必知必会第三弹:用积木讲解ABA原理

    Java并发必知必会第三弹:用积木讲解ABA原理 可落地的 Spring Cloud项目:PassJava 本篇主要内容如下 一.背景 上一节我们讲了程序员深夜惨遭老婆鄙视,原因竟是CAS原理太简单? ...

随机推荐

  1. BeanFactory体系结构

    BeanFactory是Spring中非常重要的一个类,搞懂了它,你就知道了bean的初始化和摧毁过程,对于深入理解IOC有很大的帮助. BeanFactory体系结构 首先看一下使用IDEA生成的继 ...

  2. LR有的JMeter也有之二“检查点”

    好吧!接着上一篇文章的内容和思路,继续前进. 检查点:简单的来理解一下,上一章讲到,我们对用户名和密码进行了参数化,那么怎样来判断jmeter有没有正确调用test.dat里面的文件呢.当然,我们可以 ...

  3. 用HTML5的Audio标签做一个歌词同步的效果

    HTML5出来这么久了,但是关于它里面的audio标签也就用过那么一次,当然还仅仅只是把这个标签插入到了页面中.这次呢就刚好趁着帮朋友做几个页面,拿这个audio标签来练练手. 首先你需要向页面中插入 ...

  4. 【游记】NOIP2019前传

    声明 我的游记是一个完整的体系,如果没有阅读过往届文章,阅读可能会受到障碍. ~~~上一篇游记的传送门~~~ 前言 比完赛后,我沉浸在胜利中长达半个月,而后才清醒过来,意识到自己需要为NOIP2019 ...

  5. 逆向破解之160个CrackMe —— 002-003

    CrackMe —— 002 160 CrackMe 是比较适合新手学习逆向破解的CrackMe的一个集合一共160个待逆向破解的程序 CrackMe:它们都是一些公开给别人尝试破解的小程序,制作 c ...

  6. Python递归函数,二分查找算法

    目录 一.初始递归 二.递归示例讲解 二分查找算法 一.初始递归 递归函数:在一个函数里在调用这个函数本身. 递归的最大深度:998 正如你们刚刚看到的,递归函数如果不受到外力的阻止会一直执行下去.但 ...

  7. 通过Blazor使用C#开发SPA单页面应用程序(1)

    2019年9月23——25日 .NET Core 3.0即将在.NET Conf上发布! .NET Core的发布及成熟重燃了.net程序员的热情和希望,一些.net大咖也在积极的为推动.NET Co ...

  8. LSTM+CRF维特比解码过程

    题目:给定长度为n的序列,标签数为m(标签值表示为1,2,....,m),发射概率矩阵E(n * m),其中E[i][j]表示第i个词预测为标签j的发射概率,转移概率矩阵T(m*m),其中T[i][j ...

  9. 高速开车换底盘记:Windows 与 Linux 部署都抗住了,但修车任务艰巨

    抱歉,又是一篇流水账,在排查问题的焦头烂额中写博客的确是一个挑战,望大家见谅. 今天园友溪源More发了一篇博文博客园翻车启示录,而翻车之后的最新进展是——昨天下午我们又把 .net core 引擎的 ...

  10. OpenResty 社区王院生:APISIX 的高性能实践

    2019 年 7 月 6 日,OpenResty 社区联合又拍云,举办 OpenResty × Open Talk 全国巡回沙龙·上海站,OpenResty 软件基金会联合创始人王院生在活动上做了&l ...