我一直在研究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中的返回类型似乎允许返回Map
,Map<String, Object>
和Map<String, dynamic>
。
答案 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 Map
,List
和String
,其结构与从中派生的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中的一个错误。