Java Servlet中URLDecoder解码含%的密码参数失败如何解决
问题根因
你遇到的解码错误是重复解码导致的:
- Servlet容器(Tomcat/Jetty等)在调用
request.getParameter()之前,已经自动完成了请求参数的URL解码操作,返回的结果本身就是原始明文,不需要你再调用URLDecoder.decode二次处理。 - 你二次解码时,遇到容器解码后保留的
%字符,后面如果没有跟着2位合法十六进制字符,就会触发解码失败。
解决方案
方案1:直接使用request.getParameter返回值(推荐,符合规范)
直接删掉多余的URLDecoder调用即可,修改后的代码如下:
Map<String, String[]> paramMap = request.getParameterMap(); Set<String> keySet = paramMap.keySet(); Iterator<String> iterator = keySet.iterator(); while (iterator.hasNext()) { String key = iterator.next(); if (!key.equals("_")) { // 直接使用返回值,不需要二次解码 String value = request.getParameter(key); System.out.println("Getting parameter("+ key +" = '" + value +"')"); } }
注意:需要确保Servlet容器的URI编码配置为UTF-8,比如Tomcat的server.xml中Connector节点配置URIEncoding="UTF-8",避免容器默认用ISO-8859-1解码导致乱码。
方案2:手动解析QueryString(兼容客户端未规范编码的场景)
如果是客户端提交参数时没有对原始%做URL编码(即没有把%转成%25),不符合URL规范导致容器解析参数出错,可以手动拆分query string获取参数:
// 只适用于GET请求,POST请求需要自行读取请求体拆分 String queryString = request.getQueryString(); Map<String, String> params = new HashMap<>(); if (queryString != null) { String[] pairs = queryString.split("&"); for (String pair : pairs) { int idx = pair.indexOf("="); if (idx > 0) { String key = URLDecoder.decode(pair.substring(0, idx), "UTF-8"); String value = URLDecoder.decode(pair.substring(idx + 1), "UTF-8"); params.put(key, value); } } } // 从params中取对应参数即可 String password = params.get("password");
内容的提问来源于stack exchange,提问作者Rose
相关产品推荐
相关产品推荐

