Flutter анализирует сложные общие решения JSON

Flutter

проблема

Недавно я попробовал 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 для получения, затем вручную объяснить его в соответствии с типом, а позже обнаружил, что это невозможно.

мое решение

  1. Измените 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配置了
  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.В любом случае, я чувствую, что парсинг json в Dart немного полуавтоматический, я не знаю, что Google позже поймет требования разработчика, отпустит разрешения, или предоставит решение, или предоставит готовый пакет. Если это может быть похоже на Java Toolkit, такие как fastjson и Gson, они еще лучше, и их легко и приятно разрабатывать.

Вы можете прочитать статью о переводе, чтобы понять проблему синтаксического анализа всего json:[Перевод] Разбор сложного JSON во Flutter