在Tomcat运行过程中,控制台输出的中文出现乱码,常见表现为:
Tomcat涉及多个编码环节,任何一处不一致都会导致乱码:
# 在catalina.bat文件开头添加
set "JAVA_OPTS=%JAVA_OPTS% -Dfile.encoding=UTF-8 -Dsun.jnu.encoding=UTF-8"
set "JAVA_OPTS=%JAVA_OPTS% -Dconsole.encoding=UTF-8"
# 或者在setlocal后添加
set "JAVA_OPTS=%JAVA_OPTS% -Dfile.encoding=UTF-8"
Linux/Unix环境(catalina.sh)
# 在catalina.sh文件开头添加
JAVA_OPTS="$JAVA_OPTS -Dfile.encoding=UTF-8 -Dsun.jnu.encoding=UTF-8"
export JAVA_OPTS
# 或者添加到# OS specific support之前
export LC_ALL=en_US.UTF-8
export LANG=en_US.UTF-8
找到conf/logging.properties文件:
# 修改控制台处理器编码
java.util.logging.ConsoleHandler.encoding = UTF-8
# 修改文件处理器编码
java.util.logging.FileHandler.encoding = UTF-8
# 确保所有日志处理器使用UTF-8
handlers = 1catalina.org.apache.juli.AsyncFileHandler, \
2localhost.org.apache.juli.AsyncFileHandler, \
3manager.org.apache.juli.AsyncFileHandler, \
4host-manager.org.apache.juli.AsyncFileHandler, \
java.util.logging.ConsoleHandler
1catalina.org.apache.juli.AsyncFileHandler.encoding = UTF-8
2localhost.org.apache.juli.AsyncFileHandler.encoding = UTF-8
在conf/server.xml中修改Connector:
<!-- HTTP连接器 -->
<Connector port="8080" protocol="HTTP/1.1"
connectionTimeout="20000"
redirectPort="8443"
URIEncoding="UTF-8"
useBodyEncodingForURI="true" />
<!-- AJP连接器 -->
<Connector port="8009" protocol="AJP/1.3"
redirectPort="8443"
URIEncoding="UTF-8" />
创建EncodingFilter:
@WebFilter("/*")
public class EncodingFilter implements Filter {
@Override
public void doFilter(ServletRequest request, ServletResponse response,
FilterChain chain) throws IOException, ServletException {
request.setCharacterEncoding("UTF-8");
response.setCharacterEncoding("UTF-8");
response.setContentType("text/html;charset=UTF-8");
chain.doFilter(request, response);
}
}
File → Settings → Editor → File Encodings
Global Encoding: UTF-8
Project Encoding: UTF-8
Default encoding for properties files: UTF-8
Run/Debug Configuration
VM options: -Dfile.encoding=UTF-8
Help → Edit Custom VM Options
-Dfile.encoding=UTF-8
-Dconsole.encoding=UTF-8
Eclipse设置:
Window → Preferences → General → Workspace
Text file encoding: UTF-8
Run Configuration → Arguments
VM arguments: -Dfile.encoding=UTF-8
# 修改系统区域设置
控制面板 → 区域 → 管理 → 更改系统区域设置
勾选"Beta版: 使用Unicode UTF-8提供全球语言支持"
# 或者修改环境变量
set JAVA_TOOL_OPTIONS=-Dfile.encoding=UTF-8
Linux系统:
# 编辑/etc/environment
LANG=en_US.UTF-8
LC_ALL=en_US.UTF-8
# 或临时设置
export LANG=en_US.UTF-8
export LC_ALL=en_US.UTF-8
创建测试Servlet:
@WebServlet("/encodingTest")
public class EncodingTestServlet extends HttpServlet {
protected void doGet(HttpServletRequest req, HttpServletResponse resp)
throws ServletException, IOException {
resp.setContentType("text/html;charset=UTF-8");
PrintWriter out = resp.getWriter();
out.println("系统属性检查:<br>");
out.println("file.encoding: " + System.getProperty("file.encoding") + "<br>");
out.println("sun.jnu.encoding: " + System.getProperty("sun.jnu.encoding") + "<br>");
out.println("Default Charset: " + Charset.defaultCharset().name() + "<br>");
out.println("<br>请求编码检查:<br>");
out.println("Request Character Encoding: " + req.getCharacterEncoding() + "<br>");
// 测试中文输出
out.println("<br>中文测试:你好,世界!");
}
}
# 1. 检查Java默认编码
java -XshowSettings:properties -version 2>&1 | findstr "file.encoding"
# 2. 检查Tomcat启动参数
jps -v | findstr catalina
# 3. 测试控制台输出
System.out.println("中文测试:你好");
# 4. 检查日志文件编码
file -i logs/catalina.out
Windows(bin/setenv.bat):
@echo off
set "JAVA_OPTS=%JAVA_OPTS% -Dfile.encoding=UTF-8"
set "JAVA_OPTS=%JAVA_OPTS% -Dsun.jnu.encoding=UTF-8"
set "JAVA_OPTS=%JAVA_OPTS% -Duser.language=zh"
set "JAVA_OPTS=%JAVA_OPTS% -Duser.region=CN"
Linux(bin/setenv.sh):
#!/bin/sh
export JAVA_OPTS="$JAVA_OPTS -Dfile.encoding=UTF-8"
export JAVA_OPTS="$JAVA_OPTS -Dsun.jnu.encoding=UTF-8"
export JAVA_OPTS="$JAVA_OPTS -Duser.language=zh"
export JAVA_OPTS="$JAVA_OPTS -Duser.region=CN"
export LC_ALL=en_US.UTF-8
完整的server.xml配置
<?xml version="1.0" encoding="UTF-8"?>
<Server port="8005" shutdown="SHUTDOWN">
<Service name="Catalina">
<Connector port="8080" protocol="HTTP/1.1"
URIEncoding="UTF-8"
useBodyEncodingForURI="true"
compression="on"
compressionMinSize="2048"
compressableMimeType="text/html,text/xml,text/plain,text/css,text/javascript,application/json"
connectionTimeout="20000"
redirectPort="8443" />
<Engine name="Catalina" defaultHost="localhost">
<Host name="localhost" appBase="webapps" unpackWARs="true" autoDeploy="true">
<Context path="" docBase="your-app" reloadable="true">
<WatchedResource>WEB-INF/web.xml</WatchedResource>
</Context>
</Host>
</Engine>
</Service>
</Server>
可能原因:多个配置冲突 解决方案:
# 查看所有编码相关系统属性
java -cp . EncodingChecker
# EncodingChecker.java
public class EncodingChecker {
public static void main(String[] args) {
System.out.println("file.encoding=" + System.getProperty("file.encoding"));
System.out.println("sun.jnu.encoding=" + System.getProperty("sun.jnu.encoding"));
System.out.println("Default Charset=" + Charset.defaultCharset());
}
}
解决方案:
# 确保logging.properties中所有FileHandler使用UTF-8
java.util.logging.FileHandler.encoding = UTF-8
1catalina.org.apache.juli.AsyncFileHandler.encoding = UTF-8
解决方案:
<!-- 确保server.xml中Connector配置 -->
<Connector URIEncoding="UTF-8" useBodyEncodingForURI="true" />
FROM tomcat:9.0
ENV LANG C.UTF-8
ENV LC_ALL C.UTF-8
ENV JAVA_OPTS="-Dfile.encoding=UTF-8 -Dsun.jnu.encoding=UTF-8"
# 修改server.xml
RUN sed -i 's/URIEncoding="ISO-8859-1"/URIEncoding="UTF-8"/g' /usr/local/tomcat/conf/server.xml
# 修改logging.properties
RUN sed -i 's/java.util.logging.ConsoleHandler.encoding =.*/java.util.logging.ConsoleHandler.encoding = UTF-8/g' /usr/local/tomcat/conf/logging.properties
通过以上综合方案,可以彻底解决Tomcat中文乱码问题。建议按照"操作系统 → JVM → Tomcat → 应用"的顺序逐步排查和设置。