You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.07 00:30:01