Android中訪問網絡時url中帶有特殊字符的問題


Component Example value Also known as
Protocol http scheme
Authority username:password@host:8080  
User Info username:password  
Host host  
Port 8080  
File /directory/file?query  
Path /directory/file  
Query query  
Ref ref fragment

一個完整的url鏈接可以表示成這樣:

http://username:password@host:8080/directory/file?query#ref: 

(IPv6的url格式就是把文本地址用符號“[”和“]”來封閉,簡單例如:http://[FEDC:BA98:7654:3210:FEDC:BA98:7654:3210]:80/index.html)

而在android里面如果使用httpGet或httpPost來訪問網絡,除了一個無參構造函數,它們還有兩個構造函數,例如

 1 public HttpGet(final URI uri) {
 2         super();
 3         setURI(uri);
 4     }
 5 
 6     /**
 7      * @throws IllegalArgumentException if the uri is invalid. 
 8      */
 9 public HttpGet(final String uri) {
10         super();
11         setURI(URI.create(uri));
12     }

注意第7行這句話,它告訴我們,如果這個字符串包含有特殊字符,我們需要對這些特殊字符進行轉化。

我們看一下URI.create(uri)這個函數:

1     public static URI create(String uri) {
2         try {
3             return new URI(uri);
4         } catch (URISyntaxException e) {
5             throw new IllegalArgumentException(e.getMessage());
6         }
7     }

android文檔中對這兩個類URL.class和URI.class描述如下:

A URL(URI) is composed of many parts. This class can both parse URL(URI) strings into parts and compose URL(URI) strings from parts. For example, consider the parts of this URL(URI)。

URL.class的構造函數:

public URL(String spec);

public URL(URL context, String spec);

public URL(URL context, String spec, URLStreamHandler handler);

public URL(String protocol, String host, String file);

public URL(String protocol, String host, int port, String file);

public URL(String protocol, String host, int port, String file,URLStreamHandler handler); 

URI.class的構造函數:

public URI(String spec)

public URI(String scheme, String schemeSpecificPart, String fragment)

public URI(String scheme, String userInfo, String host, int port, String path, String query,String fragment)

public URI(String scheme, String host, String path, String fragment)

事實上,這兩個類通過一個String構造一個uri(或url),主要是利用libcore.net.url.UrlUtils這個類來標識String中"//""?"":""&""#""@"這些特定字符然后區分一個url各個部分的。

很顯然,除了這些非字母的特殊字符,另外如空格,“+”這些特殊字符它並沒有處理。這需要我們自己對這些字符進行替換,可以使用encode函數,也可以直接replace為%(該字符的ascii碼)。

 1     private String encodeUrl(String urlStr)
 2     {
 3         url =urlStr.contains("%")?urlStr.replace("%", "%25"):urlStr;
 4         url =urlStr.contains("+")?urlStr.replace("+", "%2B"):urlStr;
 5         url =urlStr.contains(" ")?urlStr.replace(" ", "%20"):urlStr;
 6     //    url =urlStr.contains("/")?urlStr.replace("/", "%2F"):urlStr;
 7     //    url =urlStr.contains("?")?urlStr.replace("?", "%3F"):urlStr;
 8     //    url =urlStr.contains("#")?urlStr.replace("#", "%23"):urlStr;
 9     //    url =urlStr.contains("&")?urlStr.replace("&", "%26"):urlStr;
10     //    url =urlStr.contains("=")?urlStr.replace("=", "%3D"):urlStr;
11         return url;
12     }

被注釋的部分是因為這些字符我測試中一般鏈接是可以成功被處理的,但是%,+和空格是需要轉換的。

最后我選擇了這種處理方式。

新手初探,求指正。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM