DELPHI XE2 采用 JSON 的方式来序列化对象
DELPHI XE2 采用 JSON 的方式来序列化对象
以下代码测试通过。问题是里面的中文,在反序列化后是乱码。
1. 序列化对象为字符串,Subject 里面的中文看起来正常,仍然是中文;
2. 反序列化为对象后,Subject 里面的中文是乱码。
XE2 处理 Unicode 还是有问题啊。
TItemRecord = class
private
FID: string;
FSubject: string;
FADate: TDateTime;
published
property ID: string read FID write FID;
property Subject: string read FSubject write FSubject;
property ADate: TDateTime read FADate write FADate;
end;
procedure TForm1.Button3Click(Sender: TObject);
var
JO: TJSONObject;
P:TJSONPair;
A:TJSONArray;
B:TBytes;
S:string;
JM:TJSONMarshal;
JUM:TJSONUnMarshal;
Item: TItemRecord;
V, V2:TJSONValue;
UJ: TJSONUnMarshal;
begin
//采用 JSON
JM:=TJSONMarshal.Create;
Item := TItemRecord.Create;
with ClientDataSet1 do
begin
Item.ID := FieldByName('ID').AsString;
Item.Subject := FieldByName('Subject').AsString;
Item.ADate := FieldByName('ADate').AsDateTime;
end;
V:=JM.Marshal(Item); //序列化
S := V.ToString;
Item.Free;
V.Free;
Memo1.Lines.Text := S;
//------------------- 反序列化-------------
JO := TJSONObject.Create;
JO.Parse(BytesOf(S), 0, Length(S)); //将字符串变回 Json 对象
UJ := TJSONUnMarshal.Create;
Item := UJ.Unmarshal(JO) as TItemRecord; //将 Json 对象变回我自己的对象。
Memo1.Lines.Add('-----------');
Memo1.Lines.Add('ID = ' + Item.ID);
Memo1.Lines.Add('Subject = ' + Item.Subject); //问题: 对字符串里面的汉字编码没搞好,有问题。
Memo1.Lines.Add('Date = ' + DateTimeToStr(Item.ADate));
end;
---------------------------------------------------- 分隔符 -------------------------
前面说到,把对象用 ToString 的方法输出为字符串时,对象里面的中文在字符串里面是正确的,把字符串写道 TMEMO 里面显示出来的中文正常。但如果这时候把这个字符串用 JO.Parse(BytesOf(S), 0, Length(S)); 语句变回对象,则对象的中文字段值是乱码。
采用:B := TEncoding.ASCII.GetBytes(S); 的方式获得的 TBytes 用于 Parse,出来的对象,中文值也是乱码;
如果采用 B := TEncoding.Unicode.GetBytes(S); 的方式获得的 TBytes 用于Parse无法获得正确的对象,即运行 Jo.Parse(B, 0); 时会出现异常。
测试,不输出字符串,而是直接输出 TBytes,然后再拿这个 TBytes 去 Parse,获得的对象,中文字段值OK,没有乱码。
SetLength(B, 200);
i := V.ToBytes(B, 0);
JO := TJSONObject.Create;
Jo.Parse(B, 0);
UJ := TJSONUnMarshal.Create;
Item := UJ.Unmarshal(JO) as TItemRecord;
这样获得的 Item 对象,其中文字段值没乱码。
也就是说,它的 ToString 输出的不知道是什么编码,需要按其编码变换回 TBytes 才行。简单的 BytesOf(S) 不行。
----------------------------
继续测试:采用 UTF8 字符串
S := V.ToString;
S8 := Utf8Encode(S); //S8: UTF8STRING;
V2 := TJSONObject.ParseJSONValue(S8); //V2: TJSONValue;
然后, Item := UJ.Unmarshal(V2) as TItemRecord; 可以成功获得有中文字段值的对象!
也就是说,DELPHI 自带的 JSON 库,不能正确处理 UNICODE 双字节字符串,但能处理 UTF8 字符串。
-------------------------
继续:要处理中文,上面采用 Jo.Parse(B, 0); 的方式,直接处理中文字符串,获得的对象的中文字段值会乱码。
这样处理就对了:
V: TJSONValue;
V := TJSONObject.ParseJSONValue(S);
UJ := TJSONUnMarshal.Create;
Item := UJ.Unmarshal(V) as TItemRecord;
这样获得的对象,字段的中文值不是乱码,正常了。
总 结:不要用 TJSONObject 的对象的 Parse 方法来解析字符串为 JSON 对象,而应该用类方 法 TJSONObject.ParseJSONValue(S) 的方式来获得 TJSONValue 对象,然后拿这个 JSONValue 对象去 反序列化出来的对象,中文没问题。
---------------------------------
总结:绕了一大圈,其实很简单!它是可以直接处理UNICODE字符串的。只是 DELPHI 给出的这个JSON库里面的对象的方法,不太直观。
DELPHI XE2 采用 JSON 的方式来序列化对象的更多相关文章
- SpringBoot-08:SpringBoot采用json的方式实现前后台通用的配置文件
------------吾亦无他,唯手熟尔,谦卑若愚,好学若饥------------- 一.需求: 本篇博客是最近笔者做的一个项目,已经上线但是还在不断开发,有些页面上的配置,测试服务器和正式服务器 ...
- 依赖注入之setter注入---只需修改配置,电脑就可以安装不同的打印机;读取properties配置文件并创建实例;实现不采用new的方式直接实例化对象
1.项目截图 2.黑白打印机类 package com.example.demo.printer; public class GrayPrinter implements Printer{ @Over ...
- Delphi 10.2 JSON与对象/结构体序列化性能提高100多倍
今天在盒子闲逛,无意中看到有人说XE7自带的Json对象序列化很慢,帖子在这里:http://bbs.2ccc.com/topic.asp?topicid=464378;经过测试的确如此. 但 ...
- Java序列化的几种方式以及序列化的作用
Java序列化的几种方式以及序列化的作用 本文着重讲解一下Java序列化的相关内容. 如果对Java序列化感兴趣的同学可以研究一下. 一.Java序列化的作用 有的时候我们想要把一个Java对象 ...
- Newtonsoft.Json高级用法DataContractJsonSerializer,JavaScriptSerializer 和 Json.NET即Newtonsoft.Json datatable,dataset,modle,序列化
原文地址:https://www.cnblogs.com/yanweidie/p/4605212.html Newtonsoft.Json介绍 在做开发的时候,很多数据交换都是以json格式传输的.而 ...
- C#三种方式实现序列化(转)
序列化和反序列化我们可能经常会听到,其实通俗一点的解释,序列化就是把一个对象保存到一个文件或数据库字段中去,反序列化就是在适当的时候把这个文件再转化成原来的对象使用. 序列化和反序列化最主要的作用有: ...
- WebApi2官网学习记录---JSON与XML的序列化
JSON序列化: WebAPI的默认序列库使用的是Json.NET,可以在Globally中配置使用DataContractJsonSerializer 进行序列化 protected void Ap ...
- 关于Delphi XE2的FMX的一点点研究之消息篇
Delphi XE2出来了一阵子了,里面比较抢眼的东西,除了VCLStyle这个换肤的东西之外,另外最让人眼亮的应该是FMX这个东西了.万一的博客上都连载了一票的关于FMX的使用心得了.我还是没咋去关 ...
- 小白的Python之路 day4 json and pickle数据标准序列化
一.简述 我们在写入文件中的数据,只能是字符串或者二进制,但是要传入文件的数据不一定全是字符串或者二进制,那还要进行繁琐的转换,然后再读取的时候,还要再转回去,显得很麻烦,今天就来学习标准的序列化:j ...
随机推荐
- Erlang Process input queue
http://www.cnblogs.com/me-sa/archive/2011/11/05/erlang0012.html Erlang进程有自己的消息队列来保存接收到的消息,新接收到的消息放在队 ...
- CentOS使用(一)-----各种环境搭建
使用virtual box虚拟机,镜像为CentOS-6.9-x86_64-LiveDVD.iso,使用SecureCRT远程连接. 安装CentOS系统之后,选择host-only连接模式,修改虚拟 ...
- BZOJ 4264 小c找朋友 - hash
传送门 题目大意: 给定一张无向图,求满足以下条件的点对 (x,y) 数目:对任意点 z (z!=x,y),边 (x,z) 和 (y,z) 同时存在或同时不存在. 题目分析: 首先要分析的出如果xy满 ...
- Docker Redis 安装
原文:Docker Redis 安装 拉取官方的镜像 docker pull redis:3.2 查看 docker images redis 运行容器 docker run -p 6379:6379 ...
- 空间同构(isomorphic)
1. introduction 对于一个 M22 矩阵空间,其 dimM22=4,基的构成如下: {(1000)(0010)(0100)(0001)} 则:M22≅R4 对于 P3 多项式空间,也即: ...
- hexo主题选择和配置
之前用next主题,发现文章标题都是h2,不利于seo,想着通过改模板改成h1的,发现很繁琐.今天发现,通过下载指定版本的next后,标题自动是h1的. 参考网页https://notes.iissn ...
- Android中判断网络是否连接并提示设置
/** * 判断网络是否连通 * @param context * @return */ public static boolean isNetworkConnected(Context contex ...
- Android中TabHost中实现标签的滚动以及一些TabHost开发的奇怪问题
最近在使用TabHost的时候遇到了一些奇怪的问题,在这里总结分享备忘一下. 首先说一点TabActivity将会被FragmentActivity所替代,但是本文中却是使用的TabActivity. ...
- 【oracle ocp 知识点二】
1.数据库操作语言 DML在运行时下面的语句 添加一个新行到表 更新表现出一定的线 从表删除现有行 一个事务处理是由一系列的DML语句逻辑组成 A.insert 每次插入一行数据 字符和日期的须要单引 ...
- 0-1分布(伯努利分布)、n 重伯努利分布(二项分布)
1. 0-1 分布(伯努利分布) 0-1分布又名两点分布,或叫伯努利分布. P{X=k}=pk(1−p)1−k 其中 k=0,1. 伯努利分布未必一定是 0-1 分布,也可能是 a-b 分布,只需满足 ...