Flutter网络请求插件http_services的使用

发布于 1周前 作者 caililin 来自 Flutter

Flutter网络请求插件http_services的使用

http_services 是一个用于在Dart应用程序中创建HTTP服务的包。它提供了一些便捷的方法来执行HTTP请求,清理未完成的请求以避免不必要的资源浪费,并为请求和响应对象提供了标准模型。

Features

  • 提供了方便的方法来进行HTTP请求
  • 释放服务会清理所有挂起的请求,以避免不必要的资源浪费!
  • 提供了方便的模型,以便为请求和响应对象设定标准

RequestBase

每个请求都应该扩展 RequestBase 并实现其重写方法:

  • endpoint:指定请求的路径

  • toJson:此方法用于请求的序列化

  • toData:这是一个可选的重写方法,在你需要发送非JSON正文时使用。它返回类型为 T 的对象。

    默认情况下 toData 返回 null

ResponseBase

每个响应都应该扩展 ResponseBase

Exceptions

该包中的所有异常都继承自 HttpServiceException

ApiException:

当请求出现问题时抛出(例如,缺少互联网连接、资源未找到等)。

  • networkError 表示连接是否中断
  • httpCode 是收到的HTTP状态码
  • httpMessage 是收到的HTTP状态消息

UnexpectedStatusCodeException:

当预期的HTTP代码与接收到的代码不匹配时抛出。

  • expected 是预期的状态码
  • actual 是接收到的状态码

ResponseMappingException:

当映射响应时发生错误时抛出。

RequestCanceledException:

当请求被取消时抛出。

HttpServiceBase

每个服务都应该扩展这个类。

要在你的服务中发起请求,可以使用以下方法之一:

  • getQuery:执行 GET 请求
  • postData:执行带有数据体的 POST 请求
  • postJson:执行带有 JSON 数据体的 POST 请求
  • putData:执行带有数据体的 PUT 请求
  • putJson:执行带有 JSON 数据体的 PUT 请求
  • deleteData:执行 DELETE 请求
  • deleteJson:执行带有 JSON 数据体的 DELETE 请求
  • patchData:执行带有数据体的 PATCH 请求
  • patchJson:执行带有 JSON 数据体的 PATCH 请求
  • download:下载文件
  • getBytes:从端点获取字节

Example

下面是一个完整的示例demo,演示如何使用 http_services 包进行网络请求。

import 'package:dio/dio.dart';
import 'package:http_services/http_services.dart';

// 定义请求类
class TodosRequest extends RequestBase {
  final int page;

  TodosRequest(this.page) : assert(page != null && page > 0);

  @override
  String get endpoint => '/todos/$page';

  @override
  Map<String, dynamic> toJson() {
    return {};
  }
}

// 定义响应类
class TodosResponse extends ResponseBase {
  final int userId;
  final int id;
  final String title;
  final bool completed;

  TodosResponse({
    this.userId,
    this.id,
    this.title,
    this.completed,
  });

  factory TodosResponse.fromJson(Map<String, dynamic> json) => TodosResponse(
        userId: json['userId'],
        id: json['id'],
        title: json['title'],
        completed: json['completed'],
      );
}

// 定义服务类
class TodosService extends HttpServiceBase {
  TodosService(Dio dioInstance) : super(dioInstance);

  Future<TodosResponse> getTodo(int page) {
    final request = TodosRequest(page);

    return getQuery(
      request: request,
      mapper: (json, _) => TodosResponse.fromJson(json),
    );
  }

  // 示例 POST 请求
  Future<void> postBoh() async {
    // 这里可以添加具体的POST请求逻辑
  }
}

void main() async {
  // 初始化 Dio 实例
  final dio = Dio(
    BaseOptions(
      baseUrl: 'https://jsonplaceholder.typicode.com/',
    ),
  );

  // 创建服务实例
  final service = TodosService(dio);

  try {
    print("Requesting data...");
    // 发起 GET 请求并处理响应
    final response1 = await service.getTodo(1);
    print(
      "user id: ${response1.userId}\n"
      "id: ${response1.id}\n"
      "title: ${response1.title}\n"
      "completed: ${response1.completed}",
    );

    // 发起 POST 请求并处理响应
    final response2 = await service.postBoh();
    print(response2);
  } on HttpServiceException catch (e) {
    print('Service exception: ${e.runtimeType}');
  }
}

Notes

有时,JSON响应可能不是如下格式:

{
  "data": [{"name": "Bob"},{"name":"Alice"}],
}

这将不会被视为JSON,因为它不是一个 Map<String,dynamic> 而是一个 List<Map<String,dynamic>>。 一种解决方案是在执行HTTP请求时使用 orElse 参数。记住,orElse 在响应体不是 Map<String,dynamic> 时执行。

同样地,如果你需要发送类似上述的JSON,可以重写 RequestBase 中的 onData 方法,并在你的请求对象中使用 *data 版本的请求。例如:

class User {
  final String name;
  User(this.name);

  Map<String, dynamic> toJson() => {'name': name};
}

class UsersToSend extends RequestBase {
  final List<User> users;
  UsersToSend(this.users);

  @override
  Map<String, dynamic> toJson() => {};

  @override
  List<User> toData() => users;
}

然后在你的服务中使用 postData 而不是 postJson

Contributors 🚀

希望这个回答能帮助你更好地理解和使用 http_services 插件!如果有任何问题或需要进一步的帮助,请随时提问。


更多关于Flutter网络请求插件http_services的使用的实战系列教程也可以访问 https://www.itying.com/category-92-b0.html

1 回复

更多关于Flutter网络请求插件http_services的使用的实战系列教程也可以访问 https://www.itying.com/category-92-b0.html


当然,关于Flutter中http_services插件的使用,这里提供一个简单的示例来展示如何进行网络请求。需要注意的是,http_services并非Flutter官方插件,但我们可以假设它类似于常用的http包来进行说明。如果http_services具有特定的API或方法,请参考其官方文档进行调整。以下示例将基于Flutter中常用的http包来展示如何进行网络请求,因为http包是Flutter社区广泛使用的网络请求库。

首先,确保在pubspec.yaml文件中添加http依赖:

dependencies:
  flutter:
    sdk: flutter
  http: ^0.13.3  # 请根据需要更新为最新版本

然后,运行flutter pub get来安装依赖。

接下来,创建一个Flutter应用,并在其中使用http包进行网络请求。以下是一个简单的示例:

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

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

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Flutter Network Request Demo',
      theme: ThemeData(
        primarySwatch: Colors.blue,
      ),
      home: MyHomePage(),
    );
  }
}

class MyHomePage extends StatefulWidget {
  @override
  _MyHomePageState createState() => _MyHomePageState();
}

class _MyHomePageState extends State<MyHomePage> {
  String _responseData = '';

  void _makeRequest() async {
    String url = 'https://jsonplaceholder.typicode.com/posts/1'; // 示例API

    try {
      http.Response response = await http.get(Uri.parse(url));

      if (response.statusCode == 200) {
        // 请求成功,解析JSON数据
        Map<String, dynamic> data = jsonDecode(response.body);
        setState(() {
          _responseData = data['title'].toString(); // 假设我们想要显示帖子的标题
        });
      } else {
        setState(() {
          _responseData = '请求失败,状态码:${response.statusCode}';
        });
      }
    } catch (e) {
      setState(() {
        _responseData = '请求异常:$e';
      });
    }
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text('Flutter 网络请求示例'),
      ),
      body: Center(
        child: Column(
          mainAxisAlignment: MainAxisAlignment.center,
          children: <Widget>[
            Text(
              '响应数据:',
              style: TextStyle(fontSize: 20),
            ),
            SizedBox(height: 10),
            Text(
              _responseData,
              style: TextStyle(fontSize: 24, fontWeight: FontWeight.bold),
            ),
            SizedBox(height: 20),
            ElevatedButton(
              onPressed: _makeRequest,
              child: Text('发送请求'),
            ),
          ],
        ),
      ),
    );
  }
}

在这个示例中,我们创建了一个简单的Flutter应用,其中包含一个按钮和一个显示响应数据的文本区域。当用户点击按钮时,应用将向指定的URL发送GET请求,并解析返回的JSON数据,将结果显示在文本区域中。

请注意,如果http_services插件的API与http包有所不同,请查阅http_services的官方文档以获取正确的使用方法。不过,大多数网络请求库的基本用法是相似的,涉及发送请求、处理响应和解析数据等步骤。

回到顶部