我的RCP客户端未返回对象的深层副本

时间:2016-03-22 19:03:34

标签: json dart rpc

我一直在研究RCP客户端来处理天气数据。

我做的是两件事,首先我把我将要使用的JSON刮掉并放入飞镖文件中。请参阅:https://dartpad.dartlang.org/a9c1fe8ce34c608eaa28

我的server.dart页面将导入天气数据,然后执行以下操作:

import "dart:io";
import "weather_data.dart";
import "dart:convert";
import "package:rpc/rpc.dart";

find ApiServer _apiServer = new ApiServer(prettyPrint:true);
main() async {
  Weather w = new Weather(WeatherJson);
  TestServer ts = new TestServer(w);
  _apiServer.addApi(ts);
  HttpServer server = await HttperServer.bind(InternetAddress.ANY_IP_V4, 12345);
  server.listen(_apiServer.httpRequestHandler);
}

class Weather{
  Map weather;
  Weather(this.weather){
    Map get daily => weather["daily"];
  }
}

@ApiClass(name:"test_server", version: 'v1', description: 'This is a test server api to ping for some quick sample data.')
class TestServer {
  Weather myWeather;
  TestServer(this.myWeather){

  }

  @ApiMethod(method:'GET', path: 'daily')
  Map<String, Object> getDaily(){
    return myWeather.daily;
  }
}

因此,服务器正常启动,我将转到localhost:12345/test_server/v1/daily,它将返回此信息:

{
 "summary": {},
 "icon": {},
 "data": {}
}

这是不正确的。如果查找JSON数据,摘要和图标都是字符串,数据是数组。它们也是空的,应该包含我想要返回的数据。

为什么会这样?是因为我要归还Map<String, Object>吗?我试图把它设置为:Map<String, dynamic>但是dart编译器不喜欢它。

如何获取此数据以返回正确的数据集?

RPC的Dart网站位于:https://github.com/dart-lang/rpc 你可以看到,在方法下,方法的返回值可以是类的实例,也可以是future。这是正常的,所以我把它设置为Map<String,Object>虽然试图模糊地说:Map是不够的。

修改

当这种情况主要在没有RPC的飞镖垫中进行时,似乎可以通过以下样本正常工作:https://dartpad.dartlang.org/3f6dc5779617ed427b75

这让我相信Parsing工具有问题,因为dartpad中的返回类型似乎允许返回MapMap<String, Object>Map<String, dynamic>

2 个答案:

答案 0 :(得分:2)

快速查看这里的RPC包README https://pub.dartlang.org/packages/rpc,标记为Api方法(使用@ApiMethod)的方法似乎应该返回一个具有简单字段的类的实例,例如:

class ResourceMessage {
  int id;
  String name;
  int capacity;
}

RPC包将采用该实例并根据字段名称将其序列化为JSON。

来自自述文件:

  

MyResponse类必须是具有未命名的非抽象类   构造函数不需要参数。 RPC后端会   自动序列化MyResponse的所有公共字段   实例进入JSON ......

您正在返回希望RPC操作发出的JSON的嵌套Map 表示,并且会猜测RPC包没有像您期望的那样处理它。< / p>

回答:你的问题:

  

这让我相信解析工具有问题   似乎dartpad中的返回类型允许返回Map,Map和Map。

没有&#39;解析&#39;关于JSON继续你的例子。您拥有的数据是一组嵌套的文字Dart MapListString,其结构与从中派生的JSON相同。它碰巧看起来像JSON。

在您的示例中,您只是选择并打印数据地图的子地图(data['daily']),该地图打印出调用String产生的toString() - 这是递归的所以你可以获得其中所有嵌套地图和列表的内容。

所以它不是一个很深的副本&#39;问题,但toString()和RPC代码处理一组嵌套映射的方式不同。

BTW:getDaily()方法的返回类型并不重要。无论方法的声明返回类型是什么,返回的只是Map。记住Dart中的类型是可选的,编辑器和编译器可以找到可能不正确的代码。请参阅https://www.dartlang.org/docs/dart-up-and-running/ch02.html#variables

答案 1 :(得分:0)

我将在这里搭载@Argenti Apparatus,因为他从中获得了大量信息。

长话短说,方法所需的返回类型:

@ApiMethod(method:'GET', path: 'daily')
Map<String,Object> getDaily(){       // <-- Map<String,Object>
  return myWeather.daily;
}

是错误。

我经历过并将方法签名更新为Map<String,String>,并将其解析为完全正确。它没有将对象解析为字符串,但实际上将其解析为完整的递归对象。

我经历过,为了代码清洁,还改变了天气属性的签名以反映它们实际上的内容,Map<String,Object>

总而言之,当将它定义为Object的值类型时,它返回花括号,但将其设置为String正确解析它。

我通过JSLint运行它以确认它也是正确的。

我给了助手一个+1,我不得不深入研究代码,看为什么它没有正确地做Map。

我觉得这也是RPC Dart中的一个错误。