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库里面的对象的方法,不太直观。

http://blog.sina.com.cn/s/blog_722bc92e0101hl88.html

时间: 2024-12-24 12:34:32

DELPHI XE2 采用 JSON 的方式来序列化对象的相关文章

依赖注入之setter注入---只需修改配置,电脑就可以安装不同的打印机;读取properties配置文件并创建实例;实现不采用new的方式直接实例化对象

1.项目截图 2.黑白打印机类 package com.example.demo.printer; public class GrayPrinter implements Printer{ @Override public void init() { System.out.println("启动打印机"); } @Override public void print(String txt) { System.out.println("打印黑白文字:".concat(

Delphi 10.2 JSON与对象/结构体序列化性能提高100多倍

今天在盒子闲逛,无意中看到有人说XE7自带的Json对象序列化很慢,帖子在这里:http://bbs.2ccc.com/topic.asp?topicid=464378;经过测试的确如此.     但是 D10.2后,自带的 Json 做了优化,性能大大的提高了100多倍. 和其他json库对比了序列化和反序列化性能,JsonDataObjects 性能最好,但是只支持简单的对象,不支持结构体,QJson 则不支持动态数组,不支持 Attributes (RTTI),比如需要过滤某个字段,自带和

Java序列化的几种方式以及序列化的作用

Java序列化的几种方式以及序列化的作用 本文着重讲解一下Java序列化的相关内容. 如果对Java序列化感兴趣的同学可以研究一下. 一.Java序列化的作用    有的时候我们想要把一个Java对象变成字节流的形式传出去,有的时候我们想要从一个字节流中恢复一个Java对象.例如,有的时候我们想要 把一个Java对象写入到硬盘或者传输到网路上面的其它计算机,这时我们就需要自己去通过java把相应的对象写成转换成字节流.对于这种通用 的操作,我们为什么不使用统一的格式呢?没错,这里就出现了java

关于Delphi XE2的FMX的一点点研究之消息篇

Delphi XE2出来了一阵子了,里面比较抢眼的东西,除了VCLStyle这个换肤的东西之外,另外最让人眼亮的应该是FMX这个东西了.万一的博客上都连载了一票的关于FMX的使用心得了.我还是没咋去关注,因为技术这个东西,天天在变,跟着他跑,俺伤不起啊!直到今天,看了一下盒子,然后群中也有人说关于FMX在Windows下面如何来发送消息的问题,说发送不了.实际上,FMX这个东西是一套跨平台机制的GUI类库,消息这个东西只是Windows下面的,所以发送消息这个说法应该不算通用.不过加以研究应该可

JSON.NET与LINQ序列化示例教程

1.手动创建JSON对象和数组 JSON格式主要包括对象和数组两种形式,在JSON.NET中分别用JArray和JObject表示,属性用JProperty表示,属性值用 JValue表示,这些对象都直接或间接继承JToken抽象类,而且都有一个ToString方法,该方法用于直接输出元素的JSON字符串表示形式, 我们可以通过JArray和JObject手动创建JSON并序列化,使用方式非常灵活. JArray array = new JArray(); array.Add("Manual t

JSON的解析和序列化

背景:XML曾经是互联网传输结构化数据的事实标准,但XML过于繁琐.冗长,而且解析麻烦,同XML数据结构要解析成DOM文档而且从中提取数据极为麻烦相比,JSON可以解析为JavaScript对象的优势极其明显.相比之下,JOSN是在JavaScript中读写结构化数据更好的方式,可以把JSON字符串直接传给eval(),而且不必创建DOM对象.JSON是一种数据格式,很多编程语言都有针对JOSN的解析器和序列化器. 一.JSON为JavaScript子集,可以使用eval解析JSON字符串,并返

Delphi XE2 生成的.exe 在未安装有Delphi的电脑上运行提示 “丢失 rtl160.bpl”

解决方案: XE2中加入了多平台的概念,默认的Release模式,也是带包编译,带运行时库的,所以,需要手工设置一下工程选项: 打开工程以后,Project-->Options-->左侧树列表选中C++ Linker-->右侧上方的Target选择Release configuration 下的 32-bit Windows platform-->取消 Link with Dynamic RTL 的对钩-->左侧树列表选中 Packages 下的 Runtime Packag

Newtonsoft.Json.4.5.0 序列化与反序列化json字符串使用方法总结

在VS里下载安装: Json.NET 5.0.6 http://www.nuget.org/packages/Newtonsoft.Json/5.0.6 反序列化json字符串为List: json字符串如下: 1 {"docs": [{ 2 "uid": 2629577, 3 "nickname": "枕边疯电台", 4 "is_v": "true", 5 "category

go调用其它C库,若采用命令行方式,不支持重定向的输出解决;smp协议未打开,发送信息到对方,没人响应

很多时候要学会站在巨人的肩膀上,该用别人 现有的东东一定要用,只要是开源合法的 go调用其它C库,一般两种方式,1,查看是否有接口,采用cgo方式编写:2.采用命令行直接执行,前提必须被调用的C库已经安装运行在该机器上 为了高效处理gif文件,采用gifsicle工具 http://download.csdn.net/detail/u010026901/7711469 重定向符合 > 在代码中会出错,所以在代码中实现重定向代替命令行重定向 package main import ( // "