catalina_opts必须设置-dfile.encoding=utf-8 -duser.language=zh -duser.country=cn,以强制jvm使用utf-8编码读取properties文件并精准匹配messages_zh_cn资源束,避免中文乱码和locale fallback;windows下须设为无引号、无换行、单行空格分隔的系统环境变量,并通过jinfo验证进程级生效。

CATALINA_OPTS 是控制 Tomcat 启动时 JVM 行为的关键环境变量,国际化(i18n)支持依赖它来设置默认语言、区域和字符编码。直接配 CATALINA_HOME 或 PATH 不起作用——那些只影响脚本可执行性,不干预 JVM 的 locale 初始化。
为什么 CATALINA_OPTS 必须设 -Dfile.encoding=UTF-8 -Duser.language=zh -Duser.country=CN
Tomcat 默认用系统 locale 启动 JVM,Windows 中文版常是 GBK 编码 + zh_CN 区域,但 JSP/Servlet 读取 .properties 文件时若没显式指定编码,会按平台默认解码,导致 messages_zh_CN.properties 里的中文乱码;同时 ResourceBundle.getBundle() 查找资源束时依赖 user.language 和 user.country,值不匹配就 fallback 到 default(通常是英文)。所以必须在 JVM 启动前固化这三要素:
-
-Dfile.encoding=UTF-8:强制所有文件 I/O 使用 UTF-8,避免读取.properties时误判编码 -
-Duser.language=zh:确保Locale.getDefault().getLanguage()返回"zh",匹配资源束命名规则 -
-Duser.country=CN:配合 language 构成完整 locale,使messages_zh_CN.properties被优先加载
CATALINA_OPTS 在 Windows 上的正确写法(无空格、无引号、单行)
很多人把 CATALINA_OPTS 设成带空格的多行字符串或加了双引号,结果 startup.bat 解析失败,JVM 完全忽略参数。正确做法是:
- 新建系统变量:
CATALINA_OPTS,变量值为:-Dfile.encoding=UTF-8 -Duser.language=zh -Duser.country=CN - 值中不能有换行、制表符,开头结尾不能有空格
- 不要加引号(
"-Dfile.encoding=UTF-8"是错的) - 如果已有其他 JVM 参数(如内存配置),用空格拼接:
-Xms512m -Xmx1024m -Dfile.encoding=UTF-8 -Duser.language=zh -Duser.country=CN
验证是否生效:用 jps -l 和 jinfo 检查实际启动参数
仅看环境变量是否设置成功没用,得确认这些参数真传给了 Tomcat 进程。启动后执行:
- 打开新命令行,运行
jps -l找到 Tomcat 对应的 PID(通常类名含Bootstrap) - 运行
jinfo -flags <pid></pid>,输出里必须出现-Dfile.encoding=UTF-8等项 - 再运行
jinfo -sysprops <pid> | findstr "user.language user.country file.encoding"</pid>,确认三项值准确无误 - 若没看到,说明
CATALINA_OPTS没被读取——常见原因是变量设在用户环境而非系统环境,或 startup.bat 被双击运行(绕过环境变量加载)
Web 应用内仍乱码?检查 web.xml 和 JSP pageEncoding
CATALINA_OPTS 解决的是 JVM 层和 ResourceBundle 层,但 HTTP 响应编码、表单提交解析、JSP 编译仍需显式声明:
- 在
web.xml中添加过滤器强制请求/响应编码:CharacterEncodingFilter,encoding设为UTF-8 - JSP 顶部必须写:
- HTML meta 里加:
<meta charset="UTF-8"> - Spring Boot 用户注意:
server.servlet.encoding.charset=UTF-8和spring.http.encoding.force=true仍需配置,CATALINA_OPTS不覆盖框架级编码逻辑
CATALINA_OPTS 设置正确,只要 Tomcat 是通过双击 startup.bat 启动的,CMD 窗口继承的是当前用户的临时环境,而非系统级环境变量——此时必须用管理员权限打开 CMD,再手动执行 %CATALINA_HOME%\bin\startup.bat,才能确保变量生效。











