url 傳遞中文參數亂碼問題的終極解決方法。

估計不少人在作web開發的時候,都會碰到過url傳遞中文參數,有時候會出現亂碼的問題,但有些項目或者環境,又不會有問題。當遇到亂碼的時候,上網找了不少解決方案,好比:html

  1. 頁面設置它的編碼方式,改爲utf-8 或者gb2312。
  2. encodeURI(url),也有人說要2個encodeURI,如:window.location.href = encodeURI('b.html?cId='+id+"&cName="+encodeURIComponent(name));
    而後後臺String str = java.net.URLDecoder.decode(str, "UTF-8");這樣進行轉碼等。java

解決方法就不一一列舉了,你們可自行百度搜索,我也搞不清楚究竟怎麼能保證百分百解決問題。web

項目中碰到的狀況是,開發環境通過上述的2種方法,折騰過,確實能定位某個編碼轉換是正常的。ajax

但部署到測試環境調試輸出後發現,不管是gbk,utf8,iso等等編碼測試,都沒法正常還原中文字符串。json

因而想到了另一種方法,就是把中文轉換爲數字或者是英文字母以及標點符號等組成的字符串傳遞到後臺,app

所以有想法是把字符串加密爲base64的方式傳過去後,再後臺再進行解密。上網找了下,沒找到現成的有效方法,因而放棄了。jsp

再後來,想着不須要加密了,直接把字符串轉換成16進制傳遞到後臺,再把它轉回來吧,因而,這個終極的解決方案就出來了。函數

首先是jsp頁面中增長腳本,把字符串轉換成16進制字符串,字符之間用,號隔開,不隔開,沒法區分出哪一個是半角哪一個是全角(若是不用,號隔開的,麻煩請提供個好的解決方法,謝謝)oop

function stringToHex(str){
var val="";
for(var i = 0; i < str.length; i++){
if(val == "")
val = str.charCodeAt(i).toString(16);
else
val += "," + str.charCodeAt(i).toString(16);
}
return val;
}

頁面上把字符串通過該函數轉換後,傳遞到後臺,如:測試

var code_value=stringToHex(PrjName);
var url= "/assets/fmProjectInfo.do?method=synCheckProjectName&prjName="+code_value+"&typeId=<bean:write name="fmProjectInfoForm" property="bo.ftId"/>"

 後臺的轉換代碼爲:

       public static String decode(String unicodeStr) {  
        if (unicodeStr == null) {  
            return null;  
        }  
        StringBuffer retBuf = new StringBuffer();  
        int maxLoop = unicodeStr.length();  
        for (int i = 0; i < maxLoop; i++) {  
            if (unicodeStr.charAt(i) == '\\') {  
                if ((i < maxLoop - 5)  
                        && ((unicodeStr.charAt(i + 1) == 'u') || (unicodeStr  
                                .charAt(i + 1) == 'U')))  
                    try {  
                        retBuf.append((char) Integer.parseInt(  
                                unicodeStr.substring(i + 2, i + 6), 16));  
                        i += 5;  
                    } catch (NumberFormatException localNumberFormatException) {  
                        retBuf.append(unicodeStr.charAt(i));  
                    }  
                else  
                    retBuf.append(unicodeStr.charAt(i));  
            } else {  
                retBuf.append(unicodeStr.charAt(i));  
            }  
        }  
        return retBuf.toString();  
    }  
       //把jsp頁面傳遞進來的,用,號隔開的16進制字符串轉換成 相似:select \u7528\u6237\u540d from \u7528\u6237 的字符串,在調用decode方法把中文轉換出來。
       public static String jspStrInit(String sourceStr)
       {
        String[] sourceStrArray = sourceStr.split(",");
        StringBuffer sb=new StringBuffer();
        for (int i = 0; i < sourceStrArray.length; i++) {
            if (sourceStrArray[i].length()<=2)
            	sb.append(hexStr2Str(sourceStrArray[i].toUpperCase()));
            else
            	sb.append("\\u"+sourceStrArray[i]);
        }
       		return sb.toString();
       }
       
       public static String jspDecode(String unicodeStr) {
       		String mStr=jspStrInit(unicodeStr);
       		return decode(mStr);
       }

       /** 
        * 十六進制轉換字符串
        * @param String str Byte字符串(Byte之間無分隔符 如:[616C6B])
        * @return String 對應的字符串
        */   
       public static String hexStr2Str(String hexStr) 
       {   
           String str = "0123456789ABCDEF";   
           char[] hexs = hexStr.toCharArray();   
           byte[] bytes = new byte[hexStr.length() / 2];   
           int n;   
    
           for (int i = 0; i < bytes.length; i++) 
           {   
               n = str.indexOf(hexs[2 * i]) * 16;   
               n += str.indexOf(hexs[2 * i + 1]);   
               bytes[i] = (byte) (n & 0xff);   
           }   
           return new String(bytes);   
       } 
public static void main(String[] args) throws Exception { String bb="5e02,91cd,70b9,5de5,4f5c,6d4b,8bd5"; String cc=jspDecode(bb); System.out.println(cc); }

jspDecode這個方法就是把jsp頁面傳遞過來的字符串進行還原的。該終極解決方法就此結束。 最後,在另一個項目中有客戶的研發保障,說修改意見那裏有時候保存不成功,有時候又沒問題,通過分析,修改意見那裏是使用ajax封裝了json的數據傳遞到後臺進行更新的。 因爲意見裏面包含了回車,標點符號等特殊符號,違反了json的原則致使的,我給他提供的解決方案,也是採用了該方案,讓他把該意見轉換爲16進制字符串以後,傳遞到後臺再轉換回來去解決。 目前還沒獲得問題的解決答覆,但按理,應該也能夠用在該場景裏面。 原創做品出自努力偷懶,轉載請說明文章出處:http://blog.csdn.net/kfarvid或 http://www.cnblogs.com/kfarvid/

相關文章
相關標籤/搜索