《Java核心技术II》获取Web数据URL和URI使用URLConnection获取信息

news/2025/1/21 1:49:33/

4.3 获取Web数据

4.3.1 URL和URI

URL和URLConnection类封装了大量复杂的实现细节,这些细节涉及如何从站点获取信息。
从字符串构建URL对象,openStream方法产生输入流对象,用Scanner构建这个对象。
var url = new URL(urlString);
InputStream inStream = url.openStream();
var in = new Scanner(inStream,StandardCharsets.UTF-8);

统一资源定位符:(Uniform Resource Locator,URL),是URI的特例,包含定位Web资源的足够信息。
统一资源标识符:(Uniform Resource Identifier,URI),包含指定Web资源的字符串的各种组成部分。
Java中,URI不会包含任何用于访问该标识符指向的资源的方法,唯一作用是解析。
URL可以打开一个链接到资源的流,因此,URL只能作用于Java类库知道的方式,如http,https,ftp,file,jar等。
基于服务器的URI:[user-info@]host:[:port]
URI类的作用之一就是解析标识符并将它分解成各种不同的组成部分,可以用一下方法读取它们。
getScheme,getSchemeSpecificPart,getAuthority,getUserInfo,getHost,getPort,getPath,getQuery,getFragment。
一个绝对URI和相对URI可以组成和一个绝对URL.
绝对URL http://docs.mycompany.com/api/
绝对URL http://docs.mycompany.com/api/java/lang/String.html
相对化之后 java/lang/String.html

4.3.2 使用URLConnection获取信息

  • 调用URL中的openConnection方法获得对象
  • 使用这些方法来设置请求属性,setDoInput,setDoOutput,setIfModifiedSince,SetUseCaches,setAllowUserInteraction,setRequestProperty,setConnectTimeout,setReadTimeout。
  • 调用connect方法连接远程资源,除与服务器建立套接字外,可用于查询头信息(header information)。
  • 建立连接后,getHeaderFieldKey,getHeaderField枚举了消息头的所有字段,getHeaderFields返回Map对象,具体查询各标准字段:getContentType,getContentLength,getContentEncoding,getDate,getExpiration,getLastModified。
  • 访问资源数据,getInputStream方法获取一个输入流读取信息。
与Socket类并不相似,要严格遵循连接步骤。
setRequestProperty统揽全局
想访问一个有密码保护的Web页面,必须按照如下步骤:
  • 将用户名,冒号和密码以字符串形式连接在一起。String input = username+":"+password;
  • 计算上一步骤所得字符串的Base64编码。(Base64将字节序列编码成可打印的ASCII字符序列)。
Base64.Encoder encoder = Base64.getEncoder();
String encoding = encoder.encodeToString(input.getBytes(StandardCharsets.UTF-8));
  • 用Authorization这个名字和asic+encoding的值调用setRequestProperty方法。
connection.setRequestProperty("Authorization","Basic "+encoding);
查询响应头信息,获得响应头第n个键,String key = connection.getHeaderFieldKey(n);
获得响应头的第n个值,String value = connection.getHeaderFieldKey(n);
getHeaderFields方法可以返回一个封装响应头字段的Map对象。
Map> headerFields = connection.getHeaderFields();
注释:可用connection.getHeaderField(0)或headerFields.get(null)获取相应状态,例如 200 OK。
用于访问响应头值的简便方法
键名-方法名-返回类型
  • Date, getDate, long
  • Expires, getExpiration, long
  • Last-Modified, getLastModified, long
  • Content-Length, getContentLength, int
  • Content-Type, getContentType, String
  • Content-Encoding, getContentEncoding, String
在命令行中输入一个URL以及用户名和密码
package 第4章网络.urlConnection;import java.net.URL;
import java.net.URLConnection;
import java.nio.charset.StandardCharsets;
import java.util.Base64;
import java.util.List;
import java.util.Map;
import java.util.Scanner;public class URLConnectionTest {public static void main(String[] args) {try {String urlName;if(args.length > 0) urlName = args[0];else urlName = "https://horstmann.com";var url = new URL(urlName);URLConnection connection = url.openConnection();//如果规定了命令行输入用户名密码if(args.length > 2) {String username = args[1];String password = args[2];String input = username+":"+password;Base64.Encoder encoder = Base64.getEncoder();String encoding = encoder.encodeToString(input.getBytes(StandardCharsets.UTF_8));connection.setRequestProperty("Authorization", "Basic "+encoding);}connection.connect();//打印响应头信息Map<String,List<String>> headers = connection.getHeaderFields();for (Map.Entry<String, List<String>> entry : headers.entrySet()) {String key = entry.getKey();for (String value : entry.getValue()) {System.out.println(key+": "+value);}}//打印6个简便方法System.out.println("------------");System.out.println("getContentType: "+connection.getContentType());System.out.println("getContentLength: "+connection.getContentLength());System.out.println("getContentEncoding: "+connection.getContentEncoding());System.out.println("getDate: "+connection.getDate());System.out.println("getExpiration: "+connection.getExpiration());System.out.println("getLastModified: "+connection.getLastModified());System.out.println("------------");String encoding = connection.getContentEncoding();if(encoding == null) encoding = "UTF-8";try (var in = new Scanner(connection.getInputStream(),encoding)){//打印10行for (int n = 1;in.hasNextLine() && n<=10; n++) {System.out.println(in.nextLine());}if(in.hasNextLine()) System.out.println("...");}} catch (Exception e) {e.printStackTrace();}}}

想要整体理解响应头的含义,请看《图解HTTP》

http://www.ppmy.cn/news/1564811.html

相关文章

AI编程工具使用技巧——通义灵码

活动介绍通义灵码1. 理解通义灵码的基本概念示例代码生成 2. 使用明确的描述示例代码生成 3. 巧妙使用注释示例代码生成 4. 注意迭代与反馈原始代码反馈后生成优化代码 5. 结合生成的代码进行调试示例测试代码 其他功能定期优化生成的代码合作与分享结合其他工具 总结 活动介绍…

在PyCharm中使用Anaconda中的虚拟环境

1、在File菜单中找到Settings 2、Settings中搜索interpreter&#xff0c;找到Python Interpreter&#xff0c;再点击Add 3、选择第一个local interpreter 4、如图&#xff1a; 5、找到anaconda安装位置中的envs文件夹&#xff0c;在里面选择需要添加的python环境&#xff0c;如…

规避路由冲突

路由冲突是指在网络中存在两个或多个路由器在进行路由选择时出现矛盾&#xff0c;导致网络数据包无法正确传输&#xff0c;影响网络的正常运行。为了规避路由冲突&#xff0c;可以采取以下措施&#xff1a; 一、合理规划IP地址 分配唯一IP&#xff1a;确保每个设备在网络中都有…

Redis系列之底层数据结构整数集IntSet

Redis系列之底层数据结构整数集IntSet 什么是IntSet IntSet&#xff0c;整数集合&#xff0c;是Redis集合类型的一种底层数据结构&#xff0c;当一个集合只包含整数值元素&#xff0c;并且这个集合的元素数量不多时&#xff0c;redis就会选用intset作为底层实现。 IntSet的数…

springboot 项目配置https

当你的前端网页添加了 https 后&#xff0c;那么 由于… 前端调用后端的接口&#xff0c;同样的也需要配置 https。下面以宝塔为例&#xff0c;如何实现&#xff0c;请看下面讲解&#xff1a; 1.准备好 SSL 证书 application.yml源文件&#xff1a; spring:redis:host: 60.20…

2024春秋杯密码题第一、二天WP

你是小哈斯? 题目内容&#xff1a; 年轻黑客小符参加CTF大赛&#xff0c;他发现这个小哈斯文件的内容存在高度规律性&#xff0c;并且文件名中有隐藏信息&#xff0c;他成功找到了隐藏的信息&#xff0c;并破解了挑战。得意地说&#xff1a;“成功在于探索与质疑&#xff0c…

人工智能之数学基础:线性表达和线性组合

本文重点 线性表达和线性组合作为线性代数的核心概念,不仅深刻揭示了向量空间的基本性质,也为解决复杂问题提供了直观而有效的方法。 向量组 要想学习线性表达和线性组合,先来理解向量组。在线性代数中,向量组是指由若干个向量构成的集合。这些向量可以是二维的、三维的…

Nvidia Blackwell架构深度剖析:深入了解RTX 50系列GPU的升级

在CES 2025上&#xff0c;英伟达推出了基于Blackwell架构的GeForce RTX 50系列显卡&#xff0c;包括RTX 5090、RTX 5080、RTX 5070 Ti和RTX 5070。一段时间以来&#xff0c;我们已经知晓了该架构的各种细节&#xff0c;其中许多此前还只是传闻。不过&#xff0c;英伟达近日在20…