URLDecoder異常解決方法


URLDecoder對參數進行解碼時候,代碼如:

URLDecoder.decode(param,"utf-8");

有時候會出現類似如下的錯誤:

URLDecoder異常Illegal hex characters in escape (%)

這是因為傳參有一些特殊字符,比如%號或者說+號,導致不能解析,報錯

如果收到的HTTP請求參數(URL中的GET請求)中有一個字符串,是中文,比如“10%是黃段子”,服務器段使用URLDecoder.decode就會出現此異常。URL只能使用英文字母、阿拉伯數字和某些標點符號,不能使用其他文字和符號。如果內容中存在中文,必須要進行編解碼。“10%是黃段子”轉碼過后是“10%25%E6%98%AF%E9%BB%84%E6%AE%B5%E5%AD%90%”被用來作為轉義字符使用。

上面的字符串中'%'是一個中文字符'是',而轉換的實現是將%后面的兩個字符一起轉為一個16進制數。拿"%是"來轉換數字,肯定會有NumberFormatException異常。

類似的如果請求字符串中有'+',也會有問題。因為'+'被當做空格使用了。一個解決辦法就是將%替換為%25。

解決方法是:

 1 public static String replacer(StringBuffer outBuffer) {
 2       String data = outBuffer.toString();
 3       try {
 4          data = data.replaceAll("%(?![0-9a-fA-F]{2})", "%25");
 5          data = data.replaceAll("\\+", "%2B");
 6          data = URLDecoder.decode(data, "utf-8");
 7       } catch (Exception e) {
 8          e.printStackTrace();
 9       }
10       return data;
11    }

這里使用了一個特殊正則表達式:零寬負向先行斷言(zero-widthnegative lookahead assertion),模式為(?!pattern),代表字符串中的一個位置,緊接該位置之后的字符序列不能匹配pattern。%(?![0-9a-fA-F]{2})意思是'%'開始,但是后面兩個字符不是數字,也不是字母。

或者使用POST請求,將參數參加到body中而不是請求url拼接

 

URLDecoder源碼:

 1 public static String decode(String s, String enc)
 2         throws UnsupportedEncodingException{
 3 
 4         boolean needToChange = false;
 5         int numChars = s.length();
 6         StringBuffer sb = new StringBuffer(numChars > 500 ? numChars / 2 : numChars);
 7         int i = 0;
 8 
 9         if (enc.length() == 0) {
10             throw new UnsupportedEncodingException ("URLDecoder: empty string enc parameter");
11         }
12 
13         char c;
14         byte[] bytes = null;
15         while (i < numChars) {
16             c = s.charAt(i);
17             switch (c) {
18             case '+':
19                 sb.append(' ');
20                 i++;
21                 needToChange = true;
22                 break;
23             case '%':
24                 /*
25                  * Starting with this instance of %, process all
26                  * consecutive substrings of the form %xy. Each
27                  * substring %xy will yield a byte. Convert all
28                  * consecutive  bytes obtained this way to whatever
29                  * character(s) they represent in the provided
30                  * encoding.
31                  */
32 
33                 try {
34 
35                     // (numChars-i)/3 is an upper bound for the number
36                     // of remaining bytes
37                     if (bytes == null)
38                         bytes = new byte[(numChars-i)/3];
39                     int pos = 0;
40 
41                     while ( ((i+2) < numChars) &&
42                             (c=='%')) {
43                         int v = Integer.parseInt(s.substring(i+1,i+3),16);
44                         if (v < 0)
45                             throw new IllegalArgumentException("URLDecoder: Illegal hex characters in escape (%) pattern - negative value");
46                         bytes[pos++] = (byte) v;
47                         i+= 3;
48                         if (i < numChars)
49                             c = s.charAt(i);
50                     }
51 
52                     // A trailing, incomplete byte encoding such as
53                     // "%x" will cause an exception to be thrown
54 
55                     if ((i < numChars) && (c=='%'))
56                         throw new IllegalArgumentException(
57                          "URLDecoder: Incomplete trailing escape (%) pattern");
58 
59                     sb.append(new String(bytes, 0, pos, enc));
60                 } catch (NumberFormatException e) {
61                     throw new IllegalArgumentException(
62                     "URLDecoder: Illegal hex characters in escape (%) pattern - "
63                     + e.getMessage());
64                 }
65                 needToChange = true;
66                 break;
67             default:
68                 sb.append(c);
69                 i++;
70                 break;
71             }
72         }
73 
74         return (needToChange? sb.toString() : s);
75     }

 


免責聲明!

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



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