問題
最近在小試牛刀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接收,然後自己手動根據型別解釋,後面發現不得行啊。
我的解決方案
- 修改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配置了
複製程式碼
- 使用的時候
//使用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