当前位置: 首页 > news >正文

Java 实战 - 字符编码问题解决方案

网罗开发(小红书、快手、视频号同名)

大家好,我是展菲,目前在上市企业从事人工智能项目研发管理工作,平时热衷于分享各种编程领域的软硬技能知识以及前沿技术,包括iOS、前端、Harmony OS、Java、Python等方向。在移动端开发、鸿蒙开发、物联网、嵌入式、云原生、开源等领域有深厚造诣。

图书作者:《ESP32-C3 物联网工程开发实战》
图书作者:《SwiftUI 入门,进阶与实战》
超级个体:COC上海社区主理人
特约讲师:大学讲师,谷歌亚马逊分享嘉宾
科技博主:华为HDE/HDG

我的博客内容涵盖广泛,主要分享技术教程、Bug解决方案、开发工具使用、前沿科技资讯、产品评测与使用体验。我特别关注云服务产品评测、AI 产品对比、开发板性能测试以及技术报告,同时也会提供产品优缺点分析、横向对比,并分享技术沙龙与行业大会的参会体验。我的目标是为读者提供有深度、有实用价值的技术洞察与分析。

展菲:您的前沿技术领航员
👋 大家好,我是展菲!
📱 全网搜索“展菲”,即可纵览我在各大平台的知识足迹。
📣 公众号“Swift社区”,每周定时推送干货满满的技术长文,从新兴框架的剖析到运维实战的复盘,助您技术进阶之路畅通无阻。
💬 微信端添加好友“fzhanfei”,与我直接交流,不管是项目瓶颈的求助,还是行业趋势的探讨,随时畅所欲言。
📅 最新动态:2025 年 3 月 17 日
快来加入技术社区,一起挖掘技术的无限潜能,携手迈向数字化新征程!


文章目录

    • 前言
    • 问题背景
      • 为什么会出现编码问题
      • 常见的乱码场景
    • 解决方案一:统一使用 UTF-8
      • 为什么选择 UTF-8
      • 如何在项目中统一使用 UTF-8
    • 解决方案二:设置 JVM 参数
      • 设置 JVM 参数
      • 在 IDE 中设置
      • 在代码中设置
      • 验证编码设置
    • 解决方案三:数据库字符集设置
      • MySQL 字符集设置
      • 连接数据库时设置字符集
      • 其他数据库的字符集设置
    • 实际应用场景
      • 场景一:Web 应用开发
      • 场景二:文件读写
      • 场景三:日志输出
    • 最佳实践建议
      • 统一编码规范
      • 明确指定编码
      • 验证编码设置
      • 测试不同环境
    • 总结

前言

最近在做一个 Java 项目的时候,遇到了一个让人头疼的问题:在 Windows 上开发的时候,中文字符显示正常,但部署到 Linux 服务器上就变成乱码了。刚开始以为是数据库的问题,检查了数据库字符集也没问题。后来才发现,原来是不同系统的默认编码不一致导致的。

相信很多开发者都遇到过类似的问题:代码里写的中文,在不同环境下显示不一样;从数据库读取的数据,有时候是乱码;日志文件里的中文显示不正常。这些问题虽然看起来简单,但如果不了解字符编码的原理,可能会折腾很久。今天我们就来聊聊字符编码问题的原因和解决方案。

问题背景

字符编码问题是一个很常见但又容易被忽视的问题。不同的系统、不同的环境,默认的字符编码可能不一样,这就导致了各种乱码问题。

为什么会出现编码问题

现在的计算机系统,底层都是使用二进制来存储数据的。但我们在屏幕上看到的文字,比如中文、英文、日文等,都是字符。要把字符转换成二进制存储,就需要用到字符编码。

常见的字符编码:

  • ASCII:最早的字符编码,只能表示 128 个字符,主要是英文字母、数字和一些符号
  • GBK/GB2312:中文编码,Windows 系统默认使用
  • UTF-8:现在最流行的编码,可以表示世界上所有的字符,跨平台兼容性好

问题根源:

不同系统默认的字符编码不一样:

  • Windows 系统默认使用 GBK 或 GB2312
  • Linux 系统默认使用 UTF-8
  • Mac 系统默认使用 UTF-8

如果你的代码在 Windows 上开发(默认 GBK),但部署到 Linux 服务器上(默认 UTF-8),就可能出现乱码问题。

常见的乱码场景

在实际开发中,我们经常会遇到这些乱码场景:

场景一:文件读取乱码

从文件读取数据时,如果文件的编码和读取时使用的编码不一致,就会出现乱码。比如文件是 UTF-8 编码的,但用 GBK 编码去读取,中文就会变成乱码。

场景二:数据库存储乱码

数据库的字符集设置不对,或者连接数据库时没有指定正确的字符集,存储和读取的数据就可能出现乱码。

场景三:日志输出乱码

程序输出的日志,如果控制台的编码设置不对,或者日志文件的编码不对,中文日志就会显示成乱码。

场景四:网络传输乱码

不同系统之间通过网络传输数据时,如果编码不一致,接收到的数据可能就是乱码。

解决方案一:统一使用 UTF-8

解决字符编码问题最根本的方法,就是统一使用 UTF-8 编码。UTF-8 是目前最流行的字符编码,几乎所有的现代系统都支持,而且可以表示世界上所有的字符。

为什么选择 UTF-8

UTF-8 有很多优点:

  1. 兼容性好:几乎所有的系统、浏览器、数据库都支持 UTF-8
  2. 国际化支持:可以表示世界上所有的字符,包括中文、日文、韩文、阿拉伯文等
  3. 向后兼容:对于 ASCII 字符,UTF-8 编码和 ASCII 编码完全一样
  4. 变长编码:英文字符只占 1 个字节,中文字符占 3 个字节,比较节省空间

如何在项目中统一使用 UTF-8

代码文件编码:

确保所有的源代码文件都使用 UTF-8 编码保存。在 IDE 中,可以设置默认的文件编码:

  • IntelliJ IDEA:File → Settings → Editor → File Encodings,将 Project Encoding 和 Default encoding for properties files 都设置为 UTF-8
  • Eclipse:Window → Preferences → General → Workspace,将 Text file encoding 设置为 UTF-8
  • VS Code:在设置中搜索 “files.encoding”,设置为 UTF-8

配置文件编码:

配置文件(如 properties、xml、json 等)也要使用 UTF-8 编码。特别是 properties 文件,如果包含中文,必须使用 UTF-8 编码,否则会出现乱码。

资源文件编码:

资源文件(如国际化文件、模板文件等)也要使用 UTF-8 编码。

解决方案二:设置 JVM 参数

在 Java 项目中,JVM 的默认字符编码可能会影响程序的运行。如果 JVM 的默认编码不是 UTF-8,可能会导致文件读写、网络传输等操作出现乱码。

设置 JVM 参数

在启动 Java 程序时,可以通过 JVM 参数来设置字符编码:

java -Dfile.encoding=UTF-8 -jar your-app.jar

这个参数会告诉 JVM,文件系统的默认编码是 UTF-8。

在 IDE 中设置

如果你在 IDE 中运行程序,也需要设置 JVM 参数:

IntelliJ IDEA:

  1. 点击 Run → Edit Configurations
  2. 选择你的运行配置
  3. 在 VM options 中输入:-Dfile.encoding=UTF-8
  4. 点击 Apply 和 OK

Eclipse:

  1. 右键项目 → Run As → Run Configurations
  2. 选择你的运行配置
  3. 在 Arguments 标签页的 VM arguments 中输入:-Dfile.encoding=UTF-8
  4. 点击 Apply 和 Run

在代码中设置

除了 JVM 参数,也可以在代码中设置系统属性:

System.setProperty("file.encoding","UTF-8");

但这种方式不推荐,因为有些代码可能在设置之前就已经读取了系统属性。

验证编码设置

可以通过代码来验证当前的编码设置:

System.out.println("默认字符编码: "+System.getProperty("file.encoding"));System.out.println("控制台编码: "+System.getProperty("console.encoding"));

如果输出不是 UTF-8,说明设置没有生效。

解决方案三:数据库字符集设置

数据库的字符集设置也很重要,如果数据库的字符集不对,存储和读取的数据就可能出现乱码。

MySQL 字符集设置

创建数据库时设置字符集:

CREATEDATABASEmydbDEFAULTCHARACTERSETutf8mb4DEFAULTCOLLATEutf8mb4_unicode_ci;

utf8mb4是 MySQL 中真正的 UTF-8 编码,可以存储所有的 Unicode 字符,包括 emoji 表情。而 MySQL 的utf8实际上只支持最多 3 字节的字符,不支持 emoji。

创建表时设置字符集:

CREATETABLEusers(idINTPRIMARYKEY,nameVARCHAR(100)CHARACTERSETutf8mb4COLLATEutf8mb4_unicode_ci)DEFAULTCHARACTERSETutf8mb4COLLATEutf8mb4_unicode_ci;

修改现有数据库字符集:

如果数据库已经创建,可以修改字符集:

ALTERDATABASEmydbCHARACTERSETutf8mb4COLLATEutf8mb4_unicode_ci;ALTERTABLEusersCONVERTTOCHARACTERSETutf8mb4COLLATEutf8mb4_unicode_ci;

连接数据库时设置字符集

在连接数据库时,也要指定字符集:

JDBC 连接字符串:

Stringurl="jdbc:mysql://localhost:3306/mydb?useUnicode=true&characterEncoding=utf8&useSSL=false";

或者使用更完整的参数:

Stringurl="jdbc:mysql://localhost:3306/mydb?useUnicode=true&characterEncoding=utf8mb4&useSSL=false&serverTimezone=UTC";

Spring Boot 配置:

application.propertiesapplication.yml中配置:

spring.datasource.url=jdbc:mysql://localhost:3306/mydb?useUnicode=true&characterEncoding=utf8mb4&useSSL=false spring.datasource.username=root spring.datasource.password=password

或者:

spring:datasource:url:jdbc:mysql://localhost:3306/mydb?useUnicode=true&characterEncoding=utf8mb4&useSSL=falseusername:rootpassword:password

其他数据库的字符集设置

PostgreSQL:

PostgreSQL 默认使用 UTF-8 编码,创建数据库时:

CREATEDATABASEmydbWITHENCODING'UTF8';

Oracle:

Oracle 数据库的字符集在创建数据库时设置,之后很难修改。建议在创建数据库时就选择 UTF-8 相关的字符集,如AL32UTF8

实际应用场景

让我们看看几个实际应用场景,了解如何在实际项目中应用这些解决方案:

场景一:Web 应用开发

在 Web 应用中,需要处理前端的请求和响应:

设置请求和响应编码:

在 Spring MVC 中,可以配置字符编码过滤器:

@ConfigurationpublicclassWebConfigimplementsWebMvcConfigurer{@BeanpublicCharacterEncodingFiltercharacterEncodingFilter(){CharacterEncodingFilterfilter=newCharacterEncodingFilter();filter.setEncoding("UTF-8");filter.setForceEncoding(true);returnfilter;}}

或者在web.xml中配置:

<filter><filter-name>characterEncodingFilter</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>

场景二:文件读写

在读写文件时,要明确指定编码:

读取文件:

// 使用 UTF-8 编码读取文件try(BufferedReaderreader=newBufferedReader(newInputStreamReader(newFileInputStream("file.txt"),StandardCharsets.UTF_8))){Stringline;while((line=reader.readLine())!=null){System.out.println(line);}}

写入文件:

// 使用 UTF-8 编码写入文件try(BufferedWriterwriter=newBufferedWriter(newOutputStreamWriter(newFileOutputStream("file.txt"),StandardCharsets.UTF_8))){writer.write("中文内容");}

场景三:日志输出

在输出日志时,要确保日志文件的编码正确:

Logback 配置:

<configuration><appendername="FILE"class="ch.qos.logback.core.FileAppender"><file>app.log</file><encoder><charset>UTF-8</charset><pattern>%d{yyyy-MM-dd HH:mm:ss} [%thread] %-5level %logger{36} - %msg%n</pattern></encoder></appender></configuration>

Log4j2 配置:

<Configuration><Appenders><Filename="File"fileName="app.log"><PatternLayoutpattern="%d{yyyy-MM-dd HH:mm:ss} [%t] %-5level %logger{36} - %msg%n"charset="UTF-8"/></File></Appenders></Configuration>

最佳实践建议

在实际项目中,为了避免字符编码问题,建议遵循以下最佳实践:

统一编码规范

  1. 所有代码文件使用 UTF-8 编码:包括 Java 源文件、配置文件、资源文件等
  2. 所有数据库使用 UTF-8 字符集:MySQL 使用 utf8mb4,PostgreSQL 使用 UTF8
  3. 所有网络传输使用 UTF-8 编码:HTTP 请求和响应、消息队列等
  4. 所有日志文件使用 UTF-8 编码:确保日志中的中文能正常显示

明确指定编码

在代码中,凡是涉及字符编码的地方,都要明确指定 UTF-8,不要依赖系统默认编码:

// 好的做法:明确指定编码Stringcontent=newString(bytes,StandardCharsets.UTF_8);// 不好的做法:依赖默认编码Stringcontent=newString(bytes);// 可能在不同环境下表现不一致

验证编码设置

在项目启动时,可以输出当前的编码设置,方便排查问题:

@PostConstructpublicvoidcheckEncoding(){System.out.println("file.encoding: "+System.getProperty("file.encoding"));System.out.println("Default Charset: "+Charset.defaultCharset());}

测试不同环境

在部署到不同环境之前,要测试字符编码是否正常:

  1. 在 Windows 开发环境测试
  2. 在 Linux 测试环境测试
  3. 在 Linux 生产环境测试

确保在所有环境下,中文字符都能正常显示。

总结

字符编码问题虽然看起来简单,但在实际项目中却经常遇到。解决这类问题的关键是统一使用 UTF-8 编码,并在所有可能涉及编码的地方明确指定。

关键点总结:

  1. 统一使用 UTF-8:所有文件、数据库、网络传输都使用 UTF-8 编码
  2. 设置 JVM 参数:通过-Dfile.encoding=UTF-8设置 JVM 默认编码
  3. 数据库字符集:数据库和表都使用 UTF-8 字符集,连接时也要指定字符集
  4. 明确指定编码:在代码中,凡是涉及编码的地方都要明确指定,不要依赖默认值
  5. 验证和测试:在不同环境下测试,确保编码设置正确

最佳实践:

  1. 项目开始时就统一编码规范
  2. 在 IDE 中设置默认编码为 UTF-8
  3. 在构建脚本中设置 JVM 参数
  4. 数据库创建时就使用 UTF-8 字符集
  5. 代码中明确指定编码,不要依赖默认值
http://www.jsqmd.com/news/295293/

相关文章:

  • LLMs之ISC:《Enhancing LLM Planning Capabilities through Intrinsic Self-Critique》翻译与解读
  • 干货大集合!AI应用架构师构建AI系统性能监控平台全攻略
  • AI原生应用领域边缘推理:实现实时智能决策的关键
  • 2025网文新手必看避坑指南:新人逆袭SOP|投稿指南+AI写小说工具合集
  • 盘点10个顶级写小说软件!ai写小说效率提升10倍,一个人顶一个编辑部!
  • 有哪些免费好用的AI写小说软件?盘点2026年AI写作10大辅助工具
  • 2026新手指南:盘点5款好用的写小说软件,第一款简直是“日更救星”!
  • 从零开始写网文:2026年最强小说软件生成器深度横评与避坑指南
  • 探索未来智能记忆系统 - MemU
  • [特殊字符] 提升你编码效率的超级助手:Awesome GitHub Copilot
  • 【心电信号ECG】QRS波和峰值的检测(从噪声和清晰信号中获得心跳)附Matlab代码和报告
  • 2026年市面上评价好的一体板加工厂怎么选,仿石漆保温装饰一体板/保温装饰一体板,一体板厂家哪家权威
  • 攻防世界ics-06
  • 微软开源 VibeVoice:90 分钟播客级语音合成技术解析
  • 高德地图 API Key 获取指南
  • best work
  • 在 Coze(扣子)中搭建自定义智能体
  • 一维振动信号变为二维灰度图,利用局部二值模式(LBP)深化灰度图特征,然后利用CNN进行特征提取,最后使用softmax分类器和SVM进行分类对比(Python代码,解压缩后直接运行)
  • 机械寿命预测(基于NASA C-MAPSS数据的剩余使用寿命RUL预测,Python代码,CNN_LSTM模型,有详细中文注释)
  • 基于深度学习的人脸面部表情识别系统(Python代码+PyqtUI界面,可以实现图像识别和视频识别,有详细中文注释)
  • 电池寿命预测(Python代码,K最近邻回归模型(KNN)、支持向量机回归模型(SVM)和随机森林回归模型(Random Forest)三种模型,添加了中文注释)
  • 2026年厦门GEO优化公司推荐Top5:从技术实力到效果落地的深度评估
  • 2026运动医学厂商怎么选?优质厂家在这里,内窥镜手术动力/泌尿科刨削动力代加工/运动医学,运动医学源头厂家选哪家
  • MLflow / Feast 实战手记:MLOps 不是装工具,是治内伤
  • 2026年1月济南GEO优化公司TOP5推荐榜:从技术硬实力到效果落地的全维度选型指南
  • 2026年重庆GEO优化公司排行榜Top6:从技术到效果的全维度选型指南
  • 学习日记day67
  • 全网最全本科生必用TOP9 AI论文网站测评
  • 长文本优化:KV Cache机制与显存占用平衡策略
  • 探寻优质之源:3 大维度揭秘宁波山水印红茶批发厂家——浙江山水印农业开发有限公司,生态红茶,红茶批发厂家怎么选