08-SpringMVC过滤器

1. 什么是字符编码过滤器?一个生动的比喻 🗣️

想象一下两个说不同语言的人要交流:

  • 中国人说:"你好"(中文)
  • 美国人听到的是乱码,因为他不理解中文
  • 这时候需要一个翻译官,把中文翻译成英文"Hello"

CharacterEncodingFilter就是这个"翻译官",它确保浏览器和服务器使用同一种"语言"(字符编码)进行交流。

2. 为什么需要这个过滤器? 🤔

没有字符编码过滤器时,你可能会遇到:

  • 中文变成乱码:你好���%E4%BD%A0%E5%A5%BD
  • 表单提交的数据显示异常
  • 页面显示问号或奇怪的符号

根本原因: 浏览器和服务器使用了不同的字符编码规则。

3. CharacterEncodingFilter的工作原理 🔍

看看你提供的配置:

<filter>
    <filter-name>oneFilter</filter-name>
    <filter-class>org.springframework.web.filter.CharacterEncodingFilter</filter-class>
    <init-param>
        <param-name>encoding</param-name>
        <param-value>utf-8</param-value> <!-- 指定使用UTF-8编码 -->
    </init-param>
</filter>
<filter-mapping>
    <filter-name>oneFilter</filter-name>
    <url-pattern>*.do</url-pattern> <!-- 只拦截以.do结尾的请求 -->
</filter-mapping>

这个过滤器做了两件事:

  1. 对进来的请求:告诉服务器"请用UTF-8来解读这些数据"
  2. 对出去的响应:告诉浏览器"请用UTF-8来显示这些内容"

4. 如何配置字符编码过滤器? 🛠️

完整配置示例(推荐):

<filter>
    <filter-name>encodingFilter</filter-name>
    <filter-class>org.springframework.web.filter.CharacterEncodingFilter</filter-class>
    <init-param>
        <param-name>encoding</param-name>
        <param-value>UTF-8</param-value> <!-- 设置编码为UTF-8 -->
    </init-param>
    <init-param>
        <param-name>forceEncoding</param-name>
        <param-value>true</param-value> <!-- 强制使用UTF-8,覆盖任何现有设置 -->
    </init-param>
</filter>

<filter-mapping>
    <filter-name>encodingFilter</filter-name>
    <url-pattern>/*</url-pattern> <!-- 拦截所有请求 -->
</filter-mapping>

配置说明:

参数名 说明 推荐值
encoding 使用的字符编码 UTF-8
forceEncoding 是否强制使用指定编码 true
url-pattern 拦截的请求模式 /*(所有请求)

5. 实际应用场景 🎯

场景1:处理表单提交的中文

没有过滤器时:

@PostMapping("/submit")
public String submitForm(String name) {
    // 如果name是中文,可能会显示乱码
    System.out.println("收到名字: " + name); // 可能输出: 收到名字: ???
    return "result";
}

有过滤器后:

@PostMapping("/submit")
public String submitForm(String name) {
    // 中文能正确显示
    System.out.println("收到名字: " + name); // 正确输出: 收到名字: 张三
    return "result";
}

场景2:返回中文内容到页面

没有过滤器时:

@GetMapping("/message")
@ResponseBody
public String getMessage() {
    return "你好世界"; // 浏览器可能显示乱码
}

有过滤器后:

@GetMapping("/message")
@ResponseBody
public String getMessage() {
    return "你好世界"; // 浏览器正确显示中文
}

6. 重要注意事项 ⚠️

1. GET请求和POST请求的区别

POST请求:

  • 参数在请求体中
  • CharacterEncodingFilter 能完美处理
  • 设置一次就搞定

GET请求:

  • 参数在URL中(如:?name=张三&age=20
  • 需要额外配置Tomcat服务器

解决GET请求乱码:
在Tomcat的conf/server.xml中配置:

<Connector port="8080" protocol="HTTP/1.1"
           connectionTimeout="20000"
           redirectPort="8443"
           URIEncoding="UTF-8" /> <!-- 添加这一行 -->

注意: Tomcat 8.0及以上版本默认就是UTF-8,不需要额外配置。

2. 过滤器的位置很重要

一定要把字符编码过滤器放在所有过滤器的最前面:

<!-- 字符编码过滤器应该是最先执行的 -->
<filter>
    <filter-name>encodingFilter</filter-name>
    <filter-class>org.springframework.web.filter.CharacterEncodingFilter</filter-class>
    ...
</filter>

<!-- 其他过滤器放在后面 -->
<filter>
    <filter-name>otherFilter</filter-name>
    <filter-class>...</filter-class>
</filter>

3. 拦截范围建议

推荐使用:

<url-pattern>/*</url-pattern> <!-- 拦截所有请求 -->

而不是:

<url-pattern>*.do</url-pattern> <!-- 只拦截.do请求 -->

因为:

  • 静态资源(CSS、JS)也可能需要设置编码
  • RESTful API也可能返回中文内容

7. 常见问题及解决方案 ❓

问题1:配置了但还是乱码

可能原因:

  1. 过滤器不是第一个执行的
  2. 页面本身没有设置UTF-8编码

解决方案:

  1. 确保字符编码过滤器是web.xml中的第一个过滤器
  2. 在HTML/JSP页面中添加编码声明:
<meta charset="UTF-8">

问题2:GET请求仍然乱码

解决方案:

  1. 检查Tomcat版本
  2. 如果是Tomcat 7或更早版本,配置server.xml中的URIEncoding="UTF-8"
  3. 或者对参数手动解码:
String name = new String(request.getParameter("name").getBytes("ISO-8859-1"), "UTF-8");

问题3:静态资源乱码

解决方案:
确保拦截模式是/*而不是*.do

8. 总结 🎯

概念 说明 比喻
CharacterEncodingFilter 统一字符编码的过滤器 翻译官
encoding参数 指定使用的字符编码 选择翻译的语言
forceEncoding参数 强制使用指定编码 要求必须用这种语言
POST请求 过滤器能完美处理 室内谈话
GET请求 需要Tomcat服务器配置 室外喊话

字符编码过滤器的核心价值: 确保浏览器和服务器使用同一种"语言"交流,避免中文乱码问题。

最佳实践:

  1. 配置字符编码过滤器为第一个过滤器
  2. 使用UTF-8编码和forceEncoding=true
  3. 拦截所有请求(/*
  4. 根据Tomcat版本配置GET请求支持
posted on 2025-09-14 21:27  笨忠  阅读(5)  评论(0)    收藏  举报