本文阐述了 URL, URI,以及对应的java类的api;
1)URI采用特定语法标识网络资源,URI 是一个标识资源的字符串而已;
2)URI标识语法 模式:模式特定部分;
2.1)模式包括(可以理解为资源协议):
2.2)模式特定部分采用一种层次结构,如 //authority/path?k1=v1&k2=v2#anchor ;
1)URL 是一种URI, 除了标识一个网络资源,还提供资源的网络位置,以便查找; 客户端可以用它获取资源;
2)资源的网络位置包括 协议如http,服务器主机域名,端口,路径(查询参数,锚点或有); 3)URL语法如下:协议://userInfo@host:port/path?query#fragment
@Test public void f1() throws MalformedURLException { URL url = new URL("http://www.baidu.com"); System.out.println(url); System.out.println(url.getProtocol()); System.out.println(url.getPort()); System.out.println(url.getAuthority()); }
http://www.baidu.com
http
-1
www.baidu.com
@Test public void f2() throws IOException { URL url1 = new URL("https://blog.csdn.net/PacosonSWJTU/article/details/120964766"); URL url2 = new URL(url1, "120980127"); // 相对地址 System.out.println(url1.getPath()); // /PacosonSWJTU/article/details/120964766 System.out.println(url2.getPath()); // /PacosonSWJTU/article/details/120980127 }
从url获取数据(3种方式)
补充,URL.openStream() 方法如下:
public final InputStream openStream() throws java.io.IOException { return openConnection().getInputStream(); // 获取输入流 } // 打开连接 public URLConnection openConnection() throws java.io.IOException { return handler.openConnection(this); }
3.1)方法1,使用openStream() 方法
@Test public void f3() throws IOException { URL url1 = new URL("https://blog.csdn.net/PacosonSWJTU/article/details/120964766"); try (DataInputStream dataInputStream = new DataInputStream(url1.openStream())) { int c; while((c = dataInputStream.read()) != -1) { System.out.print((char)c); // 有乱码 无法对中文进行解析 } } }
改用基于UTF-8字符编码格式的 inputStreadReader 读取数据,(可以处理中文)如下:
@Test public void f4() throws IOException { URL url1 = new URL("https://blog.csdn.net/PacosonSWJTU/article/details/120964766"); // 采用utf-8 编码,可以解析中文字符 String str = null; try (BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(url1.openStream(), StandardCharsets.UTF_8))) { while((str = bufferedReader.readLine()) != null) { System.out.print(str); } } }
方法2,使用 URL.openConnection() 和 URLCOnnection.getInputStream() 方法 读取资源;
/** * @title 从URL获取资源内容-url1.openConnection()+urlConnection.getInputStream()方法 * @author xiaotang * @updateTime 2021/10/31 */ @Test public void f4_2() throws IOException { URL url1 = new URL("https://blog.csdn.net/PacosonSWJTU/article/details/120964766"); // 采用utf-8 编码,可以解析中文字符 String str = null; URLConnection urlConnection = url1.openConnection(); try (BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(urlConnection.getInputStream(), StandardCharsets.UTF_8))) { while((str = bufferedReader.readLine()) != null) { System.out.print(str); } } }
方法3,使用 URL.getContent() 方法读取资源
/** * 通过 getContent() 获取资源内容 */ @Test public void f5() throws IOException { URL url1 = new URL("https://blog.csdn.net/PacosonSWJTU/article/details/120964766"); // getContent() 获取资源内容 Object o = url1.getContent(); System.out.println(o); // sun.net.www.protocol.http.HttpURLConnection$HttpInputStream@694e1548 } /** * 通过 getContent(Class[] classes) 获取资源内容 */ @Test public void f6() throws IOException { URL url1 = new URL("https://blog.csdn.net/PacosonSWJTU/article/details/120964766"); Class<?>[] arr = {String.class, Reader.class, InputStream.class}; Object o = url1.getContent(arr); System.out.println(o); // sun.net.www.protocol.http.HttpURLConnection$HttpInputStream@694e1548 InputStream inputStream = (InputStream) o ; BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(inputStream, StandardCharsets.UTF_8)); String result = null; while((result = bufferedReader.readLine()) != null) { System.out.println(result); } }
1)URL 包括5部分;
/** * @title 分解URL, URL 包括5部分 * @author xiaotang * @updateTime 2021/10/31 */ @Test public void f6() throws IOException { URL url = new URL("https://blog.csdn.net/PacosonSWJTU/article/details/120904564?k1=v1&k2=v2#anchor=1"); System.out.println(url.getProtocol()); System.out.println(url.getHost()); System.out.println(url.getPort()); System.out.println(url.getFile()); System.out.println(url.getPath()); System.out.println(url.getRef()); System.out.println(url.getQuery()); System.out.println(url.getUserInfo()); System.out.println(url.getAuthority()); }
https
blog.csdn.net
-1
/PacosonSWJTU/article/details/120904564?k1=v1&k2=v2
/PacosonSWJTU/article/details/120904564
anchor=1
k1=v1&k2=v2
null
blog.csdn.net
2)URL相等性
/** * @title URL 相等性 * @author xiaotang * @updateTime 2021/10/31 */ @Test public void f7() throws IOException { URL url1 = new URL("https://blog.csdn.net/PacosonSWJTU/article/details/120904564?k1=v1&k2=v2#anchor=1"); URL url2 = new URL("https://blog.csdn.net/PacosonSWJTU/article/details/120904564?k1=v1&k2=v2#anchor=1"); if (url1.equals(url2)) { // equals 底层调用了 sameFile() 方法 System.out.println(url1 + "is equals to " + url2); } else { System.out.println(url1 + "is not equals to " + url2); } System.out.println(url1.sameFile(url2)); // true }
3)URL 比较
// URL比较,调用URl.toString() toExternalForm(), toURI() @Test public void f8() throws Exception { URL url1 = new URL("http://www.baidu.com?name=张三&city=成都#anchor=2"); System.out.println(url1.toString()); // System.out.println(url1.toExternalForm()); URI uri2 = url1.toURI(); // URL 转为 URI 类 System.out.println(uri2); }
1)URI 包含 URL 和 URN;即 统一资源标识符包括 统一资源定位符 + 统一资源名称;
2)URI 与 URL 的3个区别
简单点, URL对象 是对应网络获取的应用层协议的一个表示,而URI 对象用于解析和处理字符串;
1)构建URI;
// 相对uri @Test public void f11() throws Exception { URI uri = new URI("https://blog.csdn.net/PacosonSWJTU/article/details/120964766"); System.out.println(uri); URI uri2 = uri.resolve("59483747"); // 相对地址 59483747 System.out.println(uri2); // https://blog.csdn.net/PacosonSWJTU/article/details/59483747 }
2)URI的各个部分
模式:模式特定部分:片段;
// 获取URI属性 @Test public void f10() throws Exception { URI uri = new URI("https://blog.csdn.net/PacosonSWJTU/article/details/120904564?k1=v1&k2=张三#anchor=1"); System.out.println(uri.isOpaque()); System.out.println(uri.getAuthority()); System.out.println(uri.getFragment()); System.out.println(uri.getHost()); System.out.println(uri.getPath()); System.out.println(uri.getPort()); System.out.println(uri.getQuery()); System.out.println(uri.getUserInfo()); /* 获取原生数据 */ System.out.println("----------------- raw -------------------"); System.out.println(uri.getRawAuthority()); System.out.println(uri.getRawFragment()); System.out.println(uri.getRawPath()); System.out.println(uri.getRawQuery()); System.out.println(uri.getRawUserInfo()); System.out.println(uri.getRawSchemeSpecificPart()); }
false
// 如果 URI是一个层次URI,则返回false; 若URI不是层次URI,即不是透明的,返回true
blog.csdn.net
anchor=1
blog.csdn.net
/PacosonSWJTU/article/details/120904564
-1
k1=v1&k2=张三
null
----------------- raw -------------------
blog.csdn.net
anchor=1
/PacosonSWJTU/article/details/120904564
k1=v1&k2=张三
null
//blog.csdn.net/PacosonSWJTU/article/details/120904564?k1=v1&k2=张三
@Test public void f11() throws Exception { URI uri = new URI("https://blog.csdn.net/PacosonSWJTU/article/details/120964766"); System.out.println(uri); URI uri2 = uri.resolve("59483747"); // 相对地址 59483747 System.out.println(uri2); // https://blog.csdn.net/PacosonSWJTU/article/details/59483747 }
// uri 字符串表示 @Test public void f12() throws Exception { URI uri = new URI("https://blog.csdn.net/PacosonSWJTU/article/details/120964766?name=张三"); System.out.println(uri.toString()); // https://blog.csdn.net/PacosonSWJTU/article/details/120964766?name=张三 System.out.println(uri.toASCIIString()); // https://blog.csdn.net/PacosonSWJTU/article/details/120964766?name=%E5%BC%A0%E4%B8%89 }
1) x-www-form-urlencoded
1.1)介绍: intro2 x-www-form-urlencode, refer2
https://developer.mozilla.org/zh-CN/docs/Web/HTTP/Methods/POST
2)编码与解码
// 对url进行编码与解码 格式为 x-www-form-urlencode ; // intro2 x-www-form-urlencode, refer2 https://developer.mozilla.org/zh-CN/docs/Web/HTTP/Methods/POST @Test public void f13() throws Exception { System.out.println(URLEncoder.encode("hello world", StandardCharsets.UTF_8.displayName())); System.out.println(URLEncoder.encode("hello world 张三", StandardCharsets.UTF_8.displayName())); // 编码 String str = URLEncoder.encode("hello world 张三", StandardCharsets.UTF_8.displayName());// 编码-> hello+world+%E5%BC%A0%E4%B8%89 String decodedStr = URLDecoder.decode(str, StandardCharsets.UTF_8.displayName());// 解码->hello world 张三 System.out.println(decodedStr); }
3)url编码方式
3.1)背景
在发明web时,unicode 还没有完全普及,所以并不是所有系统都可以处理 本(中文)之类的字符;为了解决这个问题,URL 中使用的字符必须来自 ASCII的一个固定的子集,包括:
3.2)url编码方式如下:
除了 ascii数字,字母和前面指定的标点符号外,所有其他字符都要转换为字节,每个字节要写为 百分号后面加两个16进制数字;
空格是一种特殊情况, 因为它太普遍了;除了编码为 %20,还可以编码为 为加号+;加号本身编码为 %2B ;