【发布时间】:2014-08-19 10:17:36
【问题描述】:
这个问题来自"DataSnap return empty dataset" 我认为这是另一个问题,所以我在这里创建一个新线程。
我编写了一个 DataSnap 休息服务器,它返回一个带有 TDateTime 字段的数据集。
function TServerMethods1.GetDataSet: TDataset;
begin
FDQuery1.SQL.Clear;
FDQuery1.SQL.Text := 'select EmployeeID, LastName, FirstName, BirthDate from Employees';
FDQuery1.Open();
Result := FDQuery1;
end;
但是我的 android 客户端 (Java) 无法解析从服务器获取的日期时间值。
我从服务器跟踪Json数据,发现TDatetime类型值:
"BirthDate":["1948-12-08.0","1952-02-19.0","1963-08-30.0"]
每个日期值都附加一个“.0”尾部。所以,Java 无法转换回 Date 类型:
然后,我添加一个新的服务器方法来测试返回 TDateTime 类型:
function TServerMethods1.GetDateTime: TDateTime;
begin
Result := int(Now);
end;
DataSnap 也把它放到了下面的样式中:
{"result":["2014-06-27.0"]}
那么,如何修复 Java 客户端中的这个 bug?
[更新,临时解决方案]----------
@BasilBourque,谢谢。你给了我一些灵感。我认为如果替换 Java 类或类库是一个很大的工作量。所以我选择了一个简单的解决方案。
现在,我修复了 DataSnap 服务器自动生成的 Java 代码文件“DBXDefaultFormatter.java”。
DBXDefaultFormatter.java,第 257 行, 原代码:
public Date StringToDateTime(String value) throws ParseException {
return datetimeFormatter.parse(value);
}
固定代码:
public Date StringToDateTime(String value) throws ParseException {
if ((value.length() == 12) & (value.endsWith(".0"))) {
return dateFormatter.parse(value);
} else {
return datetimeFormatter.parse(value);
}
}
我知道,这不是一个完美的解决方案,但基本上就足够了。
【问题讨论】:
-
这看起来像
datasnap中的一个错误。.0是否意味着什么? -
@PeterLawrey,这不是错误。结果类型为 TDateTime,因此 .0 表示该值的时间分数。要获取日期,只需将结果类型声明为 TDate。关于数据集,必须选择适当的字段类型来仅表示日期值(取决于数据库)。
-
@UweRaabe 为什么 DataSnap 在将 TDateTime 序列化为 JSON 时不使用 ISO-8601 文本编码,或者使用相应双精度变量的纯浮点值进行传输?如果它“不是错误,而是功能”,对我来说听起来像是一个非常误解的功能。
-
@Uwe Raabe,1. DataSnap 无法导出(ProxyGenerator)TDate 或 TTime 类型。我们在使用 TDatetime 时会遇到类似的“2014-06-28 00:00:00”数据。 Delphi客户端可以解析它,但java不能。 2.我们不能改变Table Field类型来适应这个问题,这不是一个明智的解决方案。 3.我认为最好的解决方案是改变DataSnap输出的json内容,或者让Java可以接受json内容。但是,我仍然无法找出修复条目。
-
您是否考虑过要求供应商 (RemObjects) 调查您的错误?