正确的认识乱码与编码

本文涉及的产品
RDS MySQL Serverless 基础系列,0.5-2RCU 50GB
RDS MySQL Serverless 高可用系列,价值2615元额度,1个月
云数据库 RDS MySQL,高可用系列 2核4GB
简介: 编码将《内存字节》作用于《磁盘文件或者网络文件》的过程,也是将《磁盘文件/网络文件》反解析成《内存字节》的过程. 这个过程中如果 内存字符串到 “字节数组”的编码 与 网络/磁盘文件的之间转化的编解码方式不一致或者不兼容就 会产生乱码. 在一次网络数据访问的过程中,可能有多次这两个步骤的转化.

编码的本质

编码将《内存字节》作用于《磁盘文件或者网络文件》的过程,也是将《磁盘文件/网络文件》反解析成《内存字节》的过程.
这个过程中如果 内存字符串到 “字节数组”的编码 与 网络/磁盘文件的之间转化的编解码方式不一致或者不兼容就 会产生乱码. 在一次网络数据访问的过程中,可能有多次这两个步骤的转化.

写文件的正常流程:内存字符串->"使用编码转化为"-> 字节数组 ,writer将字节数组写入文件,文件头中的编码方式如果和 字符串转化为字节数组的编码不一致或者不兼容,打开文件/再次使用文件头中的编码方式读取文件的时候就会显示乱码, 这个时候方式处理是: 如果明确知道字符串到字节数组转化使用的编码,那么打开文件或者读取文件主动指定使用的编码就行了

上面讲了乱码的原理性,在判断乱码的时候需要考虑输入源的编码是什么,输出源使用了什么编码 , 下面看几个乱码的例子.

乱码的几个例子及思考解决方案

浏览器输入到后端乱码

现象不再赘述

理论上浏览器发送请求的时候,指定编码 并使用指定的编码编码request param或者body 那么后端只要使用浏览器说的编码来 解码就能得到正确内容.

排查方式为 确认request header中的编码方式 与后端接收到并且解码的编码方式是否一致,可以使用抓包的方式判断。如果request header中没有指定编码方式,那么就看浏览器以及服务端的默认编码方式了, 所以在协议交互的过程中编码方式是最好显示指定

后端返回浏览器乱码

现象不再赘述

理论上后端返回response的时候会在response header中带上编码方式,并使用指定的编码方式编码response body 那么浏览器只要使用response header中的编码来 解码就能得到正确内容.

排查方式为 确认response header中的编码方式,了解不同浏览器的默认编码逻辑. 以及html中的其他元素标签对编码的支持

java 枚举类乱码

public enum OfcDeliveryStatusEnum {
    init(0, "数据库-初始化"),
    create(1, "生成运单"),
    accept(2, "配送待分配")
        private Integer code;
    private String desc;
}

现象:当在代码中想要使用OfcDeliveryStatusEnum.create.getDesc()的时候 发现获取到的是乱码

原因:java源文件是UTF-8格式保存的,maven编译使用的GBK格式编译生产class文件,这中间有一个文件读取到内存再输出到文件的过程,编码的差异导致格式被破坏从而产生乱码.

排查方式需要明白java的工作原理,OfcDeliveryStatusEnum.create.getDesc() 程序运行起来后直接从内存的metaspace中取出来的,如果内存中通过utf-8查看是乱码,那么内存中已经乱码了,而内存值是通过加载class文件生成的,那么class文件难道也是乱码吗?class文件是maven从java源文件编译而来,源文件正常,那只可能是编译过程出了问题

数据库存储乱码

现象不再赘述

应用程序连接mysql server之间有一次通信会话写入数据,mysql server到 存储到磁盘有一次文件存储,从mysqlserver 查询数据返回到前端有一次通信会话 可以看到这中间有3次通信,那就存在三次编码转化,分别抓住两次编码转化是否一致。

1)character_set_server:mysql server默认字符集。
2)character_set_database:数据库默认字符集。
3)character_set_client:MySQL server假定客户端发送的查询使用的字符集。
4)character_set_connection:MySQL Server接收客户端发布的查询请求后,将其转换为character_set_connection变量指定的字符集。
5)character_set_results:mysql server把结果集和错误信息转换为character_set_results指定的字符集,并发送给客户端。
6)character_set_system:系统元数据(字段名等)字符集

Linux系统显示乱码

https://help.aliyun.com/document_detail/169436.html

总结


不管什么场景,只要存在一次读写操作,如果使用的编码不一致就可能导致乱码, 现实中碰到的场景都可能使用多次读写操作的复合场景,判断乱码的方式需要分段判断,最终确认第一次出现编码不一致的一段

相关实践学习
每个IT人都想学的“Web应用上云经典架构”实战
本实验从Web应用上云这个最基本的、最普遍的需求出发,帮助IT从业者们通过“阿里云Web应用上云解决方案”,了解一个企业级Web应用上云的常见架构,了解如何构建一个高可用、可扩展的企业级应用架构。
MySQL数据库入门学习
本课程通过最流行的开源数据库MySQL带你了解数据库的世界。   相关的阿里云产品:云数据库RDS MySQL 版 阿里云关系型数据库RDS(Relational Database Service)是一种稳定可靠、可弹性伸缩的在线数据库服务,提供容灾、备份、恢复、迁移等方面的全套解决方案,彻底解决数据库运维的烦恼。 了解产品详情: https://www.aliyun.com/product/rds/mysql 
目录
相关文章
|
Arthas 监控 Java
Arthas 可以用于监控和诊断在 Windows 系统下部署的 Tomcat 服务
Arthas 可以用于监控和诊断在 Windows 系统下部署的 Tomcat 服务
1262 2
|
5月前
|
存储 运维 安全
探秘阿里云云专线:企业上云网络连接的最优解
阿里云云专线(CCN)是专用网络连接服务,通过物理专线将企业本地网络与云端资源无缝连接。它具备高速稳定、安全可靠、灵活扩展和便捷管理等优势,适用于混合云架构、分支机构互联及数据灾备迁移等场景。用户可登录阿里云官网选择合适套餐并快速开通服务,关注公众号还能获取更多资讯。
433 9
|
Linux 数据处理 Perl
深入探索Linux中的`more`命令
`more`命令是Linux下的文本查看器,适合查看长文件,分页显示内容,支持交互操作如空格(下一页)、回车(下一行)、q(退出)。参数包括:+<num>从指定行开始,/-<num>跳过行,/pattern搜索模式。示例:查看日志`more /var/log/syslog`,从第1000行开始`more +1000 file`,搜索关键词`more /var/log/syslog +/ERROR`。大文件可考虑使用`less`。结合`grep`等命令增强功能。
|
Dart API C语言
Dart ffi 使用问题之想在C/C++中创建异步线程来调用Dart方法,如何操作
Dart ffi 使用问题之想在C/C++中创建异步线程来调用Dart方法,如何操作
|
SQL Java 数据库连接
Hibernate 批量操作来袭!掌握最佳实践,轻松应对数据洪流,开启高效开发新时代
【9月更文挑战第3天】在软件开发中,高效数据操作至关重要。作为流行的Java持久化框架,Hibernate提供了强大的数据库操作功能。本文探讨了Hibernate批量操作,包括批量插入、更新和删除的最佳实践,通过使用原生SQL和`Session`的`createNativeQuery()`方法,结合`addBatch()`及`executeBatch()`方法实现高效批量操作。合理设置批量大小、事务管理和性能测试是优化的关键。在实际开发中,应根据业务需求和性能要求选择合适的方法,以提升程序性能和可维护性。
647 3
|
Java Windows
Java演进问题之JVM在内存返还策略上会左右为难如何解决
Java演进问题之JVM在内存返还策略上会左右为难如何解决
188 0
|
消息中间件 SQL 关系型数据库
设置 Flink 的定时任务来实现定时触发写入 MySQL 的逻辑
设置 Flink 的定时任务来实现定时触发写入 MySQL 的逻辑
1646 1
|
负载均衡 算法 应用服务中间件
Nginx+Tomcat实现反向代理与负载均衡入门
Nginx+Tomcat实现反向代理与负载均衡入门
580 0
|
人工智能 JavaScript 前端开发
AI问答:JSBridge / WebView 与 Native 通信
AI问答:JSBridge / WebView 与 Native 通信
366 0
|
存储 人工智能 自然语言处理
中文分词模型体验
中文分词任务就是把连续的汉字分隔成具有语言语义学意义的词汇。中文的书写习惯不像英文等日耳曼语系语言词与词之前显式的用空格分隔。为了让计算机理解中文文本,通常来说中文信息处理的第一步就是进行文本分词。
1270 32
中文分词模型体验