Java URLEncode空格轉換爲“+”號問題

問題

最近做一個URL拼接的函數,需要將用戶名拼接到url上。因爲用戶名可能會有特殊字符,所以需要進行urlencode。這裏我使用的是java的urlEncode方式。問題代碼可以提煉如下:

public static void main(String[] args) throws UnsupportedEncodingException, EncoderException, DecoderException {
	String source = "hello,  張三1+";
	String encodeStr = URLEncoder.encode(source, "UTF-8");
	String decodeStr = URLDecoder.decode(encodeStr, "UTF-8");
	System.out.println("原生編碼後:" + encodeStr);
	System.out.println("原生解碼後:" + decodeStr);
	
	String encodeStr1 = new URLCodec().encode(source);
	String decodeStr1 = new URLCodec().decode(encodeStr);
	System.out.println("Apache Common 編碼後:" + encodeStr1);
	System.out.println("Apache Common 解碼後:" + decodeStr1);
}

運行後結果如下:

原生編碼後:hello%2C++%E5%BC%A0%E4%B8%891%2B
原生解碼後:hello,  張三1+
Apache Common 編碼後:hello%2C++%E5%BC%A0%E4%B8%891%2B
Apache Common 解碼後:hello,  張三1+

從結果裏可以看到,經過encode之後,空格被轉換成了“+”號
這裏我試了兩種方式,一種是java原生的URLEncoder(java.net.URLDecoder),另一種是apache common下的URLCodec類,但是均轉換成+號。我將這樣的結果給前端,前端說轉換有誤。空格應該轉換爲“%20

原因

這個問題我沒有注意過,特意網上百度了一下,總結如下:
首先,這個解析方式並沒有錯。只是標準不同而已,這裏設計到三個標準:RFC1738、RFC2396、HTML4.01
從源碼java.net.URLDecoder#encode方法上的註釋可以看到,該方法轉換規則爲application/x-www-form-urlencoded,對應的網址爲 https://www.w3.org/TR/html40/appendix/notes.html#non-ascii-chars,我們可以從https://www.w3.org/TR/REC-html40/interact/forms.html#h-17.13.4 章節中看到,這裏特殊指定了

Space characters are replaced by `+’
URLEncode

Java官方的URLEncoder.encode 實際上是爲了post請求的content-type爲x-www-form-urlencoded來設計的。

所以對於get和post兩種請求:

  • 如果是get提交 或者是路徑的話 如: http://www.bai du.com?wo=he he&ni=abc 就應該遵循RFC1738、RFC2396;空格轉換爲 %20

  • 如果是post提交:參數的值如果有空格應該編碼成+號(注意不是%20)

結尾

因爲我這次要拼接的卻是是get請求,所以我按照網上大多數說法,在encode之後再特殊處理一下空格

 encodeStr = URLEncoder.encode(content, "UTF-8");
 encodeStr = encodeStr.replaceAll("\\+", "%20");
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章