
1. 编码问题为何成为TongWeb部署的头号杀手第一次在TongWeb上部署应用时我就被乱码问题狠狠教育了一回。明明在本地测试环境运行正常的系统部署到TongWeb后中文全部变成了。后来才发现TongWeb默认使用GBK编码而我们的开发环境都是UTF-8这就导致了全链路编码不匹配的问题。乱码问题之所以棘手是因为它可能出现在应用部署的任何一个环节。从操作系统环境、JDK参数到TongWeb容器配置再到应用自身编码和数据库连接任何一环的编码设置不统一都可能导致最终显示异常。更麻烦的是当问题出现时我们往往很难快速定位到底是哪个环节出了问题。2. 操作系统层面的编码基础配置2.1 Linux系统字符集检查在开始部署前首先要确保操作系统支持中文字符集。在Linux终端执行以下命令locale -a | grep zh_CN这个命令会列出系统已安装的中文字符集。如果输出为空说明需要安装中文语言包。对于CentOS系统可以这样安装yum groupinstall Chinese Support2.2 环境变量LANG的设置系统当前使用的字符集可以通过echo $LANG查看。对于中文环境通常设置为export LANGzh_CN.UTF-8为了让这个设置永久生效可以将其添加到/etc/profile或用户目录的.bashrc文件中。需要注意的是这个设置会影响系统命令的输出和终端显示但对Java应用的编码影响有限。3. JDK层面的关键编码参数3.1 -Dfile.encoding参数详解Java应用最关键的编码参数是-Dfile.encoding它决定了JVM默认的字符编码方式。在TongWeb的启动脚本中通常是startserver.sh我们需要添加JAVA_OPTS$JAVA_OPTS -Dfile.encodingUTF-8这个参数必须在JVM启动时指定运行时通过System.setProperty()修改是无效的。我曾经在一个项目中尝试动态修改这个参数结果发现虽然属性值变了但实际编码行为并没有改变。3.2 sun.jnu.encoding的作用另一个容易被忽视的参数是-Dsun.jnu.encoding它影响文件名相关的编码处理。当你的应用中出现文件内容正常但文件名乱码的情况时很可能就是这个问题。建议与file.encoding保持一致JAVA_OPTS$JAVA_OPTS -Dsun.jnu.encodingUTF-8这两个参数的关系可以这样理解file.encoding管内容sun.jnu.encoding管文件名。就像装修房子时一个负责室内装潢一个负责门牌号码。4. TongWeb容器自身的编码配置4.1 Web容器默认编码修改TongWeb的Web容器默认使用GBK编码这需要我们手动修改为UTF-8。通过管理控制台通常是9060端口进入WEB容器配置 容器配置修改默认请求参数解码字符集和默认应答编码字符集为UTF-84.2 HTTP通道的URL编码设置URL编码问题特别容易导致GET请求参数乱码。在控制台中进入HTTP通道管理选择tong-http-listener在其他设置中将URL编码格式改为UTF-8这个设置相当于Tomcat中的URIEncoding参数。我遇到过这样的情况同样的应用在Tomcat上正常迁移到TongWeb就出现乱码问题就出在这个配置上。5. 应用自身的编码规范5.1 Filter中的编码设置即使容器配置正确应用内部也需要统一编码。最常见的做法是在Filter中设置request.setCharacterEncoding(UTF-8); response.setCharacterEncoding(UTF-8);这个Filter应该放在过滤器链的最前面确保后续处理都能使用正确的编码。我曾经排查过一个案例因为Filter顺序问题导致编码设置被覆盖折腾了大半天才发现。5.2 代码中的硬编码转换要特别注意代码中的硬编码转换比如new String(bytes, ISO-8859-1);这种写法相当于埋下了定时炸弹。建议统一使用标准编码常量new String(bytes, StandardCharsets.UTF_8);6. 数据库连接的编码配置6.1 JDBC连接字符串参数数据库连接也需要指定编码以MySQL为例jdbc:mysql://localhost:3306/db?useUnicodetruecharacterEncodingutf-8这个配置必须与数据库的实际编码一致。有一次我们的DBA把数据库默认编码改成了latin1导致所有中文都变成了乱码这个教训让我记忆犹新。6.2 数据库服务端配置除了JDBC参数还要确认数据库服务端的配置。对于MySQL检查my.cnf中的配置[mysqld] character-set-serverutf8mb4 collation-serverutf8mb4_unicode_ci7. 日志输出的编码问题7.1 终端编码与日志编码匹配当通过SSH查看日志时如果终端编码与日志文件编码不一致就会出现乱码。可以通过以下命令设置终端编码export LANGen_US.UTF-8或者直接下载日志文件到本地用支持多种编码的编辑器如Notepad查看。7.2 Log4j的编码配置在log4j配置中确保指定了正确的编码log4j.appender.file.encodingUTF-8我曾经遇到过一个有趣的案例日志文件本身是UTF-8编码但log4j配置成了GBK结果日志中英文正常中文全是乱码。8. 全链路编码检查清单为了帮助大家系统性地排查编码问题我整理了一个检查清单操作系统locale -a确认支持中文echo $LANG确认当前编码JDK参数检查启动脚本中的-Dfile.encoding检查-Dsun.jnu.encodingTongWeb配置容器默认编码HTTP通道URL编码检查tongweb.xml文件应用代码Filter中的编码设置避免硬编码转换检查第三方库的编码依赖数据库JDBC连接字符串参数数据库服务端配置日志系统日志框架编码配置终端编码匹配这套检查清单在我们团队内部被称为编码六脉神剑帮助新人快速定位编码问题。记住解决乱码问题的黄金法则就是全链路编码统一。无论是UTF-8还是GBK只要所有环节保持一致就能避免大多数乱码问题。