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

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

  1. SpringBoot-08:SpringBoot采用json的方式实现前后台通用的配置文件

    ------------吾亦无他,唯手熟尔,谦卑若愚,好学若饥------------- 一.需求: 本篇博客是最近笔者做的一个项目,已经上线但是还在不断开发,有些页面上的配置,测试服务器和正式服务器 ...

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

    1.项目截图 2.黑白打印机类 package com.example.demo.printer; public class GrayPrinter implements Printer{ @Over ...

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

    今天在盒子闲逛,无意中看到有人说XE7自带的Json对象序列化很慢,帖子在这里:http://bbs.2ccc.com/topic.asp?topicid=464378;经过测试的确如此.     但 ...

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

    Java序列化的几种方式以及序列化的作用 本文着重讲解一下Java序列化的相关内容. 如果对Java序列化感兴趣的同学可以研究一下. 一.Java序列化的作用    有的时候我们想要把一个Java对象 ...

  5. Newtonsoft.Json高级用法DataContractJsonSerializer,JavaScriptSerializer 和 Json.NET即Newtonsoft.Json datatable,dataset,modle,序列化

    原文地址:https://www.cnblogs.com/yanweidie/p/4605212.html Newtonsoft.Json介绍 在做开发的时候,很多数据交换都是以json格式传输的.而 ...

  6. C#三种方式实现序列化(转)

    序列化和反序列化我们可能经常会听到,其实通俗一点的解释,序列化就是把一个对象保存到一个文件或数据库字段中去,反序列化就是在适当的时候把这个文件再转化成原来的对象使用. 序列化和反序列化最主要的作用有: ...

  7. WebApi2官网学习记录---JSON与XML的序列化

    JSON序列化: WebAPI的默认序列库使用的是Json.NET,可以在Globally中配置使用DataContractJsonSerializer 进行序列化 protected void Ap ...

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

    Delphi XE2出来了一阵子了,里面比较抢眼的东西,除了VCLStyle这个换肤的东西之外,另外最让人眼亮的应该是FMX这个东西了.万一的博客上都连载了一票的关于FMX的使用心得了.我还是没咋去关 ...

  9. 小白的Python之路 day4 json and pickle数据标准序列化

    一.简述 我们在写入文件中的数据,只能是字符串或者二进制,但是要传入文件的数据不一定全是字符串或者二进制,那还要进行繁琐的转换,然后再读取的时候,还要再转回去,显得很麻烦,今天就来学习标准的序列化:j ...

随机推荐

  1. 一入Python深似海--print

    先给大家来个干货^~^,学习Python的一个好站点,http://learnpythonthehardway.org/book/ 经典样例 以下是几个老经典的样例喽,刚接触Python的能够敲一敲, ...

  2. 电子商务系统的设计与实现(七):前后端系统UI设计的一些思考

    对于大部分开发者来说,写界面是最烦人的事.我想,开发者最初诞生,以及我们在大学学习的时候,更加侧重的是程序设计和逻辑思维,而不是界面.界面更象是艺术,艺术和程序设计是两回事. 我个人还是想成为全栈式开 ...

  3. 自动化部署脚本,给每一台主机装上JDK,且配好环境变量

    centos6.7 当我们有很多台主机,想在每台机器上都安装一样的某些软件,当然,一台机器一台机器安装也是可以的,但是如果有一键安装所有机器上的软件那是不是很激动人心呢! 首先我们需要制作一台服务器, ...

  4. 12个被滥用的Android应用程序权限

    Android应用程序须要权限才干正常运作,只是网络犯罪分子会将其用在个人私利上.来看看最常被要求的权限以及它们会怎样被滥用. .网络定位功能 这代表什么:同意应用程序通过网络定位(像是基地台或无线网 ...

  5. poj1639 Picnic Planning,K度限制生成树

    题意: 矮人虽小却喜欢乘坐巨大的轿车,车大到能够装下不管多少矮人.某天,N(N≤20)个矮人打算到野外聚餐.为了集中到聚餐地点,矮人A 要么开车到矮人B 家中,留下自己的轿车在矮人B 家,然后乘坐B ...

  6. cordova打包之android应用签名

    原文:cordova打包之android应用签名 版权声明:本文为博主原创文章,未经博主允许不得转载. https://blog.csdn.net/mate_ge/article/details/78 ...

  7. markdownpad 2 的使用

    1. 注册 邮箱:Soar360@live.com 授权秘钥: GBPduHjWfJU1mZqcPM3BikjYKF6xKhlKIys3i1MU2eJHqWGImDHzWdD6xhMNLGVpbP2M ...

  8. WPF的逻辑树与视觉树(3)Visual呈现

    原文:WPF的逻辑树与视觉树(3)Visual呈现 这篇就点到为止,挑重点讲 绘图方式有两种 1.继承UIElement,重写OnRender方法 public partial class Windo ...

  9. VSCode 小鸡汤 第00期 —— 安装和入门

    简介 这将是一个新的系列,将会以 Visual Studio Code(后文都简称为 VSCode 啦)的操作,环境配置,插件介绍为主,为大家不定期的介绍 VSCode 的一些操作技巧,所以取名 VS ...

  10. Leetcode dfs Combination Sum

    Combination Sum Total Accepted: 17319 Total Submissions: 65259My Submissions Given a set of candidat ...