仅针对查询字符串解析java.net.URI

6

我正在尝试使用JDK java.net.URI 构建URI。
我想要将一个查询(以字符串形式)附加到绝对URI对象中。例如:

URI base = new URI("http://example.com/something/more/long");
String queryString = "query=http://local:282/rand&action=aaaa";
URI query = new URI(null, null, null, queryString, null);
URI result = base.resolve(query);

理论上(或者我认为)resolve应该返回:
http://example.com/something/more/long?query=http://local:282/rand&action=aaaa

但我获得的是:
 http://example.com/something/more/?query=http://local:282/rand&action=aaaa

为什么#resolve()方法会忽略路径的最后一部分?如果新的URI(query)是这样构建的:

URI query = new URI(null, null, base.getPath(), queryString, null);

它运行良好。


请查看此链接 - https://dev59.com/vHE85IYBdhLWcg3wZyqt - Subhrajyoti Majumder
2个回答

4
我来回答这个问题。Javadoc解释得非常正确。就像URI#resolve()中的第3.b部分所说:

否则,给定URI的路径是相对路径,因此新URI的路径通过将给定URI的路径与此URI的路径解析得到。这是通过将此URI的路径(如果有的话)除了最后一段之外的所有内容与给定URI的路径连接起来,然后按照调用normalize方法的方式对结果进行规范化来完成的。

所以...我没有正确阅读。我应该删除这个回复吗?还是让它由我自己回复?

文档很清晰,但是动机是什么?为什么要删除最后一段? - Gaëtan Sheridan
这显然违反了WHATWG URL规范:https://url.spec.whatwg.org/#relative-state,不幸的是,这个问题有一个错误报告:https://bugs.java.com/bugdatabase/view_bug.do? Bug_id = 6519518,解决方案是“不会修复”,因为-遗留问题。 - Guss
1
我在这里针对URI类创建了一个错误报告:https://bugs.java.com/bugdatabase/view_bug.do?bug_id=JDK-8218962,Oracle的错误跟踪系统没有社区评论功能,但至少我们可以跟踪该问题的进展。 - Guss

1

第一种情况:

base = http://example.com/something/more/long

query的评估结果为

query = ?query=http://local:282/rand&action=aaaa.

根据方法 public URI resolve(URI uri) 的文档,它会将查询URI与基本URI进行解析。在解析过程中,如果该方法在查询URI中找到路径,则将相同的路径分配给新解析的URI。在这种情况下,query 没有关联的路径。如果您查看下面的 resolve() 函数片段,就会更加清楚。

//片段

 String cp = (child.path == null) ? "" : child.path;
        if ((cp.length() > 0) && (cp.charAt(0) == '/')) {
        // 5.2 (5): Child path is absolute
        ru.path = child.path;
        } else {
        // 5.2 (6): Resolve relative path
        ru.path = resolvePath(base.path, cp, base.isAbsolute());
        }

其中cp是子级(在您的情况下是查询路径)。由于它在这里为空,流程进入else循环,解析的查询被分配了一个来自基本URI的路径。

您的新URI具有此路径/something/more/,因为它剥离了最后一个“ /”字符之后的所有内容。

第二种情况:

基础= http://example.com/something/more/longquery评估为

query = /something/more/long?query=http://local:282/rand&action=aaaa

这里进入if循环,将查询路径分配给新URI的路径。您的查询URI路径为/something/more/long,即它也包括“long”值。也许这就是他们解析URI的方式。请查看文档,您会更清楚地了解它。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接