Tomcat日志中文乱码是一个常见问题,通常是由字符编码不一致引起的。以下是常见原因和解决方案:
一、常见乱码场景
1. 控制台输出乱码
- 启动时
catalina.out或控制台中文显示为???或乱码字符
- 访问日志
localhost_access_log中的中文参数乱码
2. 日志文件乱码
- Log4j/Logback等日志框架输出的中文乱码
- 应用自身使用
System.out.println()输出的中文乱码
二、主要原因分析
Tomcat启动脚本编码问题(Windows常见)
JVM默认编码与系统不一致
日志文件保存编码格式不匹配
终端/控制台编码设置问题
三、解决方案
方案1:修改Tomcat启动脚本(推荐)
Linux/Unix系统 (catalina.sh):
# 在文件开头添加或修改
JAVA_OPTS="$JAVA_OPTS -Dfile.encoding=UTF-8"
# 或
export JAVA_OPTS="$JAVA_OPTS -Dfile.encoding=UTF-8"
Windows系统 (catalina.bat):
# 在setlocal后添加
set "JAVA_OPTS=%JAVA_OPTS% -Dfile.encoding=UTF-8"
方案2:修改JVM参数
在setenv.sh或setenv.bat中添加:
export JAVA_OPTS="$JAVA_OPTS -Dfile.encoding=UTF-8 -Dsun.jnu.encoding=UTF-8"
方案3:修改server.xml中的访问日志编码
<Valve className="org.apache.catalina.valves.AccessLogValve"
directory="logs"
prefix="localhost_access_log"
suffix=".txt"
pattern="%h %l %u %t "%r" %s %b"
fileEncoding="UTF-8" /> <!-- 添加这一行 -->
方案4:修改logging.properties(Tomcat 8+)
在conf/logging.properties中:
java.util.logging.ConsoleHandler.encoding = UTF-8
java.util.logging.FileHandler.encoding = UTF-8
方案5:Linux系统环境变量设置
在~/.bashrc或/etc/profile中添加:
export LANG="en_US.UTF-8"
export LC_ALL="en_US.UTF-8"
方案6:应用级别设置
在Spring Boot项目中,application.properties:
server.tomcat.uri-encoding=UTF-8
server.servlet.encoding.charset=UTF-8
server.servlet.encoding.force=true
四、针对不同操作系统的额外配置
Windows系统:
# 修改注册表或使用chcp命令
chcp 65001 # 设置控制台为UTF-8
# 或修改注册表:
# HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Command Processor\AutoRun
# 值为 "chcp 65001 > nul"
Docker容器:
ENV LANG C.UTF-8
ENV LC_ALL C.UTF-8
五、排查步骤
检查当前编码:
System.out.println("file.encoding=" + System.getProperty("file.encoding"));
System.out.println("Default Charset=" + Charset.defaultCharset());
检查日志配置:
- 确认日志框架(Log4j2/Logback)编码设置
- 检查日志文件实际编码格式(使用
file -i或Notepad++查看)
统一编码策略:
- JVM参数:
-Dfile.encoding=UTF-8
- 数据库连接:
characterEncoding=utf8
- HTTP请求/响应:设置UTF-8
六、最佳实践建议
统一使用UTF-8编码
在Tomcat启动脚本中统一设置JVM参数
避免混合使用不同编码
开发和生产环境保持编码一致性
使用日志框架替代System.out
七、快速测试
创建测试JSP文件test-encoding.jsp:
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<%@ page import="java.nio.charset.Charset" %>
<%
out.println("JVM file.encoding: " + System.getProperty("file.encoding") + "<br>");
out.println("Default Charset: " + Charset.defaultCharset() + "<br>");
out.println("中文测试");
%>
访问该页面,确认中文显示正常。