问答文章1 问答文章501 问答文章1001 问答文章1501 问答文章2001 问答文章2501 问答文章3001 问答文章3501 问答文章4001 问答文章4501 问答文章5001 问答文章5501 问答文章6001 问答文章6501 问答文章7001 问答文章7501 问答文章8001 问答文章8501 问答文章9001 问答文章9501

OkHTTP、Retrofit 中文乱码解决方法

发布网友 发布时间:2023-07-16 06:53

我来回答

1个回答

热心网友 时间:2024-10-25 09:11

出现乱码的根本原因是客户端、服务端两端编码格式不一致导致的。

客户端:多数情况下,客户端的编码格式是 UTF-8。
服务端:服务端会根据不同的请求方法使用不同的编码格式。如:请求方法为 POST 时,编码格式为 UTF-8;请求方法为 GET 时,编码格式为 ISO8859-1。

当请求方法为 POST 时,客户端和服务端两边的编码格式一致,所以不存在乱码问题。因此此处着重看下如何解决当请求方法为 GET 时的乱码问题。

解决方法倒也简单,只不过需要客户端和服务端配合:

在向 URL 添加参数之前,先对目标参数进行两次 encode,如 UTF-8:

服务器在收到数据之后,只需将数据进行一次跟客户端编码格式一样的 decode,如 UTF-8:

这样处理之后,两边就不会再出现乱码了。

通过上面的分析可知,乱码产生的主要原因是客户端、服务器两边编码不一致造成的,即发送 GET 请求时,客户端使用的是 UTF-8 编码格式对 URL 中的参数进行编码,而服务器在接收数据的时候,使用的是 ISO8859-1(解析 POST 请求时,服务器使用的编码格式是 UTF-8 编码格式)编码格式对 URL 中的参数进行解码。

ISO8859-1 跟 ASCII 码一样,都是单字节编码,ISO8859-1 是从 ASCII 扩展而来的。ISO8859-1 将 ASCII 一个字节中剩余的最后一位用了起来,也就是说,它比 ASCII 多了 128 个字符。另外,因为 ISO8859-1 是从 ASCII 扩展而来的,所以,ISO8859-1 兼容 ASCII。

原数据:

客户端第一次编码,URLDecoder.decode(username, "UTF-8") 编码之后:

客户端第二次编码,URLDecoder.decode(username, "UTF-8") 编码之后:

客户端发出的 URL:

服务器接收的 URL:

服务器第一次解码,服务器接收到 GET 请求之后,默认会用 ISO8859-1 编码格式解码,解码之后得到:

需要注意的是,服务器用 ISO8859-1 编码格式解码 URL 中的参数是自动完成的。
因为客户端第一次用 URLDecoder.decode(username, "UTF-8") 编码 URL 中参数之后,得到的是 ASCII 码,且 UTF-8 和 ISO8859-1 对 ASCII 的编码结果是一致的,所以,客户端第二次用 URLDecoder.decode(username, "UTF-8") 之后的结果可以直接用 ISO8859-1 编码格式解码。
由于服务器解码之后的 URL 中的参数是用 UTF-8 编码格式编码的,所以,此时需要服务器再用 UTF-8 编码格式解码一次。

服务器第二次解码,服务器用 UTF-8 编码格式解码之后得到:

如果客户端程序员没有显式用 UTF-8 编码格式编码 URL 中的参数,服务端要如何处理才能获取到原数据?

首先,分析下如果客户端没有用 UTF-8 编码格式编码 URL 中的参数,程序是如何执行的:

网络请求框架会对 URL 中的参数进行一次 UTF-8 编码:

服务器会对 URL 中的参数进行一次 ISO8859-1 编码:

明白了执行流程之后,如何解决自然也就显而易见了:
先转回 ISO8859-1 解码(decode)之前的结果,再转会 UTF-8 编码(encode)之前的结果。

具体操作步骤:

因为 URL 中的参数经 UTF-8 编码格式编码之后得到的结果在 ISO8859-1 字符集可能一样也可能根本表示不了,这也是为什么 ASCII 码经 UTF-8 编码格式编码之后的结果可以用 ISO8859-1 编码格式解码。如,在 Unicode 字符集中,第 20013 个字符是“中”,而在 ISO8859-1 字符集中,一共才有 256 个字符。字符“中”经 UTF-8 编码之后的结果再经 ISO8859-1 解码,无论如何也得不到正确答案的。
声明声明:本网页内容为用户发布,旨在传播知识,不代表本网认同其观点,若有侵权等问题请及时与本网联系,我们将在第一时间删除处理。E-MAIL:11247931@qq.com
梦幻西游怎样查看自己怎么加的属性点阿? 我好长时间没玩了 .. 怎么... 梦幻西游怎么查看我各项加了多少点 卤肉料的配方 卤肉上色最好的配方前十 三国中曹操有几个儿子 曹植的意思是什么 曹操有多少个儿子?其中姓名叫什么? 简谱中1=c2/4是什么意思?别说几节几拍我不知道节和拍是什么意思 简谱四分之二什么意思 ...是鸡膏吗 放在老汤里行吗 怎么才能容于水 谢谢 怎么使用? 梦见和前男友买西服 为什么人们会对手机上瘾呢? 梦见把自己的上衣西服给别人 手机真的会让人上瘾吗? 梦见别人赠送一套西服的预兆 梦见陪去世父亲买西服 有没动漫女主角一开始不喜欢男主但男主慢慢变强然后女主慢慢爱上... 求动漫,男主很强很低调,女主刚开始讨厌男主,后来慢慢喜欢上男主,男主... 梦见梦女朋友送西服 日本动漫 刚开始女主不喜欢男主慢慢就喜欢上男主的动漫 一开始女主和男主相互讨厌后来女主喜欢男主的动漫 有什么动漫女主由讨厌到喜欢男主的 求动漫啊! 1.女主刚开始不喜欢男主,后来喜欢男主 “德”、“惑”、“尊”、“沃”、“呈”、“惫”、“堪”和“善... 原神三枚牙齿的位置 原神牙齿三个位置 ...腐殖之牙龙牙位置原神龙牙刷新点元神腐殖之牙任务怎么做 巴硕M70手机售后处理的及时吗? 巴硕M70手机国内有卖的吗?还是海外市场多? 巴硕M70手机是杂牌子手机吗?好用吗? 打印机出现乱码是什么原因? 索尼微单6000,怎么传照片到苹果7plus上,一直都不成功,求大神 我的索尼RX102数码相机最近开始无法向苹果平板电脑发送照片,发送... 塔松优秀作文 石猴子煮汤好还是用酒泡好? win7如何更改txt后缀 1800古道江湖酒在哪能买到 江湖一杯酒多少钱一瓶 我们应该怎样报答父母的养育之恩呢? 父母的养育之恩是否应该回报? 对父母的养育之恩,我们应该怎么回报? 您好医生,我家孩子手足口病手脚口屁股上都有,也伴有泡,怎么治疗呢! 有谁知道《传闻中的七公主》当七和太子的吻戏在第几集? 交行和中信银行哪个压力大 i712650h值不值得买 宝宝得了手足口病嘴里有很多疱疹怎么办? 有没有公主关在鸟笼子里挂在树上被太子救电视剧 i712650h和i513500h哪个好 中信银行理财经理压力大吗 比较三角形,矩形和圆形哪个抗弯性能最好?拜托了各位 谢谢