2009-02-21 46 views
66

我試圖從String獲取java.net.URI對象。該字符串有一些字符,需要用它們的百分比轉義序列替換。但是,當我使用URLEncoder對UTF-8編碼的字符串進行編碼時,甚至將其替換爲它們的轉義序列。Java - 將字符串轉換爲有效的URI對象

如何從String對象獲取有效的編碼URL?

http://www.google.com?q=a b的http%3A%2F%2www.google.com ...,而我所要的輸出是http://www.google.com?q=a%20b

有人能告訴我如何實現這一目標。

我想在Android應用程序中執行此操作。所以我可以訪問數量有限的圖書館。

回答

55

您可以試試:org.apache.commons.httpclient.util.URIUtil.encodeQueryApache commons-httpclient項目

這樣的(見URIUtil):

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

將變爲:

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

當然你也可以自己做,但URI解析會變得相當凌亂......

+0

感謝漢斯。我正在嘗試在Android應用中執行此操作。所以我可以訪問數量有限的圖書館。你有什麼其他的建議?再次感謝 – lostInTransit 2009-02-21 20:53:05

+2

也許你可以看看URIUtil類的來源(畢竟這是開源的)。我假設可以從該類中提取必要的代碼。 – 2009-02-22 15:39:36

+6

指向項目(Apache commons-httpclient)「現在已過期」。部分代碼被[HttpComponents-httpclient]取代(http://hc.apache.org/httpcomponents-client-ga),但我無法在新的API中找到等價的方法。 – dgiugg 2014-08-06 13:24:54

4

你可以使用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); 

爲了安全起見,你要掃描的字符串#個字符,但這應該讓你開始。

9

如果你不喜歡圖書館,那麼這個怎麼樣?

請注意,您不應在整個網址上使用此功能,而應在組件上使用此功能。只是「a b」組件,就像你建立URL一樣 - 否則計算機將不知道哪些字符應該有特殊含義,哪些字符應該具有字面含義。

/** 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 " %$&+,/:;[email protected]<>#%".indexOf(ch) >= 0; 
} 
+0

這不起作用(至少在某些情況下)。例如。字符'Š'編碼爲'%M1',但應編碼爲'%C5%A0'。 – mindas 2011-05-10 10:47:50

4

我的項目中有一個類似的問題是從字符串中創建一個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); 
33

我要補充一個建議​​這裏針對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時,此方法利用了正確轉義組件的URI類功能。

這種方法的美妙之處在於,您可以使用任何有效的url字符串,並且無需任何特殊的知識即可工作。

3

嗯,我試着用

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

我希望這是你實際上是在尋找?

13

即使這是一個已經被接受的答案的舊帖子,我張貼我的備選答案,因爲它適用於當前的問題,並且似乎沒有人提到這種方法。

隨着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。

0

我結束了使用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