URL傳遞中文參數,大坑一枚,Windows與Linux效果竟然不一致(兩種解決方案),大坑linux
下午,計劃2個小時搞定,個人官網第6次升級,就可以幹點輕鬆的事了,結果,下午多搞了2個小時,晚上又搞了2個小時,才搞定。
最後一個世界難題是,URL傳遞中文參數。
問題大致是這麼出現的:我為“部落格雷觀” 這個欄目,增加了“全文檢索搜尋”功能,用lucene實現的。因此,需要傳遞中文參數。
搜尋方塊表單提交,傳遞中文,很簡單就搞定了。
搜尋之後的分頁url,需要帶上當前的“搜尋字詞” ,比如“程式員”,我在本地很輕鬆就搞定了。無非就是這樣:
search/search.html?keyword=${keyword}" keyword就是中文詞彙,比如“程式員”。
我本以為,扔到伺服器上,重啟一次,就萬事大吉了,結果點擊第2頁的時候,沒有搜尋到任何文章。
查看日誌,發現搜尋字詞是“亂碼” 。
我第一反應是,傳遞的中文“程式員” 沒有正確地進行url編碼,所以:
<#setting url_escaping_charset='utf-8'>
<#assign url="${base}/search/search.html?keyword=${keyword?url}"/>
把搜尋字詞編碼之後,再附帶在Url之後,但是:
Windows本地環境,ok,worked。但是,線上Linux環境,仍然不行。
圍繞著是否正確了編碼,在QQ、Chrome、IE上反覆嘗試了N次。結果,無論是否進行url編碼,本地Windows的所有瀏覽器都能夠正常地傳遞中文參數,線上Linux都失敗。
既然不是URL編碼的問題,我覺得應該是中文編碼的問題。(在初學JavaWeb開發的第1年,遇到了各種各樣的編碼問題,所以現在很有經驗了。)
String a = "ç¨åºå";
byte[] b = a.getBytes("iso8859-1");
System.out.println(new String(b, "utf-8"));
最終列印出來的是“程式員” ,這充分說明,linux線上環境是由於“中文編碼解碼不一致”導致的“亂碼問題”。
@RequestMapping("search")
public String search( String keyword)。
最開始,我仍然搞錯了一點,以為keyword還是url編碼,還需要一次解碼。
後來發現,SpringMVC接收參數的時候,會自動進行url解碼,這個時候的keyword已經是“字元” 了。
我的解決方案:
log.info("searchKey=" + keyword);
searchService.search(luceneIndexDir, keyword, pageVo);
//可能是參數亂碼導致的
if (pageVo.getTotalCount() <= 0) {
//瀏覽器發送的中文參數雖然是url編碼的,但是spring也會自動解碼,之所以亂碼,應該是url編碼和url解碼的“字元集編碼”不同導致的。
//如果遇到這種情況,線上linux遇到了,再把iso5559-1的字串轉換為utf-8的
log.info("search url iso8859-1,when in is:"+keyword);
byte[] b =keyword.getBytes("iso8859-1");
keyword=new String(b, "utf-8");
searchService.search(luceneIndexDir, keyword, pageVo);
log.info("search url iso8859-1,when out is:"+keyword);
}
如果第一次,沒有查詢到任何結果,很有可能就是“中文亂碼”,再轉換成正確的字元,再查詢一次。
我的這種方法,真心不是最好的。但是,我暫時沒能嘗試出萬能的一次性解法,Windows上正常,Linux不正常,很難搞。
只能,通過2次查詢來確保,不是由於亂碼,查詢不到內容。
-----------------------------
上面是,14日寫的。
今天補充一個“最佳解決方案”:
伺服器上修改Tomcat的URIEncoding為UTF-8
對於URL傳遞中文參數亂碼這個問題,其處理方法比較特殊,僅僅轉換這個中文字串或者設定JSP頁面顯示編碼都是不能解決問題的,需要修改Tomcat伺服器的設定檔才能解決問題。在這裡修改Tomcat的conf目錄下的server.xml設定檔,具體改後的代碼如下
server.xml
<Connector port="8080" protocol="HTTP/1.1" URIEncoding="UTF-8"
connectionTimeout="20000"
redirectPort="8443" />
在原來代碼中添加URI編碼設定URIEncoding=“UTF-8”即可,重啟Tomcat伺服器可以得到正確的頁面。其原理也和上面的情況類似,就是向程式指明編碼類別型,然後顯示就正常了。
看這篇文章的時候,想到應該是這個問題。
http://blog.csdn.net/beijiguangyong/article/details/7414247
我一般不喜歡修改Tomcat的配置,喜歡用“預設”的。