【问题标题】:How do calling API in flutter using Dio?如何使用 Dio 在 Flutter 中调用 API?
【发布时间】:2021-01-24 15:23:53
【问题描述】:

我需要将 JSON 解析为对象并在我的应用程序中使用它,但我需要使用 dio 库来执行此操作,但我是新手,谁能帮助我如何使用它将 JSON 解析为对象,我的请求也需要一个令牌,我的对象将像这样锁定:

import 'dart:convert';

Users usersFromJson(String str) => Users.fromJson(json.decode(str));
String usersToJson(Users data) => json.encode(data.toJson());

class Users {
  Users({
    this.data,
  });

  List<Datum> data;

  factory Users.fromJson(Map<String, dynamic> json) => Users(
    data: List<Datum>.from(json["data"].map((x) => Datum.fromJson(x))),
  );

  Map<String, dynamic> toJson() => {
    "data": List<dynamic>.from(data.map((x) => x.toJson())),
  };
}

class Datum {
  Datum({
    this.id,
    this.name,
    this.email,
    this.phone,
    this.status,
    this.images,
  });

  int id;
  String name;
  String email;
  String phone;
  String status;
  List<Image> images;

  factory Datum.fromJson(Map<String, dynamic> json) => Datum(
    id: json["id"],
    name: json["name"],
    email: json["email"],
    phone: json["phone"],
    status: json["status"],
    images: List<Image>.from(json["images"].map((x) => Image.fromJson(x))),
  );

  Map<String, dynamic> toJson() => {
    "id": id,
    "name": name,
    "email": email,
    "phone": phone,
    "status": status,
    "images": List<dynamic>.from(images.map((x) => x.toJson())),
  };
}

class Image {
  Image({
    this.id,
    this.url,
    this.isProfileImage,
  });

  int id;
  String url;
  int isProfileImage;

  factory Image.fromJson(Map<String, dynamic> json) => Image(
    id: json["id"],
    url: json["url"],
    isProfileImage: json["is_profile_image"],
  );

  Map<String, dynamic> toJson() => {
    "id": id,
    "url": url,
    "is_profile_image": isProfileImage,
  };
}

谁能帮我一步一步地使用provider和dio来做这件事!

【问题讨论】:

    标签: api flutter dart dio


    【解决方案1】:

    试试这样的:

      final client = Dio();
    
      Future<_yourClass_> getData() async {
        final url = 'your-url';
    
        try {
          final response = await client.get(url);
    
          if (response.statusCode == 200) {
            return _yourClass_.fromJson(response.data);
          } else {
            print('${response.statusCode} : ${response.data.toString()}');
            throw response.statusCode;
          }
        } catch (error) {
          print(error);
        }
      }
    
    ... _yourClass_ data = await getData();
    

    如果你已经有一个令牌,你可以像这样将它添加到 dio 中:

    Dio()..options.headers['authorization'] = 'Bearer $token';
    

    当然,这取决于授权类型。另外如果你还没有token,需要先请求获取token(类似上图),然后再从response.data中获取token。

    【讨论】:

    • 然后你可以在'catch'中调试你的错误响应,你可以得到服务器所说的准确信息,有了这些信息你应该能够修改你的api调用。每个 API 都不同。
    • 我用过这个但是给我一个身份验证错误请求 401 Future getData() async { try { final response = await client.get(url,options: Options( headers: {HttpHeaders.authorizationHeader : $token} ), ); if (response.statusCode == 200) { print(response.data); return Users.fromJson(response.data); } else { print('${response.statusCode} : ${response.data.toString()}');抛出 response.statusCode; } } 捕捉(错误){ 打印(错误); }
    • 是的,但是您还会从服务器收到一些响应消息,并且您需要获取有关问题所在的信息。 401 是来自服务器的响应代码。
    • 是否像我使用 dio 调用 token 的方式一样正确?
    • 是的,但请检查 api 文档,例如我们的 api 需要格式为“Bearer $token”的令牌。
    【解决方案2】:

    这里是一步一步的说明

    首先创建一个dio API服务和服务实现类

    import 'package:dio/dio.dart';
    
    abstract class HttpService{
      void init();
    
      Future<Response> getRequest(String url);
    }
    

    一个Api调用实现类

    import 'package:dio/dio.dart';
    import 'package:getx_news_app_impl/service/http_service.dart';
    
    const BASE_URL = "https://newsapi.org/";
    const API_KEY = "fb12a31181aa4498ba52877978913275";
    
    
    class HttpServiceImpl implements HttpService{
    
      Dio _dio;
    
      @override
      Future<Response> getRequest(String url) async{
        // TODO: implement getRequest
    
        Response response;
        try {
          response = await _dio.get(url);
        } on DioError catch (e) {
          print(e.message);
          throw Exception(e.message);
        }
    
        return response;
      }
    
      initializeInterceptors(){
        _dio.interceptors.add(InterceptorsWrapper(
          onError: (error){
            print(error.message);
          },
          onRequest: (request){
            print("${request.method} | ${request.path}");
          },
          onResponse: (response){
            print("${response.statusCode} ${response.statusMessage} ${response.data}");
          }
        ));
      }
    
      @override
      void init() {
        _dio = Dio(BaseOptions(
          baseUrl: BASE_URL,
          headers: {"Authorization" : "Bearer $API_KEY"}
        ));
    
        initializeInterceptors();
      }
    
    }
    

    并像这样使用该类调用 API

    class NewsRepoImpl implements NewsRepo{
    
      HttpService _httpService;
    
      
      Future<List<Article>> getNewsHeadline() async{
        // TODO: implement getNewsHeadline
    
        try {
           final response = await _httpService.getRequest("/v2/top-headlines?country=us");
    
           final parsedResponse = NewsResponse.fromJson(response.data);
    
           return parsedResponse.articles;
        } on Exception catch (e) {
          print(e);
          return null;
        }
      }
      
    }
    

    【讨论】:

      【解决方案3】:
      import 'package:dio/dio.dart';
      import 'package:flutter/cupertino.dart';
      import 'package:flutter/material.dart';
      
      class ContactListWidget extends StatefulWidget {
        const ContactListWidget({Key? key}) : super(key: key);
      
        @override
        _ContactListWidgetState createState() => _ContactListWidgetState();
      }
      
      class _ContactListWidgetState extends State<ContactListWidget> {
        List<dynamic> users = [];
      
        @override
        void initState() {
          super.initState();
      
          getDio();
        }
      
        @override
        Widget build(BuildContext context) {
          return Scaffold(
            body: Container(
              child: ListView(
                children: users.map((e) {
                  return Card(
                    child: Padding(
                      padding: const EdgeInsets.all(8.0),
                      child: Row(
                       mainAxisAlignment: MainAxisAlignment.spaceEvenly,
                       children: [
                      Expanded(
                        flex: 4,
                        child: Row(
                          crossAxisAlignment: CrossAxisAlignment.start,
                          children: [
                            Padding(
                              padding: const EdgeInsets.all(8.0),
                              child: CircleAvatar(
                                child: Image.network(e["avatar"]),
                              ),
                            ),
                            Flexible(
                              child: Padding(
                                padding: const EdgeInsets.all(8.0),
                                child: Column(
                                  crossAxisAlignment: CrossAxisAlignment.start,
                                  children: [
                                    Text(e["name"],
                                        style: TextStyle(
                                          fontWeight: FontWeight.bold,
                                          fontSize: 20,
                                        )),
                                    Text(e["title"],maxLines: 1,overflow: TextOverflow.ellipsis,),
                                    Chip(label: Text(e["role"]),),
                                  ],
                                ),
                              ),
                            ),
                          ],
                        ),
                      ),
                      Expanded(
                        flex: 1,
                        child: Text(
                          '\$  ${e["balance"].toString() == "null" ? "0" : e["balance"].toString()}',
                          style: TextStyle(
                            fontWeight: FontWeight.bold,
                            fontSize: 20,
                          ),
                        ),
                      ),
                    ],
                  ),
                ),
              );
            }).toList(),
          ),
        ),
      );
        }
      
        void getDio() async {
          try {
            var response = await Dio(BaseOptions(headers: {"Content-Type": 
      "application/json"}))
                .get('https://mock-database-f1298.web.app/api/v1/users');
            users = response.data["users"];
            setState(() {});
          } catch (e) {
            print(e);
          }
        }
      }
      

      Sample Image

      &lt;img src="https://i.stack.imgur.com/OvIOH.png"&gt;

      【讨论】:

      • 正如目前所写,您的答案尚不清楚。请edit 添加其他详细信息,以帮助其他人了解这如何解决所提出的问题。你可以找到更多关于如何写好答案的信息in the help center
      猜你喜欢
      • 1970-01-01
      • 2022-10-25
      • 1970-01-01
      • 2019-05-01
      • 2021-03-26
      • 2020-01-17
      • 2021-09-29
      • 2019-11-06
      • 2020-08-11
      相关资源
      最近更新 更多