将字符串转换为有效的 URI 对象

我试图从 String中得到一个 java.net.URI对象。字符串中有一些字符需要用它们的百分比转义序列替换。但是当我使用 URLEncoder 以 UTF-8编码对 String 进行编码时,甚至/也被替换为它们的转义序列。

如何从 String 对象获得有效的编码 URL?

Http://www.google.com?q=a b 给出 译自: http://www.google.com。,而我希望输出为 < strong > > a href = “ http://www.google.com? q = a% 20b”rel = “ noreference rer”> http://www.google.com?q=a%20b

谁能告诉我怎么做到这一点。

我试图在一个 Android 应用程序中做到这一点,所以我可以访问数量有限的库。

157257 次浏览

您可以尝试: Apache commons-httpclient项目中的 org.apache.commons.httpclient.util.URIUtil.encodeQuery

像这样(见 URIUtil) :

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

将成为:

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

您当然可以自己完成,但 URI 解析可能会非常混乱..。

您可以使用 URI类的多参数构造函数:

多参数构造函数根据它们出现的组件的要求引用非法字符。这些构造函数始终引用百分比字符(’%’)。任何其他字符被保留。

所以如果你用

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

为了安全起见,您应该扫描字符串中的 #字符,但这应该可以让您开始。

前几天,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/

如果你不喜欢图书馆,这个怎么样?

请注意,你不应该在整个 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;
}

或者你可以使用这个类:

Http://developer.android.com/reference/java/net/urlencoder.html

从 API 级别1开始就存在于 Android 中。

然而,令人恼火的是,它特别对待空格(用 + 代替% 20)。为了解决这个问题,我们简单地使用这个片段:

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

Android 一直将 Uri 类作为 SDK 的一部分: 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"));

对于我的一个项目来说,从字符串创建 URI 对象也有类似的问题。我也找不到任何干净的解决办法。这是我想到的:

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

我将在这里针对 Android 用户添加一条建议。这样做可以避免获得任何外部库。此外,在上面的一些答案中建议的所有搜索/替换字符解决方案都是危险的,应该避免。

试试这个:

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 字符串并使其工作,而不需要自己对它有任何特殊了解。

我试过用

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

我希望这就是你要找的东西?

即使这是一个已经被接受的答案的老帖子,我发布了我的替代答案,因为它对于当前的问题很有效,而且似乎没有人提到这个方法。

使用 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。

我最终使用了 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