JavaでURLまたはURIを作成する慣用的な方法は何ですか?


115

JavaでURLまたはURIを作成するにはどうすればよいですか?慣用的な方法、またはこれを簡単に行うライブラリはありますか?

リクエスト文字列から開始し、さまざまなURL部分(スキーム、ホスト、パス、クエリ文字列)を解析/変更し、クエリパラメータの追加と自動エンコードをサポートする必要があります。


7
この問題に対する一般的な非推奨の解決策が存在するかどうかが不明であるため、質問を閉じてからかなり後の時点で賛成票を投じます。これは、「java URLパラメータクラス」をグーグル検索して見つけました。
user1445967 2013

4
私の意図はJavaのURLビルダーを見つけることでした、そしてこの質問は少なくとも私にとっては役に立ちます。
whirlwin

回答:


76

Apache HTTPコンポーネント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=
}
}

編集: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());

20
これは機能しますが、v4.2以降、URIUtils.createURI()は非推奨になり、URIBuilderが優先されます。肯定的な面では、このURIBuilderにはaddParameter()メソッドがあるように思われるので、リクエスト文字列の作成は少なくとも今はもっと簡単になるはずです。
stian 2012年

6
URIBuilder builder = new URIBuilder() .setScheme("http") .setHost("www.google.com") .setParameters(qparams);@stianが言ったように
vanduc1102 2015年

上記のPrintlnは以下を出力します。google.com/...
Berkanエルカン

61

著者として、私はおそらく私のURL / URIビルダーが優れているかどうかを判断するのに最適な人ではありませんが、それでも以下のとおりです:https : //github.com/mikaelhg/urlbuilder

私は、JDKの外部に依存関係がなく、可能な限り単純な完全なソリューションを求めていたので、自分でロールする必要がありました。


6
それは素晴らしいミカエルに見えます、それをMaven Centralに公開することを考えましたか?私はその小さいことを知っていますが、それを使いやすくします。JAX-RS以外に同様のクラスが見つかりません。依存関係の欠如は間違いなくプラスです。
Barry Pitman

見た目は良いですが、ビルダーなので変更可能であるため、ホスト、ポート、プロトコル、パスではなく、パラメーターのみのセッターがあるのはなぜですか?そして、まあ、それらのためのゲッターはありません。UPD:ああ、それは変更可能ではありません-setParameterはクローンを作成します。まあ、それでもsetHost / setPort / ...は同じように機能します。または、おそらく、変更可能なバージョンもあるとよいでしょう。
mvmn 2013年

3
「依存関係がゼロの最も単純で完全なソリューション」-重要なことをご存じのようですね。あなたの答えは、受け入れられたものであるはずです。URLを構築するためだけにすべてのHttpClientを含める(バージョンの更新をすべて行い、APIを非推奨にすることさえも含む)ことが、バグの多いアプリのトップヘビーになる理由です。
Stijn de Witt

2
最後にMaven Centralで、完了するまでに4年しかかかりませんでした。
ミカエルゲック

@mikaelhgありがとうございます!この瞬間に私はまさに必要です!
Fabian Damken、2016年


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

}

6
これは現在非推奨の機能です。新しいHTTPコンポーネントパッケージを使用して同じことを行う方法を知っている人はいますか?
Link19

3
新しい4xバージョンはこれをサポートしなくなりました。
ジョシャ

13

URIの作成に役立つライブラリはたくさんあります(ホイールを再発明しないでください)。ここにあなたを始めるための3つがあります:


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テスト


2
EE 7が正解です。必要なのは、EEライブラリのスイート全体をプルし、JAX-RS実装を選択し、jax-rsバージョンの競合を解決することだけです。そして報酬として、非常にうまく機能する便利なUriBuilderクラスを用意できます。皮肉はさておき、これ正解です。:)
tekHedd


10

OkHttpを使用する

それはだ2020と名付けられ、非常に人気のライブラリがありOkHttp主演してきた35K GitHubの上で時間が。このライブラリを使用すると、以下のようなURLを構築できます。

import okhttp3.HttpUrl;

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

タイプミスを修正しました、それはaddPathSegment(ではありませんaddPathSegments)です。
PapaFreud

1

URLクラスを提案したとして非難された後。私はコメンターのアドバイスを受けて、代わりにURIクラスを提案します。クラスは一度作成すると非常に不変であるため、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.

8
ただし、名前と値のペアのセットからクエリ文字列を実際に作成およびエンコードする機能は提供していません。
Link19

4
子供の天才がアランパートリッジに言ったように-不変性の低下はあり得ません、それはそうであるか、そうではありません;-) youtube.com/watch?v=_lvFns5Lubc
Stewart

URIのコンストラクターはパスに対して厄介なことを行います。詳細はblog.palominolabs.com/2013/10/03/…をご覧ください。
mpierce 2013年

1
この回答を、これを行わない方法の例として示してください。
Mike Pone 2013年

1
文字列クエリ...細分性についてSun / Oracleに感謝します。すべてのスペースをプラス記号で置き換え、すべてのパラメーターをuriエンコードし、それらすべてをアンパサンド記号でリンクします。その後 、テーブルに繰り返し頭をぶつけます
Stijn de Witt
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.