(6)SpringMVC中使用CharacterEncodingFilter编码过滤器处理请求和响应的乱码问题

处理SpringMVC中乱码问题

处理原生Servlet中请求和响应的乱码问题,参考文章

Servlet中的过滤器的实现及其原理,参考文章

配置CharacterEncodingFilter

在Servlet规范中要求request和response对象设置编码之前不能有获取请求参数和响应数据的操作,否则后续设置的编码都将不起作用

  • 但是DispatcherServlet给控制器方法注入request时一定是已经获取了所有的请求参数,否则我们不能直接在控制器方法上声明形参获取请求参数的值

在web.xml中注册SpringMVC提供的编码过滤器CharacterEncodingFilter, 要想在DispatcherServlet获取参数前设置编码必须在其他过滤器之前配置它否则无效

  • 使用init-param初始化参数标签设置encoding属性的值指定POST请求的编码格式,如UTF-8
  • 使用init-param初始化参数标签设置forceEncoding属性的值指定响应的编码格式,true表示响应和请求的编码格式一致,fasle表示默认编码格式
xml 复制代码
<!--配置一个字符编码的Filter,一定注意字符编码filter一般都在其他Filter之前-->
<filter>
    <filter-name>CharacterEncodingFilter</filter-name>
    <filter-class>org.springframework.web.filter.CharacterEncodingFilter</filter-class>
    <!--设置encoding属性的值解决POST请求乱码-->
    <init-param>
        <param-name>encoding</param-name>
        <param-value>UTF-8</param-value>
    </init-param>
    <init-param>
        <!--设置forceEncoding属性的值解决响应乱码-->
        <param-name>forceEncoding</param-name>	
        <param-value>true</param-value>
    </init-param>
</filter>
<filter-mapping>
    <filter-name>CharacterEncodingFilter</filter-name>
    <url-pattern>/*</url-pattern>
</filter-mapping>

CharacterEncodingFilter继承的OncePerRuquestFilter重写了doFilter(request,response,filter)并调用doFilterInternal(request,response,filter)方法执行过滤

java 复制代码
// CharacterEncodingFilter的构造方法
public CharacterEncodingFilter(String encoding, boolean forceEncoding) {
    // encoding属性的值是我们在配置文件中设置的编码格式
    // forceEncoding属性的值就是我们在配置文件中设置的布尔值true
    this(encoding,forceEncoding,forceEncoding);
}

public CharacterEncodingFilter(string encoding, boolean forceRequestEncoding, boolean forceResponseEncoding){
    Assert.hasLength(encoding,"Encoding must not be empty");
    this.encoding = encoding;
    this.forceRequestEncoding = forceRequestEncoding;
    this.forceResponseEncoding = forceResponseEncoding;
}

// OncePerRuquestFilter重写了doFilter(request,response,filter)
@override
public final void doFilter(ServletRequest request, ServletResponse response, FilterChain filterChain)
    throws servletException, IOException {
    //.............
    // 满足条件放行
    filterChain.doFilter(request,response);

    // 不满足条件执行过滤规则
    doFilterInternal(httprequest,httpresponse,filterChain);
}

// CharacterEncodingFilter重写的doFilterInternal方法
protected void doFilterInternal(HttpservletRequest request, 
                                HttpservletResponse response, FilterChain filtel)throws ServletException,IOException {
    string encoding = getEncoding(); 
    // 判断我们在是否在web.xml文件中设置了编码格式
    if (encoding != null) {
        // 如果设置了编码格式,并且forceRequestEncoding的属性值为true或request对象之前没有设置过编码(确实没有设置过),此时就可以设置请求的编码
        if (isForceRequestEncoding() || request.getcharacterEncoding() == null){
            // 设置请求的编码
            request.setCharacterEncoding(encoding);
        }
        // 如果设置了编码格式,并且forceResponseEncoding属性值为true,此时就可以设置响应的编码
        if (isForceResponseEncoding()){
            response.setcharacterEncoding(encoding);
        }

    }
    // 放行
    filterchain.dofilter(reauest. response);
}
相关推荐
_Evan_Yao5 小时前
Redis 缓存穿透、击穿、雪崩,一次讲清!
java·spring·mybatis
梓豪csd5 小时前
消息订阅中心:谁该收到哪条通知
java·开发语言·人工智能·低代码·自动化·1024程序员节
秋饼5 小时前
Spring AI 2.1 Message Parts 深度实战:推理签名回放与跨轮记忆持久化的源码级落地
java·ai·技术分享·后端开发
thefool1122666 小时前
TCP 1
java·1024程序员节
金銀銅鐵9 小时前
[Java] 用 GUI 展示 EnumSet 增减元素时的内部变化(下)
java·后端·ai编程
AI人工智能+电脑小能手9 小时前
一次请求打几个下游,这个Java并行任务工具类6个方法按序聚合
java·线程池·并发编程·1024程序员节·批量处理·并行任务
paopaokaka_luck11 小时前
心理咨询管理系统(WebSocket实时沟通、基于用户的协同过滤、 ECharts多维分析、 预约业务流程、预约校验与定时处理)
java·vue.js·spring boot·mysql·spring·echarts·1024程序员节
2301_322414280411 小时前
springboot农产品交易平台的设计与实现08055-计算机毕设 原创(免费领源码+部署教程+开发环境)
java·spring boot·redis·mysql·tomcat·maven·mybatis
考虑考虑12 小时前
JDK26的JEP 500属性
java·后端·java ee
LMT流氓兔12 小时前
第五单元——第十二课:把脚本整理成项目
java·数据库·python·langchain·1024程序员节