You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Flutter调用Jikan API遇类型转换错误,请求排查解决

解决Flutter调用Jikan API获取Top动漫时的_CastError问题

错误原因

你遇到的_InternalLinkedHashMap<String, dynamic>' is not a subtype of type 'List?' in type cast错误,本质是Jikan的Top动漫API返回的不是直接的数组,而是一个包含data字段的JSON对象,直接把整个响应转为List会导致类型不匹配。

Jikan v4的Top动漫API响应结构示例:

{
  "data": [
    {"mal_id": 1, "title": "Fullmetal Alchemist: Brotherhood", ...},
    // 更多动漫数据
  ],
  "pagination": {...},
  "links": {...},
  "meta": {...}
}

常见错误代码示例

你大概率写了类似这样的代码,直接将整个响应转为List:

final response = await http.get(Uri.parse('https://api.jikan.moe/v4/top/anime'));
if (response.statusCode == 200) {
  // 这里直接转List会触发类型错误
  List<dynamic> topAnime = json.decode(response.body) as List;
}

修正后的基础代码

先把响应转为Map,再取出data字段对应的List:

import 'dart:convert';
import 'package:http/http.dart' as http;

Future<void> fetchTopAnime() async {
  final url = Uri.parse('https://api.jikan.moe/v4/top/anime');
  final response = await http.get(url);

  if (response.statusCode == 200) {
    // 第一步:将响应转为Map类型
    final Map<String, dynamic> responseMap = json.decode(response.body) as Map<String, dynamic>;
    // 第二步:取出data字段对应的List
    final List<dynamic> animeList = responseMap['data'] as List;

    // 遍历输出动漫标题示例
    for (final anime in animeList) {
      print('${anime['mal_id']}: ${anime['title']}');
    }
  } else {
    throw Exception('加载Top动漫失败,状态码:${response.statusCode}');
  }
}

进阶:类型安全的模型类处理

为避免手动类型转换出错,建议创建Anime模型类配合json_serializable包做序列化:

  1. 添加依赖到pubspec.yaml:
dependencies:
  json_annotation: ^4.8.1

dev_dependencies:
  build_runner: ^2.4.4
  json_serializable: ^6.7.0
  1. 创建anime.dart模型文件:
import 'package:json_annotation/json_annotation.dart';

part 'anime.g.dart';

@JsonSerializable()
class Anime {
  final int mal_id;
  final String title;
  @JsonKey(name: 'images')
  final Map<String, dynamic> imageData;

  Anime({
    required this.mal_id,
    required this.title,
    required this.imageData,
  });

  // 从JSON转模型
  factory Anime.fromJson(Map<String, dynamic> json) => _$AnimeFromJson(json);
  // 模型转JSON
  Map<String, dynamic> toJson() => _$AnimeToJson(this);

  // 快速获取封面图URL
  String get coverImage => imageData['jpg']['image_url'] as String;
}
  1. 运行命令生成序列化代码:
flutter pub run build_runner build
  1. 使用模型类的请求代码:
if (response.statusCode == 200) {
  final Map<String, dynamic> responseMap = json.decode(response.body) as Map<String, dynamic>;
  // 将data列表转为Anime模型列表
  final List<Anime> topAnime = (responseMap['data'] as List)
      .map((animeJson) => Anime.fromJson(animeJson))
      .toList();

  // 处理模型数据示例
  for (final anime in topAnime) {
    print('${anime.mal_id}: ${anime.title}');
    print('封面图:${anime.coverImage}');
  }
}

注意事项

  • 确认API版本:Jikan v4的响应结构包裹在data字段中,若使用v3版本结构会不同,建议优先使用v4 API。
  • 空值防护:实际开发中建议给responseMap['data']添加空值判断,避免空指针异常:
final List<dynamic>? animeList = responseMap['data'] as List?;
if (animeList != null) {
  // 处理列表逻辑
} else {
  throw Exception('API响应中未找到data字段');
}

内容的提问来源于stack exchange,提问作者Emre Isikgor

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.13 16:25:21