问题
最近在小试牛刀Flutter,基本搞了UI的学习和布局,Redux的数据管理以及异步请求,最近这两天陷入了一个JSON解析的问题上面 ,本来,我以为很简单,我是从Java过来的,Java已经有了各种的JSON解析jar包,好用到非常。我就想Dart是Google推出来的东西,肯定是已经完美的解决了JSON解析的各种问题,即使没有完美解决,那肯定有工具包能解决,后来发现不是那么回事。 下面是我的Http请求返回的结果对象
class ResponseDto{
int code;
String message;
String data;
ResponseDto({this.code, this.message, this.data});
factory ResponseDto.fromJson(Map<String, dynamic> json) {
return ResponseDto(
code: json['code'],
message: json['message'],
data: json['data'],
);
}
}
我的想法是,给ResponseDto一个泛型,然后用dart:convert加上json_serializable就可以顺理成章的搞定了,后来发现不是那么回事,反正是得手动,因为dart不让你用反射. 但是在解析过程中会出现:
type 'List<dynamic>' is not a subtype of type 'List<String>'
而且我这个ResponseDto的属性data有可能是各种类型:List,Map,int,String,数组,其他对象,反正是服务端返回的结果数据,不能定死类型,我之前的想法是用String接收,然后自己手动根据类型解释,后面发现不得行啊。
我的解决方案
1、 修改ResponseDto为泛型
class ResponseDto<T> {
int code;
String message;
T data;
ResponseDto({this.code, this.message, this.data});
factory ResponseDto.fromJson(Map<String, dynamic> json) {
return ResponseDto(
code: json['code'],
message: json['message'],
data: json['data'],
);
}
}
ResponseDto就不要使用json_serializable配置了
1、 使用的时候
//使用Dart内置的http请求服务端数据
var response = await http.get(RemoteServerConfig.remoteRoot + "/api/rattrap/ancient-article/article-type/types");
//ResponseDto的data为List数据结构的时候,使用这个泛型类型:List<dynamic>
List<dynamic> list = ResponseDto<List<dynamic>>.fromJson(json.decode(response.body)).data);
解析成自己需要的类型
class LoadChineseAncientArticleTypeAction {
List<ChineseAncientArticleTypeDto> typeDtoList;
LoadChineseAncientArticleTypeAction({this.typeDtoList});
factory LoadChineseAncientArticleTypeAction.create(List<dynamic> jsonData) {
var types = jsonData
.map((typeJson) => ChineseAncientArticleTypeDto.fromJson(typeJson))//解析成需要的类型
.toList();
return LoadChineseAncientArticleTypeAction(typeDtoList: types);
}
}
create方法传入上面获取到的List<dynamic>对象即可
如果返回的是一个对象
var data = ResponseData<dynamic>.fromJson(json.decode(response.body)).data;
之后用你的 接收对象的fromJson方法就行了
总结
注意response.body是String类型 反正感觉Dart这个json解析有点半自动的感觉,不知道后面Google会体会到开发者的诉求,放开权限,或者提供一个解决方案,在或者提供一个现成的package那就更完美了.如果可以像Java的fastjson、Gson那样的工具包就更加好了,开发起来轻松愉悦.
有一篇翻译文章可以看下,了解整个json的解析问题:[译]在 Flutter 中解析复杂的 JSON