网络——获取Web数

【0】README

0.1) 本文描述转自 core java volume 2, 旨在理解 “网络——获取Web数” 的基础知识;
0.2) for source code , please visit https://github.com/pacosonTang/core-java-volume/blob/master/coreJavaAdvanced/chapter3/URL/URLConnectionTest.java
0.3) 应用背景: 为了在 java 程序中访问web server, 你可能希望在更高级别上进行, 而不只是创建套接字连接和发送 HTTP 请求;
0.4) 本文源代码用到了 Base64Encode 编码器,参见: http://blog.csdn.net/pacosonswjtu/article/details/50614466


【1】URL 和 URI(统一资源定位符(Uniform Resource Locator, URL) 和统一资源标识符(Uniform Resource Identifier, URI))

1)URL和 URLConnection类:封装了大量复杂的实现细节, 这些细节涉及如何从远程站点获取信息;

  • 1.1)如可以用一个 string 创建一个 URL 对象:

    URL url = new URL(urlString);

  • 1.2)如果只是想获得该资源的内容, 可以使用 URL 类中的openStream 方法:

    URL url = new URL(urlName);
    InputStream stream = url.openStream();
    Scanner in = new Scanner(stream);

2)java.net 包对 统一资源定位符(Uniform Resource Locator, URL) 和统一资源标识符(Uniform Resource Identifier, URI) 做了非常有用 的区分;

  • 2.1)URI和URL的区别: (干货——URI和URL的区别)

    • 2.1.1)URI: URI 是一个纯粹的语法结构, 包含用来指定web 资源的字符串的各种组成部分; (干货——URI定义)
    • 2.1.2)URL: URL 是URI的一个特例, 它包含了用于定位Web 资源的足够信息, 其他URI, 比如 mailto:tang@gmail.com 就不属于定位符, 因为根据该标识符我们无法定位任何数据。 像这样的URI 我们称之为 URN(Uniform Resource name, 统一资源名称);(干货——URL定义)(干货——URN-统一资源名称)
  • 2.2) 在java 类库中, URI 类不包含任何用于访问资源的方法, 它唯一作用就是解析; 相反, URL类可以打开一个到达资源的流: 所以 URL类只能作用于 那些 java 类库知道该如何如理的模式,如 http: , https, ftp:, 本地文件系统(file:), jar 文件(jar:);

3)URI详解:

  • 3.1)URI 规范给出了标记这些标识符的规则,一个 URI 具有以下句法:

    [scheme:]schemeSpecificPart【#fragment】

  • 3.2)上式中, […]表示可选部分,且 : 和 # 可以被包含在标识符内;

  • 3.3)绝对URI 和 相对 URI: 包含scheme: 部分 的 URI 称为绝对URI ,否则是相对URI; (干货——绝对和相对URI)
  • 3.4)不透明URI: 如果绝对URI 的 schemeSpecificPart 不是以 / 开头的,称为不透明的;如, mailto:tang@gmail.com (干货——不透明URI)
  • 3.5)分层URI: 所有绝对的透明URI 和所有相对的URI 都是分层的, 如: http://www.baidu.com/index.html (干货——分层URI)
  • 3.6)一个分层URI 的schemeSpecificPart 具有以下结构:

    [//authority][path][?query]

    • 3.6.1)对于那些基于服务器的URI, authority 部分具有以下形式:

      [user-info@]host[:port] , 而port必须是整数;

4)URI的作用: (干货——URI的作用)

  • 4.1)URI 类的作用之一: 解析标识符并将它分解成各种不同的组成部分, 你可以用如下方法读取他们:

    getScheme
    getSchemeSpecificPart
    getAuthority
    getUserInfo
    getHost
    getPort
    getPath
    getQuery
    getFrament

  • 4.1)URI的另一个作用: (干货——URI 的绝对化 和 相对化)

  • 4.2)与以上过程相反的是相对化URI: 假设一个URI: http://docs.mycompany.com/api 和另一个URI:http://docs.mycompany.com/api/java/lang/String.html; 那么相对化之后的URI 就是: java/lang/String.html;
  • 4.3) URI 类同时支持以上两个操作: (干货——URI的绝对化 和 相对化)

    relative = base.relativize(combined);
    combined = base.resolve(relative);


【2】使用URLConnection获取信息

1)引入 URLConnection的目的: 如果想从某个web 资源获取更多信息, 应该使用 URLConnection 类,通过它能够得到比 URL类更多的控制功能; (干货——推荐使用URLConnection ,它能够得到比 URL类更多的控制功能)
2)如何操作一个 URLConnection对象:

  • step1) 调用 URL 类中的openConnection方法:

    URLConnection connection = url.openConnection();

  • step2)使用以下方法来设置任意的请求属性:

    setDoInput
    setDoOutput
    setIfModifiedSince
    setUseCaches
    setAllowUserInteration
    setRequestProperty
    setConnectTimeout
    setReadTimeout

  • step3) 调用 connect方法连接远程资源:

    connection.connect();

  • step4)与服务器建立连接后, 可以查询头信息。

    • step4.1) getHeaderFieldKey 和 getHeaderField 两个方法枚举消息头的所有字段;
    • step4.2) getHeaderFields 方法返回一个包含了消息头中所有字段的标准Map对象;
    • step4.3) 为了方便起见, 以下方法可以查询各个标准字段:

      getContentType
      getContentLength
      getContentEncoding
      getDate
      getExpiration
      getLastModified

  • step5)最后,访问资源数据。

    • step5.1)使用 getInputStream 方法获取一个输入流用以读取信息;

Attention)一些coders 在使用 URLConnection 类的过程中形成了错误的观念, 它们认为 URLConnection 类中的 getInputStream 和 getOutputStream 方法与 Socket 类中的这些方法相似,这是错误的想法; (干货——一些coders 在使用 URLConnection 类的过程中形成了错误的观念)
3)URLConnection类中的一些方法:有几个方法可以在与server 建立连接之前设置连接属性,最重要的方法是 setDoInput 和 setDoOutput方法;

  • 3.1) 如果想要获得输出流:则 connection.setDoOutput(true);
  • 3.2)setIfModifiedSince 方法: 用于高速连接你只对自某个特定日期以来被修改过的数据感兴趣;
  • 3.3)setUseCaches 和 setAllowUserInteraction 方法:这两种方法只作用于Applet;
  • 3.4) setUseCaches 方法: 用于命令浏览器首先检查它的缓存;
  • 3.5)setAllowUserInteraction方法: 用于在访问有密码保护的资源时弹出对话框;
  • 3.6)总览全局的方法 setRequestProperty方法: 它可以用来设置对特定协议起作用的任何 “键值对”;

4)看个荔枝:如果你想访问一个由密码保护的web 页面, 按如下步骤操作:

  • step1) 将用户名,,冒号, 密码连接在一起:

    String input = username + “:” + password;

  • step2) 计算上一步骤得到的 Base64 编码;Base64 编码用于将字节序列编码成可打印的ASCII字节序列; (干货——Base64编码)

    String encoding = base64Encode(input);

  • step3)调用 setRequestProperty 方法,设置name参数的值为 Authorization , value设置为 Basic + encoding;

    connection.setRequestProperty(“Authorization”, “Basic” + encoding);

5)一旦调用了 connect方法, 就可以查询响应头信息;

  • step1)枚举所有相应头的字段:

    String key = connnection.getHeaderFieldKey(n); // 可以获得第n个键,n从 1开始;

  • step2)得到第n个值;

    String key = connnection.getHeaderField(n); // 可以获得第n个键,n从 1开始;

  • step3) getHeaderFields 方法: 返回一个 封装类响应头字段的Map 对象;

    Map<String, List< String>> headers = connection.getHeaderFields();

6) 为简单起见: java 提供了6个方法用以访问最常用的消息头类型的值, 并在需要的时候将其转换为 数值类型,见下表所示: (干货——java 提供了6个方法用以访问最常用的消息头类型的值)

这里写图片描述

7)看个荔枝(如何从web server 读取数据) 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值