web-dev-qa-db-ja.com

Java-文字列を有効なURIオブジェクトに変換する

StringからJava.net.URIオブジェクトを取得しようとしています。文字列には、パーセントエスケープシーケンスで置き換える必要がある文字があります。しかし、URLEncoderを使用してUTF-8エンコーディングで文字列をエンコードすると、/もエスケープシーケンスに置き換えられます。

Stringオブジェクトから有効なエンコードされたURLを取得するにはどうすればよいですか?

http://www.google.com?q=a bhttpを与える%3A%2F%2www.google.com ...出力をhttp://www.google。 com?q = a%20b

誰かがこれを達成する方法を教えてください。

Androidアプリでこれをしようとしています。だから、限られた数のライブラリにアクセスできます。

71
lostInTransit

試してみてください:org.Apache.commons.httpclient.util.URIUtil.encodeQuery in Apache commons-httpclient プロジェクト

このように( RIUtil を参照):

URIUtil.encodeQuery("http://www.google.com?q=a b")

となります:

http://www.google.com?q=a%20b

もちろん自分でそれを行うことができますが、URIの解析はかなり面倒になります...

56
Hans Doggen

Androidには、常にSDKの一部としてUriクラスがあります。 http://developer.Android.com/reference/Android/net/Uri.html

次のようなことができます。

String requestURL = String.format("http://www.example.com/?a=%s&b=%s", Uri.encode("foo bar"), Uri.encode("100% fubar'd"));
45
bensnider

ここでは、Androidユーザーを対象とする提案を1つ追加します。これにより、外部ライブラリを取得する必要がなくなります。また、一部の検索/置換文字ソリューションは、上記の答えは危険であり、避けるべきです。

これを試してみてください:

String urlStr = "http://abc.dev.domain.com/0007AC/ads/800x480 15sec h.264.mp4";
URL url = new URL(urlStr);
URI uri = new URI(url.getProtocol(), url.getUserInfo(), url.getHost(), url.getPort(), url.getPath(), url.getQuery(), url.getRef());
url = uri.toURL();

この特定のURLで、要求に使用できるようにこれらのスペースをエンコードする必要があることがわかります。

これは、Androidクラスで利用可能ないくつかの機能を利用します。最初に、URLクラスはURLを適切なコンポーネントに分割できるため、文字列の検索/置換を行う必要がありません第二に、このアプローチは、単一の文字列からではなくコンポーネントを介してURIを構築するときに、コンポーネントを適切にエスケープするURIクラス機能を利用します。

このアプローチの利点は、有効なURL文字列を取得し、自分で特別な知識を必要とせずに機能させることができることです。

33
Craig B

これが既に受け入れられた回答のある古い投稿であっても、現在の問題にうまく機能し、この方法について誰も言及していないようであるため、代替の回答を投稿します。

Java.net.URIライブラリを使用する場合:

URI uri = URI.create(URLString);

また、それに対応するURL形式の文字列が必要な場合:

String validURLString = uri.toASCIIString();

他の多くのメソッド(Java.net.URLEncoderなど)とは異なり、このメソッドは安全でないASCII文字(çé...)。


上記の例で、URLStringが次のStringである場合:

"http://www.domain.com/façon+Word"

結果のvalidURLStringは次のようになります。

"http://www.domain.com/fa%C3%A7on+Word"

これは適切にフォーマットされたURLです。

14
dgiugg

ライブラリが好きではない場合、これはどうですか?

URL全体でこの関数を使用しないでください。代わりに、コンポーネントでこれを使用する必要があります。 URLを作成するときの「a b」コンポーネントだけです。そうしないと、コンピューターは、どの文字が特別な意味を持ち、どの文字が文字通りの意味を持つはずかを知りません。

/** Converts a string into something you can safely insert into a URL. */
public static String encodeURIcomponent(String s)
{
    StringBuilder o = new StringBuilder();
    for (char ch : s.toCharArray()) {
        if (isUnsafe(ch)) {
            o.append('%');
            o.append(toHex(ch / 16));
            o.append(toHex(ch % 16));
        }
        else o.append(ch);
    }
    return o.toString();
}

private static char toHex(int ch)
{
    return (char)(ch < 10 ? '0' + ch : 'A' + ch - 10);
}

private static boolean isUnsafe(char ch)
{
    if (ch > 128 || ch < 0)
        return true;
    return " %$&+,/:;=?@<>#%".indexOf(ch) >= 0;
}
9
Tim Cooper

URIクラスの複数引数コンストラクターを使用できます。 URI javadocから:

複数の引数を持つコンストラクターは、それらが現れるコンポーネントの要求に応じて、不正な文字を引用します。パーセント文字( '%')は、これらのコンストラクターによって常に引用されます。その他の文字は保持されます。

あなたが使用する場合

URI uri = new URI("http", "www.google.com?q=a b");

次に、http:www.google.com?q=a%20bを取得しますが、これはあまり正しくありませんが、少し近づいています。

文字列にURLフラグメントが含まれていないことがわかっている場合(例 http://example.com/page#anchor )、次のコードを使用して目的のものを取得できます。

String s = "http://www.google.com?q=a b";
String[] parts = s.split(":",2);
URI uri = new URI(parts[0], parts[1], null);

安全にするために、文字列で#文字をスキャンする必要がありますが、これで開始できます。

4
Jason Day

文字列からURIオブジェクトを作成するプロジェクトの1つでも同様の問題がありました。きれいな解決策も見つかりませんでした。ここに私が思いついたものがあります:

public static URI encodeURL(String url) throws MalformedURLException, URISyntaxException  
{
    URI uriFormatted = null; 

    URL urlLink = new URL(url);
    uriFormatted = new URI("http", urlLink.getHost(), urlLink.getPath(), urlLink.getQuery(), urlLink.getRef());

    return uriFormatted;
}

必要に応じて、代わりに次のURIコンストラクターを使用してポートを指定できます。

URI uri = new URI(scheme, userInfo, Host, port, path, query, fragment);
4
Hervé Donner

よく使ってみた

String converted = URLDecoder.decode("toconvert","UTF-8");

これがあなたが実際に探していたものであることを願っていますか?

3
Amol Ghotankar

または、このクラスを使用できます。

http://developer.Android.com/reference/Java/net/URLEncoder.html

これは、APIレベル1以降のAndroidにあります.

しかし、面倒なことに、スペースを特別に処理します(%20の代わりに+で置き換えます)。これを回避するには、次のフラグメントを使用します。

URLEncoder.encode(value, "UTF-8").replace("+", "%20");

1
MrCranky

Java.netブログには、あなたが望むことをしたかもしれないクラスが先日ありました(しかし、今はダウンしているので確認できません)。

ここにあるこのコードは、おそらくあなたが望むように修正することができます:

http://svn.Apache.org/repos/asf/incubator/shindig/trunk/Java/common/src/main/Java/org/Apache/shindig/common/uri/UriBuilder.Java

ここに私がJava.netから考えていたものがあります: https://urlencodedquerystring.dev.Java.net/

1
TofuBeer

私は最終的にhttpclient-4.3.6を使用しました:

import org.Apache.http.client.utils.URIBuilder;
public static void main (String [] args) {
    URIBuilder uri = new URIBuilder();
    uri.setScheme("http")
    .setHost("www.example.com")
    .setPath("/somepage.php")
    .setParameter("username", "Hello Günter")
    .setParameter("p1", "parameter 1");
    System.out.println(uri.toString());
}

出力は次のようになります。

http://www.example.com/somepage.php?username=Hello+G%C3%BCnter&p1=paramter+1