Java – 将String转换为有效的URI对象
我想从一个String
获取一个java.net.URI
对象。 该string有一些字符,需要用它们的百分比转义序列来replace。 但是当我使用URLEncoder编码UTF-8编码的string时,即使是/他们被replace为它们的转义序列。
我怎样才能从一个string对象获得一个有效的编码的URL?
http://www.google.com?q=a b提供http%3A%2F%2www.google.com …而我希望输出为http://www.google.com?q=a% 20B
有人可以告诉我如何做到这一点。
我正在尝试在Android应用程序中执行此操作。 所以我可以访问数量有限的图书馆。
您可以尝试: Apache commons-httpclient项目中的org.apache.commons.httpclient.util.URIUtil.encodeQuery
像这样(请参阅URIUtil ):
URIUtil.encodeQuery("http://www.google.com?q=ab")
会变成:
http://www.google.com?q=a%20b
你当然可以自己动手做,但是URIparsing会变得非常混乱
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"));
我要在这里添加一个针对Android用户的build议。 你可以做到这一点,避免得到任何外部库。 此外,上述某些答案中提出的所有search/replace字符解决scheme都是危险的,应该避免。
试试这个:
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类中的一些function。 首先,URL类可以将URL分解成适当的组件,因此不需要任何stringsearch/replace工作。 其次,当你通过组件构造一个URI而不是从一个单独的string时,这种方法利用了正确转义组件的URI类function。
这种方法的优点是,你可以采取任何有效的urlstring,并使其工作,而不需要你自己的任何特殊的知识。
即使这是一个已经接受了答案的旧post,我张贴了我的备选答案,因为它适用于目前的问题,似乎没有人提到这种方法。
使用java.net.URI库:
URI uri = URI.create(URLString);
如果你想要一个URL格式的string对应它:
String validURLString = uri.toASCIIString();
与许多其他方法(例如java.net.URLEncoder)不同,它只replace不安全的ASCII字符(如ç
, é
…)。
在上面的例子中,如果URLString
是以下String
:
"http://www.domain.com/façon+word"
得到的validURLString
将是:
"http://www.domain.com/fa%C3%A7on+word"
这是一个格式良好的url。
如果你不喜欢图书馆,这个怎么样?
请注意,你不应该在整个URL上使用这个函数,而应该在组件上使用这个函数,例如,当你build立URL的时候,只需要使用“ab”组件,否则计算机将不知道应该是什么字符具有特殊意义,哪些应该具有字面意思。
/** 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; }
您可以使用URI
类的多参数构造函数。 从URI
javadoc:
多参数构造函数根据它们出现的组件的要求引用非法字符。 百分号字符('%')总是由这些构造函数引用。 任何其他字符都被保留。
所以,如果你使用
URI uri = new URI("http", "www.google.com?q=ab");
那么你得到http:www.google.com?q=a%20b
这是不正确的,但是它更接近一点。
如果你知道你的string没有URL片段(例如http://example.com/page#anchor ),那么你可以使用下面的代码来得到你想要的:
String s = "http://www.google.com?q=ab"; String[] parts = s.split(":",2); URI uri = new URI(parts[0], parts[1], null);
为了安全起见,你应该扫描string#
字符,但这应该让你开始。
我有一个类似的问题,我的一个项目从string创build一个URI对象。 我也找不到任何干净的解决scheme。 以下是我想到的:
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);
那么我尝试使用
String converted = URLDecoder.decode("toconvert","UTF-8");
我希望这是你真正想要的?
java.net的博客有一个类,可能已经做了你想要的东西(但现在是不行了,所以我不能检查)。
这里的代码可能会被修改成你想要的:
这是我从java.net的想法: https : //urlencodedquerystring.dev.java.net/
或者你可以使用这个类:
http://developer.android.com/reference/java/net/URLEncoder.html
从API级别1开始,这是Android中的一个。
然而令人讨厌的是,它专门处理空间(用+代替%20)。 为了解决这个问题,我们简单地使用这个片段
URLEncoder.encode(value, "UTF-8").replace("+", "%20");
我结束了使用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