DELPHIXE2采⽤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;
json转换对象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 库⾥⾯的对象的⽅法,不太直观。
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。
发表评论