实用指南:Docker部署旧版本系统MySQL5.7+乱码问题解决方案

问题描述

公司需要部署一个周报管理系统,该系统目前在Windows环境下运行良好。现在,计划将其迁移到服务器上进行部署,故将这个活交给我部署,但由于系统较为陈旧,依然使用的是JSP技术栈。同时,还需要拉取tomcat:7-jre8的Docker镜像。更棘手的问题是,系统使用的是MySQL 5.7+版本,而不是当前主流的MySQL 8+,这导致在适配新的UTF-8编码格式时遇到了一些挑战。在使用Docker部署该周报管理系统后,虽然容器成功启动,但访问应用页面时却发现中文内容出现了乱码:

æ ´å°±å»ºç« å·¥ç¨‹å’Œå…±å»ºé¡¹ç›®ç®¡ç�†ç³»ç»Ÿ

同时,应用能够正常访问,但部分功能可能受到影响。

在这里插入图片描述

问题分析

通过查看应用日志和配置,我们逐步排查了可能导致乱码的原因:

  1. 应用编码配置:应用的JSP页面和web.xml已经配置了UTF-8编码
  2. Tomcat编码配置:默认Tomcat配置可能没有启用UTF-8编码支持
  3. MySQL字符集配置:数据库初始化和连接可能存在编码不一致问题
  4. 数据库连接参数:使用了不兼容的JDBC连接参数

解决方案

1. 检查应用编码配置

首先确认应用本身已经配置了UTF-8编码:

  • JSP页面:所有JSP页面都包含<%@ page contentType="text/html;charset=UTF-8"%>
  • web.xml:配置了CharacterEncodingFilter,强制使用UTF-8编码
<filter>
<filter-name>encodingFilter</filter-name>
<filter-class>org.springframework.web.filter.CharacterEncodingFilter</filter-class>
  <init-param>
  <param-name>encoding</param-name>
  <param-value>UTF-8</param-value>
  </init-param>
  <init-param>
  <param-name>forceEncoding</param-name>
  <param-value>true</param-value>
  </init-param>
</filter>
<filter-mapping>
<filter-name>encodingFilter</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>

2. 调整Tomcat编码设置

修改Dockerfile的文件,为Tomcat添加UTF-8编码支持:

# 设置环境变量,添加UTF-8编码支持
ENV JAVA_OPTS="-Djava.security.egd=file:/dev/./urandom -Dfile.encoding=UTF-8 -Dsun.jnu.encoding=UTF-8"
# 配置Tomcat URI编码为UTF-8
RUN sed -i 's/

以下为我完整的Dockerfile的文件配置

# 使用官方Tomcat 7镜像作为基础镜像
FROM tomcat:7-jre8
# 维护者信息
LABEL maintainer="周报管理系统"
# 移除Tomcat默认的ROOT应用
RUN rm -rf /usr/local/tomcat/webapps/ROOT
# 将打包好的WAR文件复制到Tomcat的webapps/weekly目录
COPY ./tomcat /usr/local/tomcat/webapps/weekly
# 暴露Tomcat端口
EXPOSE 8080
# 设置环境变量,添加UTF-8编码支持
ENV JAVA_OPTS="-Djava.security.egd=file:/dev/./urandom -Dfile.encoding=UTF-8 -Dsun.jnu.encoding=UTF-8"
# 配置Tomcat URI编码为UTF-8
RUN sed -i 's/

3. 优化MySQL配置

在docker-compose.yml中添加完整的MySQL字符集配置:

command: >
--character-set-server=utf8mb4
--collation-server=utf8mb4_unicode_ci
--init-connect='SET NAMES utf8mb4'
--skip-character-set-client-handshake
--sql-mode=STRICT_TRANS_TABLES,NO_ZERO_IN_DATE,NO_ZERO_DATE,ERROR_FOR_DIVISION_BY_ZERO,NO_AUTO_CREATE_USER,NO_ENGINE_SUBSTITUTION

4. 修复数据库连接参数

检查并修复jeeplus.properties中的数据库连接参数。旧版本MySQL驱动不支持某些参数,导致连接失败:

错误配置

jdbc.url=jdbc:mysql://mysql:3306/weekly?useUnicode=true&characterEncoding=utf-8&useSSL=false&connectionCollation=utf8mb4_unicode_ci&serverTimezone=Asia/Shanghai

正确配置

jdbc.url=jdbc:mysql://mysql:3306/weekly?useUnicode=true&characterEncoding=utf-8&useSSL=false
正确配置的修改:
  1. 去掉了 connectionCollation=utf8mb4_unicode_ci:这个参数与字符集的选择有关,但它通常不需要在 JDBC URL 中显式指定,除非有特别的需求,通常 MySQL 默认就会使用 utf8mb4 编码。
  2. 去掉了 serverTimezone=Asia/Shanghai:这个参数用于设置时区,可能在某些情况下需要,但它并不是必须的,特别是如果 MySQL 服务器的时区配置正确的话。去掉这个参数有时能避免时区冲突问题,尤其是在使用容器或者跨时区部署时。

总结,正确配置 去除了多余的配置项,确保了简单且有效的连接配置。

重新部署验证

  1. 停止并移除旧容器

    docker-compose down
  2. 删除旧数据卷(如果需要重新初始化数据):

    docker volume rm weekly_mysql_data
  3. 重新构建镜像并启动容器

    docker-compose up -d --build
  4. 验证部署结果

    # 查看容器状态
    docker-compose ps
    # 查看应用日志
    docker-compose logs -f tomcat
  5. 访问应用验证

    http://172.16.xxx.xxx:8082/weekly/a/login

在这里插入图片描述

分享一下docker-compose.yml 的配置

# 创建一个新的用户定义网络,手动指定一个未被占用的子网
networks:
weekly_network:
driver: bridge
ipam:
config:
- subnet: 10.0.0.0/24  # 使用一个未被占用的私有网络子网
services:
# MySQL数据库服务
mysql:
image: mysql:5.7.44
container_name: weekly_mysql
restart: always
environment:
MYSQL_ROOT_PASSWORD: root_password  # 替换为你的根密码
MYSQL_DATABASE: weekly              # 数据库名
MYSQL_USER: weekly_user             # 数据库用户名
MYSQL_PASSWORD: weekly_password     # 数据库密码
ports:
- "3308:3306"
volumes:
- ./mysql/weekly.sql:/docker-entrypoint-initdb.d/init.sql  # 初始化脚本
- mysql_data:/var/lib/mysql  # 数据持久化
command: >
--character-set-server=utf8mb4
--collation-server=utf8mb4_unicode_ci
--init-connect='SET NAMES utf8mb4'
--skip-character-set-client-handshake
--sql-mode=STRICT_TRANS_TABLES,NO_ZERO_IN_DATE,NO_ZERO_DATE,ERROR_FOR_DIVISION_BY_ZERO,NO_AUTO_CREATE_USER,NO_ENGINE_SUBSTITUTION
networks:
- weekly_network
# Tomcat应用服务
tomcat:
build: .
container_name: weekly_tomcat
restart: always
depends_on:
- mysql
ports:
- "8082:8080"
environment:
- SPRING_PROFILES_ACTIVE=prod
volumes:
- tomcat_logs:/usr/local/tomcat/logs  # 日志持久化
networks:
- weekly_network
volumes:
mysql_data:
driver: local
tomcat_logs:
driver: local

预防措施

  1. 统一编码标准:确保应用、Tomcat、MySQL和数据库连接都使用UTF-8编码
  2. 适配驱动版本:根据MySQL版本选择合适的JDBC驱动,避免使用不兼容的连接参数
  3. 详细日志记录:启用应用和数据库的详细日志,便于排查问题
  4. 定期备份数据:确保数据安全,便于恢复
  5. 测试编码兼容性:在开发环境中测试多语言支持,确保编码正确
  6. 使用utf8mb4字符集:支持完整的Unicode字符,包括emoji表情

总结

通过系统性地排查和解决,我们成功解决了周报管理系统Docker部署中的乱码问题。主要解决步骤包括:

  1. 调整Tomcat配置,确保启用UTF-8编码支持
  2. 优化MySQL配置,统一字符集设置
  3. 修复数据库连接参数,确保与驱动版本兼容
  4. 重新部署验证,确认问题解决

如果觉得有帮助,欢迎点赞收藏!有问题欢迎评论区交流~

posted @ 2026-02-13 21:08  clnchanpin  阅读(15)  评论(0)    收藏  举报