1. 引言

UTF-8 是 Web 应用中最常用的字符编码,支持包括中文、韩文、日文在内的全球所有语言。本文将系统讲解在 Tomcat 中确保 UTF-8 编码的完整配置方案。

2. 连接器配置

连接器(Connector)负责监听特定端口的连接请求。必须确保所有连接器使用 UTF-8 编码请求参数

TOMCAT_ROOT/conf/server.xml 中为所有连接器添加 URIEncoding="UTF-8" 参数:

<Connector 
  URIEncoding="UTF-8" 
  port="8080" 
  redirectPort="8443" 
  connectionTimeout="20000" 
  protocol="HTTP/1.1"/>

<Connector 
  URIEncoding="UTF-8" 
  port="8009" 
  redirectPort="8443" 
  protocol="AJP/1.3"/>

✅ 重点:

  • HTTP 和 AJP 连接器都需要配置
  • 需重启 Tomcat 生效

3. 字符集过滤器

配置连接器后,需强制 Web 应用以 UTF-8 处理所有请求和响应。创建 CharacterSetFilter 类:

public class CharacterSetFilter implements Filter {

    // ...

    public void doFilter(
      ServletRequest request, 
      ServletResponse response, 
      FilterChain next) throws IOException, ServletException {
        request.setCharacterEncoding("UTF-8");
        response.setContentType("text/html; charset=UTF-8");
        response.setCharacterEncoding("UTF-8");
        next.doFilter(request, response);
    }

    // ...
}

web.xml 中注册过滤器,使其作用于所有请求:

<filter>
    <filter-name>CharacterSetFilter</filter-name>
    <filter-class>com.baeldung.CharacterSetFilter</filter-class>
</filter>

<filter-mapping>
    <filter-name>CharacterSetFilter</filter-name>
    <url-pattern>/*</url-pattern>
</filter-mapping>

⚠️ 注意:

  • 过滤器需放在所有过滤器链的最前面
  • 响应类型可根据实际需求调整

4. 服务端页面编码

对于 JSP 页面,最佳实践是在每个页面顶部添加编码声明

<%@page pageEncoding="UTF-8" contentType="text/html; charset=UTF-8"%>

✅ 优势:

  • 明确告知 JVM 如何处理页面字符
  • 避免运行时编码转换问题

5. HTML 页面编码

服务端编码控制 JVM 处理,而 HTML 编码则指导浏览器解析。在所有 HTML 页面的 <head> 部分添加:

<meta http-equiv='Content-Type' content='text/html; charset=UTF-8' />

❌ 常见错误:

  • 仅配置服务端编码而忽略浏览器端
  • 使用过时的 <meta charset="UTF-8"> 声明(兼容性较差)

6. MySQL 服务器配置

完成 Tomcat 配置后,需同步配置数据库。以 MySQL 为例,修改配置文件(Windows 为 my.ini,Linux 为 my.cnf):

[client]
default-character-set = utf8mb4

[mysql]
default-character-set = utf8mb4

[mysqld]
character-set-client-handshake = FALSE
character-set-server = utf8mb4
collation-server = utf8mb4_unicode_ci

⚠️ 关键点:

  • 必须使用 utf8mb4(非 utf8)以支持完整 Unicode 字符
  • 修改后需重启 MySQL 服务器

7. MySQL 数据库配置

服务器配置仅对新数据库生效,存量数据库需手动迁移。执行以下 SQL:

针对每个数据库:

ALTER DATABASE database_name CHARACTER SET = utf8mb4 
    COLLATE = utf8mb4_unicode_ci;

针对每个表:

ALTER TABLE table_name CONVERT TO 
    CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;

针对 VARCHAR/TEXT 列:

ALTER TABLE table_name CHANGE column_name column_name 
    VARCHAR(69) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;

JDBC 连接需添加 UTF-8 参数:

jdbc:mysql://localhost:3306/?useUnicode=yes;characterEncoding=UTF-8

✅ 迁移检查清单:

  1. 数据库级编码
  2. 表级编码
  3. 列级编码
  4. 连接字符串参数

8. 结论

通过本文系统配置,可确保 Tomcat 全链路使用 UTF-8 编码。关键点总结:

  • 连接器强制请求编码
  • 过滤器统一处理请求/响应
  • 服务端与客户端编码双重声明
  • 数据库端到端 UTF-8 支持

完整配置能避免中文乱码、特殊字符丢失等常见问题,尤其适合国际化应用场景。


原始标题:Making Tomcat UTF-8-Ready