проблема
Недавно я попробовал Flutter, небольшой инструмент, и в основном занимался изучением и версткой пользовательского интерфейса, управлением данными 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 могут быть разных типов: List, Map, int, String, array и т. д. В любом случае, это данные результата, возвращаемые сервером, и тип не может быть определен. Моя предыдущая идея была использовать String для получения, затем вручную объяснить его в соответствии с типом, а позже обнаружил, что это невозможно.
мое решение
- Измените ResponseD, чтобы он был универсальным
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.В любом случае, я чувствую, что парсинг json в Dart немного полуавтоматический, я не знаю, что Google позже поймет требования разработчика, отпустит разрешения, или предоставит решение, или предоставит готовый пакет. Если это может быть похоже на Java Toolkit, такие как fastjson и Gson, они еще лучше, и их легко и приятно разрабатывать.
Вы можете прочитать статью о переводе, чтобы понять проблему синтаксического анализа всего json:[Перевод] Разбор сложного JSON во Flutter