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

Flutter从JSON数据创建列表遇类型转换错误求助

解决JSON转List<User>的类型不匹配问题

问题根源

你遇到的错误核心在于两个点:

  1. JSON结构不匹配:你的返回JSON外层是Map<String, dynamic>(包含user键的对象),但你直接把整个解码结果当成List强制转换,自然会触发类型不匹配错误;
  2. 模型类设计偏差:你的Phone类只定义了单个User对象,但JSON里user对应的是一个用户数组,结构完全不对。

第一步:修正模型类

我们需要调整模型来贴合JSON结构,这里提供两种实用方案:

方案1:直接使用User类(简化版)

既然最终要的是用户列表,可以直接复用User类,补充JSON里存在的字段:

class User {
  String email;
  String password;
  String username;
  int id;

  User({this.email, this.password, this.username, this.id});

  // 从JSON解析为User对象
  factory User.fromJson(Map<String, dynamic> json) {
    return User(
      email: json['email'],
      password: json['password'],
      username: json['username'],
      id: json['id'],
    );
  }

  // 可选:将User对象转回JSON(如果需要序列化)
  Map<String, dynamic> toJson() {
    return {
      'email': email,
      'password': password,
      'username': username,
      'id': id,
    };
  }
}

方案2:创建响应包裹类(规范REST API风格)

如果想严格对应整个JSON的外层结构,可以创建一个包裹类:

// 对应整个JSON的外层结构
class UserResponse {
  List<User> users;

  UserResponse({this.users});

  factory UserResponse.fromJson(Map<String, dynamic> json) {
    // 取出user对应的数组,转成List<User>
    var userList = json['user'] as List;
    List<User> userItems = userList.map((item) => User.fromJson(item)).toList();
    
    return UserResponse(users: userItems);
  }
}

// User类同方案1
class User {
  String email;
  String password;
  String username;
  int id;

  User({this.email, this.password, this.username, this.id});

  factory User.fromJson(Map<String, dynamic> json) {
    return User(
      email: json['email'],
      password: json['password'],
      username: json['username'],
      id: json['id'],
    );
  }

  Map<String, dynamic> toJson() {
    return {
      'email': email,
      'password': password,
      'username': username,
      'id': id,
    };
  }
}

第二步:修正getData()方法

根据你选的模型方案,调整数据解析逻辑:

如果用方案1(直接返回List<User>):

Future<List<User>> getData() async {
  try {
    http.Response response = await http.get(
      Uri.parse("http://chicken20.pythonanywhere.com/user"),
      headers: {"Accept": "application/json"},
    );

    // 先解码为Map,取出user对应的数组
    Map<String, dynamic> responseData = json.decode(response.body);
    List<dynamic> userRawList = responseData['user'];
    
    // 转换为List<User>
    List<User> users = userRawList.map((data) => User.fromJson(data)).toList();
    
    return users;
  } catch (e) {
    // 捕获异常,避免崩溃,可根据需求处理
    print('请求或解析错误:$e');
    return [];
  }
}

如果用方案2(返回包裹类):

Future<UserResponse> getData() async {
  try {
    http.Response response = await http.get(
      Uri.parse("http://chicken20.pythonanywhere.com/user"),
      headers: {"Accept": "application/json"},
    );

    Map<String, dynamic> responseData = json.decode(response.body);
    UserResponse userResponse = UserResponse.fromJson(responseData);
    
    return userResponse;
  } catch (e) {
    print('请求或解析错误:$e');
    return UserResponse(users: []);
  }
}

// 使用示例:
// UserResponse response = await getData();
// List<User> users = response.users;

额外小提示

  • 推荐用Uri.parse替代Uri.encodeFull,前者更适配HTTP URL的解析逻辑;
  • 一定要加异常捕获,避免网络请求失败或JSON格式异常导致APP崩溃;
  • 模型类的字段要和JSON的键完全对应,比如你JSON里的username和id,之前的User类没包含,必须补上否则数据会丢失。

内容的提问来源于stack exchange,提问作者wajdi hassyaoui

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.08 09:22:44