Java Uri和Url及Uri解析过程

文章详细介绍了URI的结构,包括scheme、authority、path、query和fragment等组成部分,并阐述了URL作为URI的子集。同时,文章讲解了URI的解析过程,包括协议、主机、端口、路径和查询参数的分解,以及URI.create()方法在处理URI字符串时的源码逻辑。
摘要由CSDN通过智能技术生成

uri遵循PFC2369规定

     foo://example.com:8042/over/there?name=ferret#nose
     \\_/   \\______________/\\_________/ \\_________/ \\__/
      |           |            |            |        |
   scheme     authority       path        query   fragment
      |   _____________________|__
     / \\ /                        \\
     urn:example:animal:ferret:nose

协议规定

统一资源标志符 - 维基百科,自由的百科全书 (wikipedia.org)

**scheme:[//[user:password@]host[:port]][/]path[?query][#fragment]**的结构

  • 协议(scheme):例如http或https。URI的方案部分应该由字母开头,后面跟着字母、数字、加号(“+”)、减号(“-”)或者点(“.”)。**URI.create(String str)**方法会检查方案部分是否符合这种规则。由字母开头,后面跟着字母、数字、加号(“+”)、减号(“-”)或者点(“.”)。
  • 用户信息(userInfo):可选的用户信息,通常在访问需要验证的资源时使用。
  • 主机名(host):服务器的名称或IP地址。URI的主机部分可以是一个域名,也可以是一个IP地址。如果是域名,那么它应该是一个有效的域名。如果是IP地址,那么它应该是一个有效的IPv4或IPv6地址。(即0-65535之间的整数)。
  • 端口(port):服务器上的端口号。如果URI包含端口,那么端口应该是一个有效的端口号(即0-65535之间的整数)。
  • 路径(path):服务器上资源的路径。
  • 查询参数(query):查询字符串,用于向服务器传递额外的参数。参数部分应该是由有效的查询字符组成的。无效的字符应该被正确地转义。
  • 片段(fragment):指向资源内部的一个标记或锚点。

url解析过程:

URI和URL的区别联系

URI:身份证号

统一资源标识符,表示Web上每一种可用的资源,如HTML文档,图像,视频片段,程序等都是由一个URI进行标识的。

Uri一定就是Url

URL:身份证住址+姓名

是URI的一个子集,统一资源定位符,URL可以用一种统一的格式来描述各种信息资源

URI解析过程

  1. 分解URI:将URI字符串分解为协议、主机、端口、路径和查询参数等组成部分。URI的一般格式是:protocol://host:port/path?query
  2. 解析协议:确定URI使用的scheme组件(协议)(如HTTP、FTP等)。协议通常是URI的开头部分,后跟://
  3. 解析主机和端口:确定URI指向的主机和端口。主机通常是URI中:///之间的部分。
  4. 解析路径:确定URI指向的资源路径。路径通常是URI中主机和查询参数之间的部分,以/开头。
  5. 解析查询参数:确定URI的查询参数。查询参数通常是URI中以?开头的键值对。如果字符串中存在?,解析并验证可选的query组件(查询参数)

URI.create()源码

public static URI create(String str) {
    try {
        return new URI(str);
    } catch (URISyntaxException x) {
        throw new IllegalArgumentException(x.getMessage(), x);
    }
}
//
void parse(boolean rsa) throws URISyntaxException {
            requireServerAuthority = rsa;
            int n = input.length();
            int p = scan(0, n, "/?#", ":");//p为":"所在位置,如果找到/?#抛出异常
            if ((p >= 0) && at(p, n, ':')) {
                if (p == 0)    // scheme为空,抛出异常
                    failExpecting("scheme name", 0);
                checkChar(0, L_ALPHA, H_ALPHA, "scheme name");//检查scheme的合法性。scheme的第一个字符必须是字母,剩下的字符可以是字母、数字、"+"、"-"或"."。
                checkChars(1, p, L_SCHEME, H_SCHEME, "scheme name");
                scheme = input.substring(0, p);//截取URI的scheme部分。
                p++;                    // Skip ':'
                if (at(p, n, '/')) {    //如果scheme后面紧跟着的是"/",则按照层次结构的方式解析URI
                    p = parseHierarchical(p, n);
                } else {              //否则,认为URI是不透明的
                    // opaque; need to create the schemeSpecificPart
                    int q = scan(p, n, "#");//如果URI包含"#",那么把"#"后面的部分解析为fragment。
                    if (q <= p)
                        failExpecting("scheme-specific part", p);
                    checkChars(p, q, L_URIC, H_URIC, "opaque part");
                    schemeSpecificPart = input.substring(p, q);
                    p = q;
                }
            } else {
                p = parseHierarchical(0, n);
            }
            if (at(p, n, '#')) {
                checkChars(p + 1, n, L_URIC, H_URIC, "fragment");
                fragment = input.substring(p + 1, n);
                p = n;
            }
            if (p < n)//如果在解析完所有组成部分后,还有剩余的字符,那么抛出异常,因为这些剩余的字符无法解析。
                fail("end of URI", p);
        }
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值