经过一个多星期的试用,DataSnap 让我感到很郁闷。
今天又遇到一个问题,
我的 Android(Java) 客户端需要从 DataSnap Server(XE6) 获取数据集,但服务器返回一个空结果:
{“结果”:[{“表格”:[]}]}
这是服务器代码:
function TServerMethods1.GetDataset(cmdstr: string): TDBXReader;
var
CMD: TDBXCommand;
begin
SQLConnection1.Open;
CMD := SQLConnection1.DBXConnection.CreateCommand;
CMD.CommandType := TDBXCommandTypes.DbxSQL;
CMD.Text := cmdstr;
if not CMD.IsPrepared then
CMD.Prepare;
Result := CMD.ExecuteQuery;
CMD.Free; // If this line is commented out, it will memory leaks and return an exception.
end;
[更新 - - - - - - - - -]
今天我将数据库访问组件更改为 FireDAC:
{$METHODINFO ON}
TServerMethods1 = class(TDataModule)
Sqlite_demoConnection: TFDConnection;
FDQuery1: TFDQuery;
FDGUIxWaitCursor1: TFDGUIxWaitCursor;
FDPhysSQLiteDriverLink1: TFDPhysSQLiteDriverLink;
private
{ Private declarations }
public
{ Public declarations }
function EchoString(Value: string): string;
function ReverseString(Value: string): string;
function GetDataSet: TDataset;
end;
{$METHODINFO OFF}
function TServerMethods1.GetDataSet: TDataset;
begin
FDQuery1.SQL.Clear;
FDQuery1.SQL.Text := 'select EmployeeID, LastName, FirstName, BirthDate from Employees';
FDQuery1.Open();
Result := FDQuery1;
end;
Delphi 客户端可以得到结果并解析它。但 Java 客户端(Android)无法解析结果:
DSRESTConnection aConn = new DSRESTConnection();
DSProxy.TServerMethods1 aProxy = new DSProxy.TServerMethods1(conn);
aConn.setHost("192.168.0.240");
aConn.setPort(8080);
aConn.setProtocol("http");
try {
TDataSet rd = aProxy.GetDataSet();
int FieldCount = rd.getColumns().size();
Log.i("FieldCount:", String.valueOf(FieldCount)); // get 4
//rd.reset();
while (rd.next()) // rd.next() get exception and return false
{
Log.i("EmployeeID", rd.getValue("EmployeeID").GetAsString());
Log.i("LastName", rd.getValue("LastName").GetAsString());
}
} catch (DBXException e) {
e.printStackTrace();
}
更新 2--------------------
好的,我可以得到结果。谢谢MartynA 和J__。
我发现了为什么rd.next()返回 false:
从服务器返回的数据集,包括一个日期时间字段。DataSnap 将其转换为 json:
"BirthDate":["1948-12-08.0","1952-02-19.0","1963-08-30.0"]
每个日期值都附加一个“.0”尾部。因此,Java 无法转换回 Date 类型:
com.embarcadero.javaandroid.DBXException: Unparseable date: "1948-12-08.0" (at offset 10)
然后,我添加了一个新的服务器方法来测试返回 TDateTime 类型:
function TServerMethods1.GetDateTime: TDateTime;
begin
Result := int(Now);
end;
DataSnap 也把它变成了下面的样式:
{"result":["2014-06-27.0"]}
哦,我的上帝。如何解决这个问题?在服务器端?在客户端?