草庐IT

json - 在 Flutter 上从 Youtube api 解码 Json

coder 2023-07-22 原文

我调用 Youtube API 并获取此 Json:

     "kind": "youtube#videoListResponse",
 "etag": "\"XI7nbFXulYBIpL0ayR_gDh3eu1k/s7-xmHXpuqQxYzDp_wxhm59K4LE\"",
 "pageInfo": {
  "totalResults": 1,
  "resultsPerPage": 1
 },
 "items": [
  {
   "kind": "youtube#video",
   "etag": "\"XI7nbFXulYBIpL0ayR_gDh3eu1k/pajQ7iBy-7A0V_owifxkw-Kbw-Y\"",
   "id": "7lCDEYXw3mM",
   "snippet": {
    "publishedAt": "2012-06-20T23:12:38.000Z",
    "channelId": "UC_x5XG1OV2P6uZZ5FSM9Ttw",
    "title": "Google I/O 101: Q&A On Using Google APIs",
    "description": "Antonio Fuentes speaks to us and takes questions on working with Google APIs and OAuth 2.0.",
    "thumbnails": {
     "default": {
      "url": "https://i.ytimg.com/vi/7lCDEYXw3mM/default.jpg",
      "width": 120,
      "height": 90
     },
     "medium": {
      "url": "https://i.ytimg.com/vi/7lCDEYXw3mM/mqdefault.jpg",
      "width": 320,
      "height": 180
     },
     "high": {
      "url": "https://i.ytimg.com/vi/7lCDEYXw3mM/hqdefault.jpg",
      "width": 480,
      "height": 360
     }

但现在我想解析它并只得到 3 个节点:

  1. 职位
  2. 描述
  3. 默认缩略图的 url

确实我得到了 Json 响应并且可以在日志中看到它,但是每次尝试解析它时都失败了。

这是我的代码:

final response = await http.get(
    'https://www.googleapis.com/youtube/v3/videos?id=HEREGOESMYAPIKEY&part=snippet&id=T0Jqdjbed40');

final parsed = json.decode(response.body).cast<Map<String, dynamic>>();
String title  = parsed['items']['snippet']['title'];
print(title);
String description  = parsed['items']['snippet']['description'];
print(description);
String thumbnail  = parsed['items']['snippet']['thumbnails']['default']['url'];
print(thumbnail);

最佳答案

您尝试的操作不适用于 Dart,这不是 javascript。 Dart 有非常强大的类型系统,这很棒。您正在尝试为定义为 String 的变量赋值,但您定义的响应是动态的,因此 Dart 无法验证赋值。 items 也是数组,没有这样的关键 items->snippet。

执行此操作的正确方法是创建模型定义,它将处理反序列化并提供方便的方式来访问您感兴趣的属性。

class YoutubeResponse {

  String kind;
  String etag;
  String nextPageToken;

  String regionCode;
  List<Item> items;

  YoutubeResponse(
      {this.kind,
      this.etag,
      this.nextPageToken,
      this.regionCode,
      this.items});

  Map<String, dynamic> toJson() => {
        'kind': kind,
        'etag': etag,
        'nextPageToken': nextPageToken,
        'regionCode': regionCode,
        'items': items,
      };

  factory YoutubeResponse.fromJSON(Map<String, dynamic> YoutubeResponseJson) {

    var list = YoutubeResponseJson['items'] as List;
    List<Item> itemsList = list.map((i) => Item.fromJSON(i)).toList();

    return new YoutubeResponse(
        kind: YoutubeResponseJson['kind'],
        etag: YoutubeResponseJson['etag'],
        nextPageToken: YoutubeResponseJson['nextPageToken'],
        regionCode: YoutubeResponseJson['regionCode'],
        mPageInfo: pageInfo.fromJSON(YoutubeResponseJson['pageInfo']),
        items: itemsList);
  }

}

class Item {
  String kind;
  String etag;
  Id id;
  Snippet snippet;

  Item({this.kind, this.etag, this.id, this.snippet});

  Map<String, dynamic> toJson() => {
        'kind': kind,
        'etag': etag,
        'id': id,
        'snippet': snippet,
      };

  factory Item.fromJSON(Map<String, dynamic> ItemJson) {
    return Item(
      kind: ItemJson['kind'],
      etag: ItemJson['etag'],
      id: Id.fromJSON(ItemJson['id']),
      snippet: Snippet.fromJSON(ItemJson['snippet']),
    );
  }
}

class Snippet {
  String publishedAt;
  String channelId;
  String title;
  String description;
  Thumbnails thumbnails;
  String channelTitle;
  String liveBroadcastContent;

  Snippet(
      {this.publishedAt,
      this.channelId,
      this.title,
      this.description,
      this.thumbnails,
      this.channelTitle,
      this.liveBroadcastContent});


  Map<String, dynamic> toJson() => {
        'publishedAt': publishedAt,
        'channelId': channelId,
        'title': title,
        'description': description,
        'thumbnails': thumbnails,
        'channelTitle': channelTitle,
        'liveBroadcastContent': liveBroadcastContent,
      };

  factory Snippet.fromJSON(Map<String, dynamic> SnippetJson) {


    return Snippet(
      publishedAt: SnippetJson['publishedAt'],
      channelId: SnippetJson['channelId'],
      title: SnippetJson['title'],
      description: SnippetJson['description'],
      thumbnails:  Thumbnails.fromJSON(SnippetJson['thumbnails']) ,
      channelTitle: SnippetJson['channelTitle'],
      liveBroadcastContent: SnippetJson['liveBroadcastContent'],
    );
  }
}

class Medium {
  int height;
  int width;
  String url;

  Medium({this.height, this.width, this.url});

  Map<String, dynamic> toJson() => {
        'height': height,
        'width': width,
        'url': url,
      };

  factory Medium.fromJSON(Map<String, dynamic> MediumJson) {
    return Medium(
      height: MediumJson['height'],
      width: MediumJson['width'],
      url: MediumJson['url'],
    );
  }

}

class High {
  int height;
  int width;
  String url;

  High({this.height, this.width, this.url});

  Map<String, dynamic> toJson() => {
        'height': height,
        'width': width,
        'url': url,
      };

  factory High.fromJSON(Map<String, dynamic> HighJson) {
    return High(
      height: HighJson['height'],
      width: HighJson['width'],
      url: HighJson['url'],
    );
  }

}

class Default {
  int height;
  int width;
  String url;

  Default({this.height, this.width, this.url});

  Map<String, dynamic> toJson() => {
        'height': height,
        'width': width,
        'url': url,
      };

  factory Default.fromJSON(Map<String, dynamic> defaultJson) {
    return Default(
      height: defaultJson['height'],
      width: defaultJson['width'],
      url: defaultJson['url'],
    );
  }

}

class Thumbnails {
  Default mDefault;
  Medium medium;
  High high;

  Thumbnails({this.mDefault, this.medium, this.high});

  var data = JsonEncoder().convert("");

  Map<String, dynamic> toJson() => {
        'default': mDefault,
        'medium': medium,
        'high': high,
      };

  factory Thumbnails.fromJSON(Map<String, dynamic> ThumbnailsJson) {
    return Thumbnails(
      mDefault: Default.fromJSON(ThumbnailsJson['default']),
      medium: Medium.fromJSON(ThumbnailsJson['medium']),
      high: High.fromJSON(ThumbnailsJson['high']),
    );
  }
}

既然我们已经描述了 JSON 的格式,我们希望它很容易解析:

YoutubeResponse parsedResponse =
  YoutubeResponse.fromJSON(json.decode(response.body));

然后您可以通过 parsedResponse.items 访问项目,然后遍历它们并获取标题、描述等。

关于json - 在 Flutter 上从 Youtube api 解码 Json,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/53253169/

有关json - 在 Flutter 上从 Youtube api 解码 Json的更多相关文章

  1. ruby-on-rails - Rails HTML 请求渲染 JSON - 2

    在我的Controller中,我通过以下方式在我的index方法中支持HTML和JSON:respond_todo|format|format.htmlformat.json{renderjson:@user}end在浏览器中拉起它时,它会自然地以HTML呈现。但是,当我对/user资源进行内容类型为application/json的curl调用时(因为它是索引方法),我仍然将HTML作为响应。如何获取JSON作为响应?我还需要说明什么? 最佳答案 您应该将.json附加到请求的url,提供的格式在routes.rb的路径中定义。这

  2. ruby-on-rails - 如何使用 Rack 接收 JSON 对象 - 2

    我有一个非常简单的RubyRack服务器,例如:app=Proc.newdo|env|req=Rack::Request.new(env).paramspreq.inspect[200,{'Content-Type'=>'text/plain'},['Somebody']]endRack::Handler::Thin.run(app,:Port=>4001,:threaded=>true)每当我使用JSON对象向服务器发送POSTHTTP请求时:{"session":{"accountId":String,"callId":String,"from":Object,"headers":

  3. ruby - 用 YAML.load 解析 json 安全吗? - 2

    我正在使用ruby2.1.0我有一个json文件。例如:test.json{"item":[{"apple":1},{"banana":2}]}用YAML.load加载这个文件安全吗?YAML.load(File.read('test.json'))我正在尝试加载一个json或yaml格式的文件。 最佳答案 YAML可以加载JSONYAML.load('{"something":"test","other":4}')=>{"something"=>"test","other"=>4}JSON将无法加载YAML。JSON.load("

  4. ruby-on-rails - Rails 渲染带有驼峰命名法的 json 对象 - 2

    我在一个简单的RailsAPI中有以下Controller代码:classApi::V1::AccountsControllerehead:not_foundendendend问题在于,生成的json具有以下格式:{id:2,name:'Simpleaccount',cash_flows:[{id:1,amount:34.3,description:'simpledescription'},{id:2,amount:1.12,description:'otherdescription'}]}我需要我生成的json是camelCase('cashFlows'而不是'cash_flows'

  5. ruby - 使用 JSON gem 将自定义对象转换为 JSON - 2

    我正在学习如何使用JSONgem解析和生成JSON。我可以轻松地创建数据哈希并将其生成为JSON;但是,在获取一个类的实例(例如Person实例)并将其所有实例变量放入哈希中以转换为JSON时,我脑袋放屁。这是我遇到问题的例子:require"json"classPersondefinitialize(name,age,address)@name=name@age=age@address=addressenddefto_jsonendendp=Person.new('JohnDoe',46,"123ElmStreet")p.to_json我想创建一个.to_json方法,这样我就可以获

  6. ruby-on-rails - 如何使用驼峰键名称从 Rails 返回 JSON - 2

    我正在构建一个带有Rails后端的JS应用程序,为了不混淆snake和camelcases,我想通过从服务器返回camelcase键名来规范化这一切。因此,当从API返回时,user.last_name将返回user.lastName。我如何实现这一点?谢谢!编辑:添加Controller代码classApi::V1::UsersController 最佳答案 我的方法是使用ActiveModelSerializer和json_api适配器:在你的Gemfile中,添加:gem'active_model_serializers'创建

  7. ruby-on-rails - 如何将数组输出为 JSON? - 2

    我有以下内容:@array.inspect["x1","x2","adad"]我希望能够将其格式化为:client.send_message(s,m,{:id=>"x1",:id=>"x2",:id=>"adad"})client.send_message(s,m,???????)如何在????????中获得@array输出?空间作为ID?谢谢 最佳答案 {:id=>"x1",:id=>"x2",:id=>"adad"}不是有效的散列,因为您有键冲突它应该是这样的:{"ids":["x1","x2","x3"]}更新:@a=["x1

  8. ruby - 使用 jbuilder 创建具有动态哈希键的 JSON - 2

    这里我想输出带有动态组名的json而不是单词组@tickets.eachdo|group,v|json.group{json.array!vdo|ticket|json.partial!'tickets/ticket',ticket:ticketend}end@ticket是这样的散列{a:[....],b:[.....]}我想要这样的输出{a:[.....],b:[....]} 最佳答案 感谢@AntarrByrd,这个问题有类似的答案:JBuilderdynamickeysformodelattributes使用上面的逻辑我已经

  9. ruby - 展平嵌套的 json 对象 - 2

    我正在寻找一种将“json”散列展平为展平散列但将路径信息保留在展平键中的方法。例如:h={"a"=>"foo","b"=>[{"c"=>"bar","d"=>["baz"]}]}flatten(h)应该返回:{"a"=>"foo","b_0_c"=>"bar","b_0_d_0"=>"baz"} 最佳答案 这应该可以解决您的问题:h={'a'=>'foo','b'=>[{'c'=>'bar','d'=>['baz']}]}moduleEnumerabledefflatten_with_path(parent_prefix=nil)

  10. ruby-on-rails - 如何计算 Ruby/Rails 中 JSON 对象的数量 - 2

    Ruby中如何“一般地”计算以下格式(有根、无根)的JSON对象的数量?一般来说,我的意思是元素可能不同(例如“标题”被称为其他东西)。没有根:{[{"title":"Post1","body":"Hello!"},{"title":"Post2","body":"Goodbye!"}]}根包裹:{"posts":[{"title":"Post1","body":"Hello!"},{"title":"Post2","body":"Goodbye!"}]} 最佳答案 首先,withoutroot代码不是有效的json格式。它将没有包

随机推荐