Flutter 网络库简易封装

1,327 阅读1分钟

本文介绍如何优雅地封装一个网络库,包含以下几个点:

  1. JSON转换为实体对象
  2. 类似Promise方式的API封装

JSON转换为实体对象

第一步,安装json2entity工具

flutter packages pub global activate json2entity

配置启动项:

vim $HOME/.bash_profile

export FLUTTER_HOME=<path to flutter>
export PATH="$PATH:$FLUTTER_HOME/.pub-cache/bin"

第二步,使用json串自动生成Dart实体类

j2e -j '{"result":1,"msg":"ok"}' -o output/BaseEntity

HTTP 封装

封装常用的GET, POST请求

import 'dart:async';
import 'dart:convert' as Convert;
import 'package:http/http.dart' as http;

class HttpRequest {
  final baseUrl;

  HttpRequest(this.baseUrl);

  Future<dynamic> get(String uri, {Map<String, String> headers}) async {
    http.Response response = await http.get(baseUrl + uri, headers: headers);
    return _processResponse(uri, response);
  }

  Future<dynamic> post(String uri, dynamic body, {Map<String, String> headers}) async {
    http.Response response = await http.post(baseUrl + uri, body: body, headers: headers);
    return _processResponse(uri, response);
  }

  Future<dynamic> _processResponse(String uri, http.Response response) async {
    try {
      final statusCode = response.statusCode;
      final responseBody = response.body;
      var result = Convert.jsonDecode(responseBody);
      return result;
    } on Exception catch (e) {
      if (response != null) {
        return {"status": response.statusCode, "message": e.toString()};
      } else {
        return {"status": -1, "message": "网络异常"};
      }
    }
  }

API封装

/*
API统一返回的实体如下:
{
    status: 0,
    message: "",
    data: {}
}
*/
class API {
  static const BASE_URL = 'https://xxx.com';
  static const CUSTOM_HEADER = {"": ""};

  static var _request = HttpRequest(API.BASE_URL);

  static Future<dynamic> _get(String uri, {Map<String, String> headers}) async {
    if (headers == null) {
      headers = Map<String, String>();
    }
    headers.addAll(CUSTOM_HEADER);

    final response = await _request.get(uri, headers: headers);
    
    final status = response['status'];
    if (status == 0) { // 成功返回
      final data = response['data'];
      return data;
    } else { // 失败返回
      throw FailureResponse(status, response['message']);
    }
  }

  // 获取xx列表
  static Future<dynamic> getXXList({int start, int limit}) async {
    final data = await _get('/v1/test?start=$start&limit=$limit');
    final items = data['items'];
    final result = List<Entity>();
    for (var item in items) {
      final bean = Entity.fromJson(item);
      result.add(bean);
    }
    return result;
  }
}

class FailureResponse {
  final int status;
  final String message;
  FailureResponse(this.status, this.message);

  @override
  String toString() {
    return 'status=$status, message=$message';
  }
}

类似Promise的方式访问API

API.getXXList(start: 0, limit: 4).then((data) {
    // 更新数据
}).catchError((error) {
    print(error);
});

参考资料