Flutter网络通讯插件lib_network的使用

Flutter网络通讯插件lib_network的使用

基于Dio封装的网络库,把项目中经常使用到的场景封装为静态方法,方便调用。

特性

  • ✅ 异步Get, Post请求
  • ❌ 同步Get, Post请求
  • ✅ 单个文件上传,多个文件上传
  • ✅ 提交表单数据
  • ✅ 文件下载
  • ✅ 日志打印
  • ✅ 实现cookie管理(基于内存的)
  • ✅ 各种请求传参
  • ✅ 统一封装处理网络错误提示
  • ✅ 设置默认connectTimeout
  • ✅ 设置默认的请求头,也可请求的时候单独设置
  • ❌ 支持缓存
  • ❌ 重试
  • ✅ 取消网络请求

使用

  1. 调用HttpUtils.init()方法进行初始化。
  2. 调用HttpUtils中提供的静态方法进行网络请求。

虽然lib提供了baseUrl的设置,但是很多项目不止一个baseUrl。所以干脆让调用方自己管理url。

// 获取完整的api地址
String _getApiUrl(String api) {
  return "host:$api";
}

网络错误提示和token失效后跳转到登录页面的处理:

responseHandler(Response response) {
  if (response.statusCode == 200) {
    try {
      var data = jsonDecode(response.data);
      var code = data['code'] as int;
      var msg = data['msg'];
      if (code == 401 || code == 403) {
        onUnauthorized(msg);
      }
    } catch (e) {
      print(e.toString());
    }
  }
}

netErrorHandler(NetError error) {
  switch (error) {
    case NetError.timeout:
      showNetFailedTip();
      break;
    case NetError.other:
      showNetFailedTip();
      break;
    case NetError.cancel:
      showNetFailedTip();
      break;
    case NetError.unauthorized:
      // 统一处理token无效的情况
      onUnauthorized('');
      break;
  }
}

getDefaultHeader() {
  var header = {"Content-Type": "application/json"};
  var token = '';
  header['token'] = token;
  return header;
}

HttpUtils.init(
  responseHandler: responseHandler,
  netErrorHandler: netErrorHandler,
  baseUrl: 'baseUrl',
  getDefaultHeader: getDefaultHeader
);

使用默认的请求头(一般默认的请求头带一些设备信息,token等参数):

test('use default header', () async {
  // 设置post请求参数
  var data = {};
  data["uid"] = 'uid';
  var response = await HttpUtils.post(_getApiUrl('/postApi'), data: data);
});

单独设置请求头(部分接口不需要在header中设置token参数,则单独设置请求头):

test('use custom header', () async {
  // 设置请求头
  Options options = Options();
  options.headers = {};
  // 设置post请求参数
  var data = {};
  data["uid"] = 'uid';
  var response = await HttpUtils.post(_getApiUrl('/postApi'), options: options, data: data);
});

完整示例Demo

以下是一个完整的示例Demo,展示了如何使用lib_network插件进行网络请求。

import 'dart:convert';
import 'package:flutter/material.dart';
import 'package:lib_network/lib_network.dart';
import 'home_page.dart';

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

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

  [@override](/user/override)
  Widget build(BuildContext context) {
    return MaterialApp(
      scaffoldMessengerKey: snackBarKey,
      title: 'Network lib Demo',
      theme: ThemeData(
        primarySwatch: Colors.blue,
      ),
      home: const MyHomePage('Network lib Demo'),
    );
  }
}

initHttp() {
  HttpUtils.baseConfig(
    enableLog: true,
    connectTimeout: 1000 * 30,
    netErrorHandler: _netErrorHandler,
    responseHandler: _responseHandler,
    getDefaultHeader: _getDefaultHeader,
    enableAppLog: true,
    baseUrl: "https://api.github.com",
  );
}

Future<Map<String, dynamic>> _getDefaultHeader() async {
  var header = {"Content-Type": "application/json"};
  return header;
}

final GlobalKey<ScaffoldMessengerState> snackBarKey = GlobalKey<ScaffoldMessengerState>();

_netErrorHandler(NetError error) {
  switch (error) {
    case NetError.timeout:
      snackBarKey.currentState?.showSnackBar(const SnackBar(content: Text('连接超时')));
      break;
    case NetError.other:
      snackBarKey.currentState?.showSnackBar(const SnackBar(content: Text('请求失败,请稍后再试')));
      break;
    case NetError.cancel:
      break;
    case NetError.unauthorized:
      onUnauthorized(null);
      break;
  }
}

// 很多API喜欢将返回包装一层code, message, data。可以在这里统一处理错误的解析
_responseHandler(Response response) {
  if (response.statusCode == 200) {
    try {
      var data = jsonDecode(response.data);
      var code = data['code'] as int;
      var msg = data['msg'];
      if (code == 401 || code == 403) {
        onUnauthorized(msg);
      }
    } catch (e) {
      print(e.toString());
    }
  }
}

void onUnauthorized(msg) {
  snackBarKey.currentState?.showSnackBar(const SnackBar(content: Text('无权限,请登录')));
  // 跳转到登录页面
}

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

1 回复

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


lib_network 是一个用于 Flutter 的网络通信插件,它简化了网络请求的处理过程,提供了简洁的 API 来进行 HTTP 请求。以下是如何使用 lib_network 插件的基本步骤:

1. 添加依赖

首先,你需要在 pubspec.yaml 文件中添加 lib_network 插件的依赖:

dependencies:
  flutter:
    sdk: flutter
  lib_network: ^1.0.0  # 请使用最新版本

然后运行 flutter pub get 来获取依赖。

2. 初始化网络请求工具

在使用 lib_network 之前,你可以初始化一个网络请求工具类,通常你可以创建一个单例类来管理网络请求。

import 'package:lib_network/lib_network.dart';

class NetworkManager {
  static final NetworkManager _instance = NetworkManager._internal();
  late final Network _network;

  factory NetworkManager() {
    return _instance;
  }

  NetworkManager._internal() {
    _network = Network(
      baseUrl: 'https://your-api-url.com',
      headers: {
        'Content-Type': 'application/json',
        // 可以在这里添加其他全局头部
      },
    );
  }

  Network get network => _network;
}

3. 发起 GET 请求

使用 NetworkManager 发起一个 GET 请求:

void fetchData() async {
  try {
    var response = await NetworkManager().network.get('/endpoint');
    print('Response data: ${response.data}');
  } catch (e) {
    print('Error: $e');
  }
}

4. 发起 POST 请求

使用 NetworkManager 发起一个 POST 请求:

void postData() async {
  try {
    var response = await NetworkManager().network.post(
      '/endpoint',
      data: {
        'key1': 'value1',
        'key2': 'value2',
      },
    );
    print('Response data: ${response.data}');
  } catch (e) {
    print('Error: $e');
  }
}

5. 发起 PUT 请求

使用 NetworkManager 发起一个 PUT 请求:

void updateData() async {
  try {
    var response = await NetworkManager().network.put(
      '/endpoint',
      data: {
        'key1': 'new_value1',
        'key2': 'new_value2',
      },
    );
    print('Response data: ${response.data}');
  } catch (e) {
    print('Error: $e');
  }
}

6. 发起 DELETE 请求

使用 NetworkManager 发起一个 DELETE 请求:

void deleteData() async {
  try {
    var response = await NetworkManager().network.delete('/endpoint');
    print('Response data: ${response.data}');
  } catch (e) {
    print('Error: $e');
  }
}

7. 处理错误

lib_network 会自动处理一些常见的网络错误,但你也可以在 catch 块中自定义错误处理逻辑。

void fetchData() async {
  try {
    var response = await NetworkManager().network.get('/endpoint');
    print('Response data: ${response.data}');
  } on NetworkException catch (e) {
    print('Network error: ${e.message}');
  } catch (e) {
    print('Unexpected error: $e');
  }
}

8. 配置请求

你可以在发起请求时配置一些选项,例如超时时间、自定义头部等。

void fetchDataWithOptions() async {
  try {
    var response = await NetworkManager().network.get(
      '/endpoint',
      options: RequestOptions(
        headers: {
          'Authorization': 'Bearer your_token',
        },
        timeout: Duration(seconds: 10),
      ),
    );
    print('Response data: ${response.data}');
  } catch (e) {
    print('Error: $e');
  }
}

9. 处理响应

lib_network 的响应对象通常包含 statusCodedataheaders 等信息。

void fetchData() async {
  try {
    var response = await NetworkManager().network.get('/endpoint');
    print('Status code: ${response.statusCode}');
    print('Response data: ${response.data}');
    print('Headers: ${response.headers}');
  } catch (e) {
    print('Error: $e');
  }
}

10. 处理 JSON 数据

如果 API 返回的是 JSON 数据,你可以直接使用 response.data 来获取解析后的 JSON 对象。

void fetchJsonData() async {
  try {
    var response = await NetworkManager().network.get('/endpoint');
    var jsonData = response.data;
    print('JSON data: $jsonData');
  } catch (e) {
    print('Error: $e');
  }
}
回到顶部