【问题标题】:Java's URL/URI doesn't resolve correctly links starting with ? (interrogation point)Java 的 URL/URI 不能正确解析以 ? 开头的链接。 (审讯点)
【发布时间】:2016-01-11 20:14:38
【问题描述】:

我正在尝试使用 Java 的 URLURI 类解析以问号 ? 开头的相对链接。

HTML 示例:

<a href="?test=xyz">Test XYZ</a>

代码示例(来自 Scala REPL):

import java.net._

scala> new URL(new URL("http://abc.com.br/index.php?hello=world"), "?test=xyz").toExternalForm()
res30: String = http://abc.com.br/?test=xyz

scala> (new URI("http://abc.com.br/index.php?hello=world")).resolve("?test=xyz").toString
res31: java.net.URI = http://abc.com.br/?test=xyz

问题是浏览器(在 Chrome、Firefox 和 Safari 上测试)输出以下 URL:http://abc.com.br/index.php?hello=world。它不会丢弃路径“index.php”。它只是替换了查询字符串部分。

似乎浏览器只是遵循https://stackoverflow.com/a/7872230/40876 中解释的电子规范。

Jsoup 库在我们使用 element.absUrl("href") 时会犯同样的“错误”,因为它还依赖于 java 的 URL 解析。

那么 java 的 URL/URI 解析相对路径是怎么回事?它是错误的/不完整的吗? 如何使其行为与浏览器实现相同?

【问题讨论】:

标签: java url jsoup uri relative-path


【解决方案1】:

这会很好用:

public static void main(String[] args) throws Exception {
    String base = "http://abc.com.br/index.php?hello=world";
    String relative = "?test=xyz";

    System.out.println(new URL(new URL(base), relative).toExternalForm());
    // http://abc.com.br/?test=xyz

    System.out.println((new URI(base)).resolve(relative).toString());
    // http://abc.com.br/?test=xyz

    System.out.println(org.apache.http.client.utils.URIUtils.resolve(new URI(base), relative).toString());
    // http://abc.com.br/index.php?test=xyz
}

URIUtils 存在于 org.apache.httpcomponents:httpclient 版本 4.0 或更高版本中。

【讨论】:

  • 我在stackoverflow.com/a/61578016/53538 中发布了简单的解决方法代码,因此您无需添加大量依赖项来解决 Java 错误。
  • 如果您“不想要第 3 方依赖” - 只需将该库中的工作代码复制粘贴到您的项目中即可。为什么要重新发明轮子?
  • 你说得对——当我从一个巨大的库中复制粘贴代码时,我最大的恐惧是单一方法永远不会独立:它们利用该库中的其他设施(和依赖项),所以它总是一个捉迷藏的游戏。我查看了URIUtils.resolve(),幸运的是它非常简单——它唯一的非 JDK 依赖是来自 Apache 的 httpcore 的 Args,可以删除和/或替换为 Objects.requireNonNull()。话虽如此,在查看了 Apache 的解决方法之后,我认为它有点幼稚,虽然我不能指出那里的具体错误,但我更喜欢我的 :)
猜你喜欢
  • 2016-02-23
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2019-11-05
  • 1970-01-01
  • 2012-01-29
  • 1970-01-01
相关资源
最近更新 更多