在Java中组合URL或URI的惯用方法是什么?

jon*_*077 111 java url

如何在Java中构建URL或URI?是否有惯用的方式,或者很容易做到这一点的库?

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

Chi*_*kei 75

从Apache HTTP Component HttpClient 4.1.3开始,来自官方教程:

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=
}
}
Run Code Online (Sandbox Code Playgroud)

编辑:从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());
Run Code Online (Sandbox Code Playgroud)

  • 这是有效的,但是从v4.2开始,URIUtils.createURI()已被弃用,有利于URIBuilder.从积极的方面来看,这个URIBuilder似乎有一个addParameter()方法,因此构建请求字符串至少应该更简单. (20认同)
  • `URIBuilder builder = new URIBuilder() .setScheme("http") .setHost("www.google.com") .setParameters(qparams);` 正如@stian 所说 (6认同)

Mik*_*eck 61

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

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

  • Mikael看起来很棒,你有没有想过把它发布到maven central?我知道它很小但更容易使用它.在JAX-RS中我找不到类似的类.缺乏依赖性绝对是一个加分. (6认同)
  • "最简单的完整解决方案,零依赖" - 听起来你知道什么是重要的!你的答案应该是公认的.包括所有HttpClient(包含所有版本的更新,甚至弃用这个问题的API)只是为了构建一个url,这是最重要的bug杂乱的应用程序. (3认同)
  • 最后在Maven Central,我只花了四年才完成. (2认同)

jon*_*077 29

使用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();

}
Run Code Online (Sandbox Code Playgroud)

  • 这是现已弃用的功能.有谁知道如何使用新的HTTP Components包来做同样的事情,因为它让我很难过. (6认同)
  • 新的4x版本不再支持此功能. (3认同)

Nic*_*aly 10

有很多库可以帮助您构建URI(不要重新发明轮子).这里有三个让你入门:


Java EE 7

import javax.ws.rs.core.UriBuilder;
...
return UriBuilder.fromUri(url).queryParam(key, value).build();
Run Code Online (Sandbox Code Playgroud)

org.apache.httpcomponents:HttpClient的:4.5.2

import org.apache.http.client.utils.URIBuilder;
...
return new URIBuilder(url).addParameter(key, value).build();
Run Code Online (Sandbox Code Playgroud)

org.springframework:弹簧网:4.2.5.RELEASE

import org.springframework.web.util.UriComponentsBuilder;
...
return UriComponentsBuilder.fromUriString(url).queryParam(key, value).build().toUri();
Run Code Online (Sandbox Code Playgroud)

另请参见: GIST> URI Builder测试

  • EE 7 是正确答案。您所要做的就是拉入整个 EE 库套件,选择一个 JAX-RS 实现,解决 jax-rs 版本冲突,作为奖励,您将拥有一个非常有用的方便的 UriBuilder 类。撇开讽刺不谈,这*是*正确答案。:) (2认同)

Tyl*_*ong 8

使用OkHttp

它是2018年,有一个非常受欢迎的名为OkHttp的图书馆,已经在GitHub上出演了27K次.使用此库,您可以构建如下所示的URL:

import okhttp3.HttpUrl;

URL url = new HttpUrl.Builder()
    .scheme("http")
    .host("example.com")
    .port(4567)
    .addPathSegment("foldername/1234")
    .addQueryParameter("abc", "xyz")
    .build().url();
Run Code Online (Sandbox Code Playgroud)