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

Flutter中使用FutureBuilder和Dio无法展示用户列表求助

Flutter中FutureBuilder+Dio加载用户列表失败的排查与解决

问题描述

在Flutter应用中使用FutureBuilder组件结合Dio库发起HTTP请求展示用户列表时,仅显示Failed to load user list提示,无法看到具体错误原因。已完成以下验证:

  • API地址正确且可正常访问
  • API返回数据格式合法有效
  • User类的fromJson反序列化方法逻辑正确

相关代码

UsersList组件代码

import 'package:flutter/material.dart';
import 'package:dio/dio.dart';
import 'dart:convert';

import 'package:larpland/model/user.dart';

class UsersList extends StatefulWidget {
  const UsersList({super.key});

  @override
  State<UsersList> createState() => _UsersListState();
}

class _UsersListState extends State<UsersList> {
  late Future<List<User>> futureUserList;

  @override
  void initState() {
    super.initState();
    futureUserList = fetchUserList();
  }

  @override
  Widget build(BuildContext context) {
    return FutureBuilder<List<User>>(
      future: futureUserList,
      builder: (context, snapshot) {
        if (snapshot.hasData) {
          return ListView.builder(
            itemCount: snapshot.data!.length,
            itemBuilder: (context, index) {
              return ListTile(
                title: Text(snapshot.data![index].name),
                subtitle: Text(snapshot.data![index].email),
              );
            },
          );
        } else if (snapshot.hasError) {
          return const Center(
            child: Text('Failed to load user list'),
          );
        }
        return const Center(
          child: CircularProgressIndicator(),
        );
      },
    );
  }

  Future<List<User>> fetchUserList() async {
    final response = await Dio().get('https://10.0.2.2:8000/api/users');
    if (response.statusCode == 200) {
      return List<User>.from(jsonDecode(response.data).map((user) => User.fromJson(user)));
    } else {
      throw Exception('Failed to fetch user list');
    }
  }
}

User模型代码

class User {
  final int id;
  final String name;
  final String email;
  final String password;
  final int rol;
   
  const User({
    required this.id,
    required this.name,
    required this.email,
    required this.password,
    required this.rol,
  });

  factory User.fromJson(Map<String, dynamic> json) {
    return switch (json) {
      {
        'id': int id,
        'name': String name,
        'email': String email,
        'password': String password,
        'rol': int rol,
      } =>
        User(
          id: id,
          name: name,
          email: email,
          password: password,
          rol: rol,
        ),
      _ => throw const FormatException('Failed to load users'),
    };
  }
}

排查与解决步骤

1. 先获取具体错误信息

当前错误提示过于笼统,修改FutureBuilder的错误分支,直接打印异常详情:

else if (snapshot.hasError) {
  return Center(
    child: Text('加载失败: ${snapshot.error.toString()}'),
  );
}

运行后即可看到具体错误类型(网络错误/序列化错误等),针对性排查。

2. 修正Dio响应解析逻辑

Dio默认会自动将JSON响应解析为Map或List,无需再调用jsonDecode,原代码的重复解析会导致类型错误,修改fetchUserList方法:

Future<List<User>> fetchUserList() async {
  final response = await Dio().get('https://10.0.2.2:8000/api/users');
  if (response.statusCode == 200) {
    // 直接使用response.data,无需jsonDecode
    return List<User>.from((response.data as List).map((user) => User.fromJson(user)));
  } else {
    throw Exception('请求失败: ${response.statusCode}');
  }
}

3. 兼容API返回字段的潜在问题

检查API返回字段是否与User类完全匹配:

  • 确认rol字段为数字类型,若API返回字符串需转为int
  • 若API可能不返回password字段,修改User类允许该参数为空:
// 修改User构造函数
const User({
  required this.id,
  required this.name,
  required this.email,
  this.password = '', // 设置默认值,转为可选参数
  required this.rol,
});

// 修改fromJson的switch表达式
factory User.fromJson(Map<String, dynamic> json) {
  return switch (json) {
    {
      'id': int id,
      'name': String name,
      'email': String email,
      'password': String? password, // 允许空值
      'rol': int rol,
    } =>
      User(
        id: id,
        name: name,
        email: email,
        password: password ?? '', // 空值时用默认值
        rol: rol,
      ),
    _ => throw const FormatException('Failed to load users'),
  };
}

4. 捕获Dio专属异常

添加Dio异常捕获,处理网络连接、证书、超时等问题:

Future<List<User>> fetchUserList() async {
  try {
    final response = await Dio().get('https://10.0.2.2:8000/api/users');
    if (response.statusCode == 200) {
      return List<User>.from((response.data as List).map((user) => User.fromJson(user)));
    } else {
      throw Exception('请求失败: ${response.statusCode}');
    }
  } on DioException catch (e) {
    // 捕获Dio专属异常,输出详细信息
    throw Exception('网络错误: ${e.message}');
  } catch (e) {
    // 捕获其他未知异常
    throw Exception('未知错误: $e');
  }
}

内容的提问来源于stack exchange,提问作者juan manuel jimenez

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.22 15:54:53