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

请求指导:Flutter中用Dio+Provider实现带Token的JSON转对象

没问题!我来一步步带你实现用Dio解析JSON到Users对象,同时结合Provider做状态管理。咱们按以下步骤来:

1. 先添加必要的依赖

首先打开你的pubspec.yaml,把dio和provider加进去,然后运行flutter pub get:

dependencies:
  flutter:
    sdk: flutter
  dio: ^5.4.0  # 用最新版本即可
  provider: ^6.1.1
2. 配置Dio实例(自动携带Token)

为了方便全局复用Dio,并且自动在请求头里加Token,咱们可以创建一个单例的Dio工具类:

import 'package:dio/dio.dart';

class DioClient {
  final Dio _dio = Dio();

  DioClient() {
    // 配置你的API基础地址
    _dio.options.baseUrl = "https://your-api-base-url.com/";
    // 添加拦截器,自动在请求头中携带Token
    _dio.interceptors.add(InterceptorsWrapper(
      onRequest: (options, handler) {
        // 这里替换成你的Token获取逻辑,比如从本地SharedPreferences读取
        String? token = "your-auth-token-here";
        if (token != null) {
          options.headers['Authorization'] = 'Bearer $token';
        }
        return handler.next(options);
      },
      onError: (DioException error, handler) {
        // 这里可以统一处理错误,比如Token过期时跳转登录页
        return handler.next(error);
      },
    ));
  }

  Dio get dio => _dio;
}
3. 创建Provider状态管理类

接下来写一个UserProvider类,继承ChangeNotifier,用来管理用户数据的状态(加载中、错误、成功),同时封装API请求和JSON解析逻辑:

import 'package:flutter/material.dart';
import 'package:dio/dio.dart';
// 导入你之前定义的Users模型类
import 'your-users-model-file.dart';

class UserProvider extends ChangeNotifier {
  final DioClient _dioClient;

  // 状态变量
  Users? _users;
  bool _isLoading = false;
  String? _errorMessage;

  // Getters供UI层读取状态
  Users? get users => _users;
  bool get isLoading => _isLoading;
  String? get errorMessage => _errorMessage;

  UserProvider(this._dioClient);

  // 获取用户列表的核心方法
  Future<void> fetchUsers() async {
    _isLoading = true;
    _errorMessage = null;
    notifyListeners(); // 更新加载状态

    try {
      // 发起GET请求,替换成你的实际API接口路径
      Response response = await _dioClient.dio.get("users");
      
      // 直接用你写的usersFromJson方法解析返回的JSON
      _users = usersFromJson(response.data.toString());
    } on DioException catch (e) {
      _errorMessage = e.response?.data['message'] ?? "请求失败,请稍后重试";
    } catch (e) {
      _errorMessage = "未知错误";
    } finally {
      _isLoading = false;
      notifyListeners(); // 更新最终状态
    }
  }
}
4. 在UI层使用Provider获取并展示数据

最后,咱们在Widget里使用Provider来获取数据,处理不同状态的UI展示:

import 'package:flutter/material.dart';
import 'package:provider/provider.dart';
// 导入你的Provider和模型类
import 'user_provider.dart';
import 'your-users-model-file.dart';

class UserListScreen extends StatelessWidget {
  const UserListScreen({super.key});

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(title: const Text("用户列表")),
      body: Consumer<UserProvider>(
        builder: (context, provider, child) {
          if (provider.isLoading) {
            return const Center(child: CircularProgressIndicator());
          }

          if (provider.errorMessage != null) {
            return Center(child: Text(provider.errorMessage!));
          }

          if (provider.users?.data == null || provider.users!.data.isEmpty) {
            return const Center(child: Text("暂无用户数据"));
          }

          // 渲染用户列表
          return ListView.builder(
            itemCount: provider.users!.data.length,
            itemBuilder: (context, index) {
              Datum user = provider.users!.data[index];
              return ListTile(
                title: Text(user.name),
                subtitle: Text(user.email),
                trailing: Text(user.status),
              );
            },
          );
        },
      ),
      floatingActionButton: FloatingActionButton(
        onPressed: () {
          // 触发重新获取数据
          context.read<UserProvider>().fetchUsers();
        },
        child: const Icon(Icons.refresh),
      ),
    );
  }
}
5. 在入口处注入Provider

别忘了在main.dart里把UserProvider和DioClient注入到Widget树中:

import 'package:flutter/material.dart';
import 'package:provider/provider.dart';
import 'dio_client.dart';
import 'user_provider.dart';
import 'user_list_screen.dart';

void main() {
  runApp(const MyApp());
}

class MyApp extends StatelessWidget {
  const MyApp({super.key});

  @override
  Widget build(BuildContext context) {
    return MultiProvider(
      providers: [
        Provider(create: (_) => DioClient()),
        ChangeNotifierProxyProvider<DioClient, UserProvider>(
          create: (_) => UserProvider(DioClient()),
          update: (_, dioClient, userProvider) => UserProvider(dioClient),
        ),
      ],
      child: MaterialApp(
        title: 'Flutter Dio + Provider Demo',
        home: const UserListScreen(),
      ),
    );
  }
}

这样一套流程走下来,你就完成了用Dio请求带Token的API、将JSON解析为Users对象,同时用Provider管理状态的完整功能啦!

内容的提问来源于stack exchange,提问作者Qasem M. Zreaq

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.09 13:52:39