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 }
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· AI与.NET技术实操系列:基于图像分类模型对图像进行分类
· go语言实现终端里的倒计时
· 如何编写易于单元测试的代码
· 10年+ .NET Coder 心语,封装的思维:从隐藏、稳定开始理解其本质意义
· .NET Core 中如何实现缓存的预热?
· 25岁的心里话
· 闲置电脑爆改个人服务器(超详细) #公网映射 #Vmware虚拟网络编辑器
· 基于 Docker 搭建 FRP 内网穿透开源项目(很简单哒)
· 零经验选手,Compose 一天开发一款小游戏!
· 一起来玩mcp_server_sqlite,让AI帮你做增删改查!!