You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

RAD Server Delphi中savetostream/loadfromstream因JSON转换元音变音失效问题

问题根源

报错核心是TStringStream默认编码与FireDAC JSON序列化/反序列化要求的UTF-8编码不匹配,中间的字符串隐式转换破坏了原始UTF-8字节结构:

  1. FireDAC的SaveToStream(sfJSON)输出为标准UTF-8编码字节流
  2. 无参数创建的TStringStream默认使用系统当前ANSI编码,读取UTF-8字节时会错误转码,导致变音字符编码异常、JSON结构被破坏
  3. 客户端直接读取Response.Content得到的是已经被EMS框架按默认编码转码后的字符串,原始UTF-8字节已经被污染,后续转码必然出现字符丢失或JSON结构损坏

可行解决方案

方案1:全链路直接使用字节流(最稳妥,无多余编码转换)

服务端修改

改用无编码属性的TMemoryStream承接FireDAC输出的原始JSON字节,避免隐式转码:

var lStream: TMemoryStream := TMemoryStream.Create;
try
  FDQuery.SaveToStream(lStream, sfJSON);
  lStream.Position := 0; // 必须重置流指针到起始位置
  // Content-Type加charset=utf-8声明,避免中间代理或框架乱转码
  AResponse.Body.SetStream(lStream, 'application/json; charset=utf-8', True);
except
  lStream.Free;
  raise;
end;
客户端修改

不要读取Response.Content字符串,直接拿响应的原始字节流加载到FDMemTable:

// 直接使用响应的原始ContentStream,不需要额外转码
var lStream := EMSBackendEndpoint.Response.ContentStream;
lStream.Position := 0;
aMemtable.LoadFromStream(lStream, sfJSON);

如果EMS客户端框架取不到ContentStream,用原始字节数组构造流即可:

var lBytes: TBytes := EMSBackendEndpoint.Response.ContentAsBytes;
var lStream: TBytesStream := TBytesStream.Create(lBytes);
try
  lStream.Position := 0;
  aMemtable.LoadFromStream(lStream, sfJSON);
finally
  lStream.Free;
end;

方案2:保留TStringStream使用,全链路明确指定UTF-8编码

如果业务逻辑需要保留字符串处理环节,所有TStringStream创建时必须明确指定UTF-8编码:

服务端修改
var lStream: TStringStream := TStringStream.Create('', TEncoding.UTF8);
try
  FDQuery.SaveToStream(lStream, sfJSON);
  lStream.Position := 0;
  AResponse.Body.SetStream(lStream, 'application/json; charset=utf-8', True);
except
  lStream.Free;
  raise;
end;
客户端修改
var lStream: TStringStream := TStringStream.Create(EMSBackendEndpoint.Response.Content, TEncoding.UTF8);
try
  lStream.Position := 0;
  aMemtable.LoadFromStream(lStream, sfJSON);
finally
  lStream.Free;
end;

内容的提问来源于stack exchange,提问作者fisi-pjm

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.09.29 19:45:02