【问题标题】:What is the idiomatic way to compose a URL or URI in Java?在 Java 中编写 URL 或 URI 的惯用方式是什么?
【发布时间】:2010-10-27 08:33:21
【问题描述】:

如何在 Java 中构建 URL 或 URI?有没有一种惯用的方式或库可以轻松做到这一点?

我需要允许从请求字符串开始,解析/更改各种 URL 部分(方案、主机、路径、查询字符串)并支持添加和自动编码查询参数。

【问题讨论】:

  • 在该问题关闭很久后对其进行投票,因为尚不清楚是否存在针对此问题的流行且不弃用的解决方案。我通过谷歌搜索“java URL 参数类”找到了这一点。
  • 我的目的是为 Java 找到一个 URL 构建器,这个问题至少对我有用。

标签: java url


【解决方案1】:

截至Apache HTTP Component HttpClient 4.1.3,来自官方tutorial

public class HttpClientTest {
public static void main(String[] args) throws URISyntaxException {
    List<NameValuePair> qparams = new ArrayList<NameValuePair>();
    qparams.add(new BasicNameValuePair("q", "httpclient"));
    qparams.add(new BasicNameValuePair("btnG", "Google Search"));
    qparams.add(new BasicNameValuePair("aq", "f"));
    qparams.add(new BasicNameValuePair("oq", null));
    URI uri = URIUtils.createURI("http", "www.google.com", -1, "/search",
                                 URLEncodedUtils.format(qparams, "UTF-8"), null);
    HttpGet httpget = new HttpGet(uri);
    System.out.println(httpget.getURI());
    //http://www.google.com/search?q=httpclient&btnG=Google+Search&aq=f&oq=
}
}

编辑:从 v4.2 开始,URIUtils.createURI() 已被弃用,取而代之的是 URIBuilder

URI uri = new URIBuilder()
        .setScheme("http")
        .setHost("www.google.com")
        .setPath("/search")
        .setParameter("q", "httpclient")
        .setParameter("btnG", "Google Search")
        .setParameter("aq", "f")
        .setParameter("oq", "")
        .build();
HttpGet httpget = new HttpGet(uri);
System.out.println(httpget.getURI());

【讨论】:

  • 这可行,但从 v4.2 开始,URIUtils.createURI() 已被弃用,取而代之的是 URIBuilder。从积极的方面来说,这个 URIBuilder 似乎有一个 addParameter() 方法,所以现在构建请求字符串应该更简单了。
  • URIBuilder builder = new URIBuilder() .setScheme("http") .setHost("www.google.com") .setParameters(qparams); 正如@stian所说的
  • Println 上面打印以下内容; google.com/…
  • 教程链接失效
  • 要给出多条路径时如何设置路径?例如。 "localhost/api/customer" + "/" +{Id1} + "/" + "summary?invoiceId=" + {Id2} + "&page=0&pageSize=10&q=" + {Id3};
【解决方案2】:

作为作者,我可能不是判断我的 URL/URI 构建器是否的最佳人选,但这里仍然是:https://github.com/mikaelhg/urlbuilder

我想要最简单的完整解决方案,在 JDK 之外零依赖,所以我不得不自己动手。

【讨论】:

  • 它看起来很棒 Mikael,你有没有想过将它发布到 maven Central?我知道它很小,但使用起来更容易。除了在 JAX-RS 中,我找不到类似的课程。缺乏依赖绝对是一个加分项。
  • 看起来不错,但既然它是一个构建器,因此是可变的,为什么只有参数的设置器,而不是主机、端口、协议和路径的设置器?而且,好吧,那些也没有吸气剂。 UPD:哦,它不是可变的 - setParameter 创建一个克隆。好吧,仍然 setHost/setPort/... 可以以相同的方式工作。或者,也许,一个可变版本也很不错。
  • “零依赖的最简单的完整解决方案” - 听起来你知道什么是重要的!您的答案应该是公认的恕我直言。包括所有的 HttpClient(包括它的所有版本更新,甚至弃用这个问题所涉及的 API)只是为了构建一个 url 是导致头重脚轻的 bug 困扰的应用程序的原因。
  • 终于在 Maven Central 上,我只花了四年时间就完成了。
  • @mikaelhg 谢谢!我正是在这一刻需要!
【解决方案3】:
【解决方案4】:

使用 HTTPClient 效果很好。

protected static String createUrl(List<NameValuePair> pairs) throws URIException{

  HttpMethod method = new GetMethod("http://example.org");
  method.setQueryString(pairs.toArray(new NameValuePair[]{}));

  return method.getURI().getEscapedURI();

}

【讨论】:

  • 现在已弃用此功能。有谁知道如何使用新的 HTTP 组件包来做同样的事情,因为它难倒我。
  • 新的4x版本不再支持这个了。
【解决方案5】:

有很多库可以帮助您构建 URI(不要重新发明轮子)。以下三个可以帮助您入门:


Java EE 7

import javax.ws.rs.core.UriBuilder;
...
return UriBuilder.fromUri(url).queryParam(key, value).build();

org.apache.httpcomponents:httpclient:4.5.2

import org.apache.http.client.utils.URIBuilder;
...
return new URIBuilder(url).addParameter(key, value).build();

org.springframework:spring-web:4.2.5.RELEASE

import org.springframework.web.util.UriComponentsBuilder;
...
return UriComponentsBuilder.fromUriString(url).queryParam(key, value).build().toUri();

另请参阅: GIST > URI Builder Tests

【讨论】:

【解决方案6】:

使用 OkHttp

现在是 2021,有一个非常受欢迎的库,名为 OkHttp,它在 GitHub 上已被加星标 40K 次。使用这个库,您可以构建一个如下所示的 url:

import okhttp3.HttpUrl;

URL url = new HttpUrl.Builder()
    .scheme("http")
    .host("example.com")
    .port(4567)
    .addPathSegments("foldername/1234")
    .addQueryParameter("abc", "xyz")
    .build().url();

【讨论】:

  • 我修正了一个错字,它是addPathSegment(不是addPathSegments)。
  • @PapaFreud 都因不同的原因而存在,已恢复修复。
【解决方案7】:

在因建议 URL 类而受到抨击之后。我会采纳评论者的建议并建议使用URI class。我建议您仔细查看 URI 的构造函数,因为该类一旦创建就非常不可变。
我认为此构造函数允许您在 URI 中设置您可能需要的所有内容。

URI(String scheme, String userInfo, String host, int port, String path, String query, String fragment)
          Constructs a hierarchical URI from the given components.

【讨论】:

  • 但它不提供从一组名称值对中实际构造和编码查询字符串的功能。
  • 正如神童对艾伦·帕特里奇所说的那样——不变性不能退化,要么是,要么不是;-) youtube.com/watch?v=_lvFns5Lubc
  • URI 的构造函数对路径做了一些讨厌的事情。详情请见blog.palominolabs.com/2013/10/03/…
  • 让这个答案作为一个例子来说明如何不这样做。
  • 字符串查询...感谢 Sun/Oracle 提供的粒度。我们将用加号替换所有空格,对所有参数进行 uri 编码,然后自己用 & 符号将它们链接在一起...... 反复敲击桌面
猜你喜欢
  • 1970-01-01
  • 2014-01-02
  • 1970-01-01
  • 2011-03-07
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2019-09-20
相关资源
最近更新 更多