字符编码导致Rapidjson(腾讯开源的json解析库)到Fastjson(阿里开发的Java json解析库)转换失败的原因分析

简介: 最近在客户端的开发的过程中,使用到了RapidJson,公司的开发是客户端和数据库端都由不同的人进行开发,我负责的客户端的逻辑开发(使用c++),开发工具同时使用了VS2017和QT的编译环境,使用QT主要是为了客户端界面开发方便,而使用了VS环境主要是维护公司开发的数据库接口库,这个库的唯一作用就是作为一个中间桥梁,使用Rapidjson将数据库接口的json数据格式解析为结构体数据,从而在客户端界面进行展示,或者接收客户端的数据,使用Rapidjson将其转换为json数据,发送给数据库接口以保存数据使用 。不太明白的可以参考我上一篇文章说明Rapidjson的使用过程-Parse解析数组

开发环境说明

最近在客户端的开发的过程中,使用到了RapidJson,公司的开发是客户端和数据库端都由不同的人进行开发,我负责的客户端的逻辑开发(使用c++),开发工具同时使用了VS2017和QT的编译环境,使用QT主要是为了客户端界面开发方便,而使用了VS环境主要是维护公司开发的数据库接口库,这个库的唯一作用就是作为一个中间桥梁,使用Rapidjson将数据库接口的json数据格式解析为结构体数据,从而在客户端界面进行展示,或者接收客户端的数据,使用Rapidjson将其转换为json数据,发送给数据库接口以保存数据使用 。不太明白的可以参考我上一篇文章说明Rapidjson的使用过程-Parse解析数组遇到的问题,附自己的解决方式。


问题说明及其截图

在日常的开发中,一般使用http进行数据传输,都是使用UTF-8进行编码,然而在我们使用C++开发时,很多时候选择了GBK或者GB2312的编码格式进行开发,这样就会由于编码的不一致性,导致很多奇奇怪怪的问题,我这里出现的问题,就是将JSON数据传输给服务器端的时候,服务器端抛出了如下图的问题

e1717cf1364ef430bf8eced31f648dbd_watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L2FiY2Q1NTIxOTE4Njg=,size_16,color_FFFFFF,t_70#pic_center.png

只要有点java基础的人都知道,这个问题就是fastjson解析json时抛出异常,这个时候一般格式问题导致的情况居多,然而通过测试发现,输入纯英文的时候,不会抛出异常,一旦在客户端输入中文的时候,就会导致这一异常情况的发生,这时候,不用多想,肯定是编码不一致导致的问题了。我这里是从客户端输入数据(QT环境)-到库(VS2017环境)-到数据库接口(intellij idea),所以只要保证库到数据库接口环境使用UTF-8就可以了,然而在开发中,也要注意从QT到VS环境时,编码的问题,否则可能出现数据能保存成功,但是却出现乱码的情况。对编码有兴趣的同学可以查阅相关资料,这里只是记录自己在使用RapidJson遇到的问题记录下来。

首先是QT端的代码到库代码的部分截图

8fd0b0f26c5eb0e3332c3fd117d14983_watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L2FiY2Q1NTIxOTE4Njg=,size_16,color_FFFFFF,t_70#pic_center.png

这里我们使用的结构体的字符参数是char数组,不是c++标准库的string,首先将页面的字符数据(QString)使用toLocal8Bit()(这里不能使用toUtf8(),因为还要经过一次库的转化,否则这里就转化为UTF8编码格式,到库的环境又变成GBK的编码格式了,这里有点混乱,可以将数据存到数据库,但是存储的数据却是乱码)函数将其拷贝到结构体中,传给库使用,以下截图是库的代码截图


上图画红线部分时将其客户端传来的字符数组参数先转换为UTF-8编码的格式,然后在通过RapidJson将其数据传送给服务器端,这样就不会出现第一张图的异常了。转换函数为以下代码:

void CEncodingTools::ConvertGBToUTF8(const char* pcGBString, char* pcUTF8String, int nUTF8BuffSize)
{
  // GB2312转换成UTF-8 
  int nWideSize = MultiByteToWideChar(CP_ACP, 0, pcGBString, -1, NULL, 0);  
  WCHAR* wstrSrc = new WCHAR[nWideSize + 1];  
  MultiByteToWideChar(CP_ACP, 0, pcGBString, -1, wstrSrc, nWideSize + 1);   
  WideCharToMultiByte(CP_UTF8, 0, wstrSrc, -1, pcUTF8String, nUTF8BuffSize, NULL, NULL);  
  delete[] wstrSrc;
}


结论

PS: 一个小小的bug,写了这么多,难免有点啰嗦,主要是自己经验太少,花了好几个小时才解决了,只要记住,客户端和服务器端在数据传输的过程中,只要保证传输的格式为UTF-8格式即可,相信每次的小问题,通过自己的积累都会使得自己更加强大。


相关文章
|
1月前
|
算法 Linux 开发者
CMake深入解析:打造高效动态链接库路径设置
CMake深入解析:打造高效动态链接库路径设置
47 0
|
1月前
|
算法 数据处理 开发者
FFmpeg库的使用与深度解析:解码音频流流程
FFmpeg库的使用与深度解析:解码音频流流程
36 0
|
1月前
|
JSON JavaScript 前端开发
C++ 智能指针与 JSON 处理:高级编程技巧与常见问题解析
C++ 智能指针与 JSON 处理:高级编程技巧与常见问题解析
269 0
|
1月前
|
存储 JSON 安全
【C++ JSON库 json值的创建手段】深入探究C++中JSON对象定位与操作:从引用到回调函数
【C++ JSON库 json值的创建手段】深入探究C++中JSON对象定位与操作:从引用到回调函数
66 0
|
1月前
|
缓存 算法 C语言
【C++ 标准查找算法 】C++标准库查找算法深入解析(In-depth Analysis of C++ Standard Library Search Algorithms)
【C++ 标准查找算法 】C++标准库查找算法深入解析(In-depth Analysis of C++ Standard Library Search Algorithms)
48 0
|
11天前
|
JSON API 数据格式
python的request库如何拿到json的返回值
python的request库如何拿到json的返回值
10 0
|
16天前
|
存储 JSON JavaScript
「Python系列」Python JSON数据解析
在Python中解析JSON数据通常使用`json`模块。`json`模块提供了将JSON格式的数据转换为Python对象(如列表、字典等)以及将Python对象转换为JSON格式的数据的方法。
32 0
|
19天前
|
XML JSON JavaScript
Java中XML和JSON的比较与应用指南
本文对比了Java中XML和JSON的使用,XML以自我描述性和可扩展性著称,适合结构复杂、需验证的场景,但语法冗长。JSON结构简洁,适用于轻量级数据交换,但不支持命名空间。在Java中,处理XML可使用DOM、SAX解析器或XPath,而JSON可借助GSON、Jackson库。根据需求选择合适格式,注意安全、性能和可读性。
27 0
|
25天前
|
XML JSON JavaScript
使用JSON和XML:数据交换格式在Java Web开发中的应用
【4月更文挑战第3天】本文比较了JSON和XML在Java Web开发中的应用。JSON是一种轻量级、易读的数据交换格式,适合快速解析和节省空间,常用于API和Web服务。XML则提供更强的灵活性和数据描述能力,适合复杂数据结构。Java有Jackson和Gson等库处理JSON,JAXB和DOM/SAX处理XML。选择格式需根据应用场景和需求。
|
1月前
|
算法 IDE Linux
【CMake 小知识】CMake中的库目标命名和查找策略解析
【CMake 小知识】CMake中的库目标命名和查找策略解析
99 1

推荐镜像

更多