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

Servlet技术疑问:获取请求参数后能否设置字符编码?

这个问题我太熟了!核心原因是你在设置字符编码之前就已经获取了请求参数——Servlet容器有个关键规则:一旦调用了getParameter()、getParameterMap()这类参数获取方法,容器就会立即用默认编码(通常是ISO-8859-1)解析请求参数,之后再调用setCharacterEncoding()根本不会生效。

看你的代码片段,doFilter里先调用了getParams(request),这个方法里肯定是执行了参数获取操作对吧?这直接导致后续的编码设置完全无效。

修复方案:调整执行顺序+正确处理请求包装

1. 把编码设置放在最前面

必须在所有参数读取操作之前设置字符编码,这是最核心的修复点:

public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {
    HttpServletRequest httpRequest = (HttpServletRequest) request;
    
    // 第一步:先设置编码,一定要在获取参数之前!
    httpRequest.setCharacterEncoding("UTF-8");
    
    // 第二步:再执行你的参数检查/特殊字符移除逻辑
    getParams(httpRequest);
    
    // 第三步:传递经过处理的请求(如果用Wrapper,基于已设置编码的request初始化)
    chain.doFilter(new RequestWrapper(httpRequest), response);
}

2. 确保RequestWrapper正确处理编码(如果需要自定义参数逻辑)

如果你的RequestWrapper是用来修改参数值(比如移除特殊字符),要基于已经设置好编码的原始请求来读取参数,避免二次解析时编码混乱:

public class RequestWrapper extends HttpServletRequestWrapper {
    private Map<String, String[]> sanitizedParams;

    public RequestWrapper(HttpServletRequest request) {
        super(request);
        // 基于已设置UTF-8编码的request读取原始参数
        sanitizedParams = new HashMap<>(request.getParameterMap());
        // 在这里执行特殊字符移除逻辑
        removeSpecialCharacters(sanitizedParams);
    }

    private void removeSpecialCharacters(Map<String, String[]> params) {
        for (Map.Entry<String, String[]> entry : params.entrySet()) {
            String[] values = entry.getValue();
            for (int i = 0; i < values.length; i++) {
                // 示例:移除HTML危险字符,你可以替换成自己的规则
                values[i] = values[i].replaceAll("[<>&\"']", "");
            }
        }
    }

    // 重写参数获取方法,返回处理后的参数
    @Override
    public String getParameter(String name) {
        String[] values = sanitizedParams.get(name);
        return values != null && values.length > 0 ? values[0] : null;
    }

    @Override
    public Map<String, String[]> getParameterMap() {
        return Collections.unmodifiableMap(sanitizedParams);
    }

    @Override
    public String[] getParameterValues(String name) {
        return sanitizedParams.get(name);
    }
}

额外注意点

  • 如果是GET请求,仅设置setCharacterEncoding()可能不够,因为GET参数是通过URL传递的,Tomcat等容器默认用ISO-8859-1解析URL编码。需要在容器配置(比如Tomcat的server.xml)里的Connector标签添加URIEncoding="UTF-8":
    <Connector port="8080" protocol="HTTP/1.1"
               connectionTimeout="20000"
               redirectPort="8443"
               URIEncoding="UTF-8"/>
    
  • 永远不要在读取参数后再尝试设置编码,这个顺序错误是编码问题的高频坑点。

内容的提问来源于stack exchange,提问作者Bala

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.26 08:37:29