Code Monkey home page Code Monkey logo

flutter_net's Introduction

可能是 Flutter 上最强的网络框架, 基于dio实现的非侵入式框架(不影响原有功能). 学习成本低、使用简单, 一行代码发起网络请求, 甚至无需初始化。

Features

  • RESTful API 设计 GET/POST/PUT/HEAH/DELETE/PATCH/DOWNLOAD
  • 可取消请求
  • 异步解析,数据量大不再卡顿
  • 全局错误处理(减少崩溃率)
  • 自定义解析器,支持全局和单个请求
  • 自定义解析方法
  • 配置请求参数
  • 漂亮的日志打印
  • 证书快速配置
  • 代理配置
  • 拦截器配置
  • 强制缓存模式/自定义缓存Key/缓存有效期/LRU缓存算法/缓存任何数据
  • 监听上传/下载进度

Getting started

dependencies:
  flutter_nb_net: ^1.0.3

Usage

全局配置:

 NetOptions.instance
      // header
      .addHeaders({"aaa": '111'})
      // baseUrl
      .setBaseUrl("https://www.wanandroid.com/")
      // 代理/https
      .setHttpClientAdapter(IOHttpClientAdapter()
        ..onHttpClientCreate = (client) {
          client.findProxy = (uri) {
            return 'PROXY 192.168.20.43:8888';
          };
          client.badCertificateCallback =
              (X509Certificate cert, String host, int port) => true;
          return client;
        })
      // cookie
      .addInterceptor(CookieManager(CookieJar()))
      // dio_http_cache
      .addInterceptor(DioCacheManager(CacheConfig(
        baseUrl: "https://www.wanandroid.com/",
      )).interceptor)
      // dio_cache_interceptor
      .addInterceptor(DioCacheInterceptor(
          options: CacheOptions(
        store: MemCacheStore(),
        policy: CachePolicy.forceCache,
        hitCacheOnErrorExcept: [401, 403],
        maxStale: const Duration(days: 7),
        priority: CachePriority.normal,
        cipher: null,
        keyBuilder: CacheOptions.defaultCacheKeyBuilder,
        allowPostMethod: false,
      )))
       //  全局解析器
      .setHttpDecoder(MyHttpDecoder.getInstance())
       //  超时时间
      .setConnectTimeout(const Duration(milliseconds: 3000))
      // 允许打印log,默认未 true
      .enableLogger(true)
      .create();

请求:

    var appResponse = await get<BannerModel, BannerModel>("banner/json",
        responseType: BannerModel());
    appResponse.when(success: (BannerModel model) {
      var size = model.data?.length;
      debugPrint("成功返回$size条");
    }, failure: (String msg, int code) {
      debugPrint("失败了:msg=$msg/code=$code");
    });

泛型一样,也可以不写:

    var appResponse = await get("banner/json",
        responseType: BannerModel());
    appResponse.when(success: (BannerModel model) {
      var size = model.data?.length;
      debugPrint("成功返回$size条");
    }, failure: (String msg, int code) {
      debugPrint("失败了:msg=$msg/code=$code");
    });

需要原始数据的请求:

    var appResponse = await get("banner/json");
    appResponse.when(success: (dynamic) {
      // var size = model.data?.length;
      debugPrint("成功返回$dynamic");
    }, failure: (String msg, int code) {
      debugPrint("失败了:msg=$msg/code=$code");
    });

Additional information

代码仓库

flutter_net's People

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar

flutter_net's Issues

能否支持对于范型的限制。目前所有的请求方法范型是必要的。

如题,针对如下场景的json,传递范型进行decoder是很有必要的。
{ "data": [{ "desc": "我们支持订阅啦~", "id": 30, "imagePath": "https://www.wanandroid.com/blogimgs/42da12d8-de56-4439-b40c-eab66c227a4b.png", "isVisible": 1, "order": 2, "title": "我们支持订阅啦~", "type": 0, "url": "https://www.wanandroid.com/blog/show/3352" }, { "desc": "", "id": 6, "imagePath": "https://www.wanandroid.com/blogimgs/62c1bd68-b5f3-4a3c-a649-7ca8c7dfabe6.png", "isVisible": 1, "order": 1, "title": "我们新增了一个常用导航Tab~", "type": 1, "url": "https://www.wanandroid.com/navi" }, { "desc": "一起来做个App吧", "id": 10, "imagePath": "https://www.wanandroid.com/blogimgs/50c115c2-cf6c-4802-aa7b-a4334de444cd.png", "isVisible": 1, "order": 1, "title": "一起来做个App吧", "type": 1, "url": "https://www.wanandroid.com/blog/show/2" }], "errorCode": 0, "errorMsg": "" }

但对于如下json,范型就是多余的,没必要的。 勉强可以定一个 只有 status字段但model,但很没必要。
{ "data": { "status": true }, "errorCode": 0, "errorMsg": "" }
甚至,对于不太规范的json,通过 NetConverter 自行解析,就会问题。
{ "data": true, "errorCode": 0, "errorMsg": "" }

能否支持对于范型的限制。目前所有的请求方法范型是必要的。

首先 感谢大佬开源,受益匪浅。

如题,针对如下场景的json,传递范型进行decoder是很有必要的。

{ "data": [{ "desc": "我们支持订阅啦~", "id": 30, "imagePath": "https://www.wanandroid.com/blogimgs/42da12d8-de56-4439-b40c-eab66c227a4b.png", "isVisible": 1, "order": 2, "title": "我们支持订阅啦~", "type": 0, "url": "https://www.wanandroid.com/blog/show/3352" }, { "desc": "", "id": 6, "imagePath": "https://www.wanandroid.com/blogimgs/62c1bd68-b5f3-4a3c-a649-7ca8c7dfabe6.png", "isVisible": 1, "order": 1, "title": "我们新增了一个常用导航Tab~", "type": 1, "url": "https://www.wanandroid.com/navi" }, { "desc": "一起来做个App吧", "id": 10, "imagePath": "https://www.wanandroid.com/blogimgs/50c115c2-cf6c-4802-aa7b-a4334de444cd.png", "isVisible": 1, "order": 1, "title": "一起来做个App吧", "type": 1, "url": "https://www.wanandroid.com/blog/show/2" }], "errorCode": 0, "errorMsg": "" }

但对于如下json,范型就是多余的,没必要的。 勉强可以定一个 只有 status字段但model,但很没必要。

{ "data": { "status": true },  "errorCode": 0,  "errorMsg": "" }

甚至,对于不太规范的json,通过 NetConverter 自行解析,就会问题。

 { "data": true,  "errorCode": 0,  "errorMsg": "" }

put/delete 方法。范型完全没必要。虽然可以通过 类似download() 方式进行解析,但感觉有些奇怪。

强大

强大是强大,怎么赶紧没人用呢,赶紧多发文章,多宣传,多写源码分析给别人看,推广起来,不然我也不敢用 😂

关于lru缓存的需求

  1. 场景 : 如果应用程序需要频繁访问某些数据,并且这些数据在一段时间内保持不变或者变化较慢,那么将这些数据缓存到本地磁盘可以显著提高访问速度,减轻服务器负担。
  2. 能否提供一个配置项 , 包含最大缓存数 、 缓存时间 、 缓存行为开关

感谢大大,有一些改进建议~

每个实现类都要继承 BaseNetworkModel 可能对项目浸入会比较大,写起来也麻烦。是否考虑将 decodeType 改为直接传 实体类的fromJson函数?
示例:

/// 默认解码器
class MyHttpDecoder extends NetDecoder {
  /// 单例对象
  static final MyHttpDecoder _instance = MyHttpDecoder._internal();

  /// 内部构造方法,可避免外部暴露构造函数,进行实例化
  MyHttpDecoder._internal();

  /// 工厂构造方法,这里使用命名构造函数方式进行声明
  factory MyHttpDecoder.getInstance() => _instance;

  @override
  K decode<T, K>({required Response<dynamic> response, T? Function(dynamic)? fromJsonFunc }) {
    var errorCode = response.data['code'];

    /// 请求成功
    if (errorCode == 2000) {
      var data = response.data['data'];
      if (fromJsonFunc != null && data is List) {
        var dataList = List<T>.from(data.map((item) => fromJsonFunc(item)).toList()) as K;
        return dataList;
      }
      if (fromJsonFunc != null) {
        var model = fromJsonFunc(data) as K;
        return model;
      }
      return data as K;
    } else {
      var errorMsg = response.data['message'];
      throw NetException(errorMsg, errorCode);
    }
  }
}

修改后的效果:

class MineUserInfoBean {

  MineUserInfoBean({...}) {...}

  MineUserInfoBean.fromJson(dynamic json) {...}

}
class MineHttpManager {


  ///获取MINE/用户信息
  static Future<Result<MineUserInfoBean>> getMineInfo() {
    return get(
      '/user',
      fromJsonFunc: MineUserInfoBean.fromJson,
    );
  }

  ///获取通用的资源
  static Future<Result<List<CommonResBean>>> getCommonRes({
    required String? resId,
  }) {
    return get(
      "/getGenericResource/$resId",
      fromJsonFunc: CommonResBean.fromJson,
    );
  }

}

NetOptions.instance 怎么修改 contentType multipart/form-data create中写死了

/// 配置网络请求并初始化
void create() {
var httpConfig = _httpConfigBuilder.create();
if (httpConfig.interceptors?.isNotEmpty ?? false) {
_dio.interceptors.addAll(httpConfig.interceptors!);
}
if (_isLogger) {
dio.interceptors.add(PrettyDioLogger(
requestHeader: true,
requestBody: true,
responseBody: true,
responseHeader: false,
error: true,
compact: true,
maxWidth: 90
));
}
_dio.options = BaseOptions(
baseUrl: httpConfig.baseUrl ?? '',
contentType: 'application/json',
connectTimeout: httpConfig.connectTimeout,
sendTimeout: httpConfig.sendTimeout,
receiveTimeout: httpConfig.receiveTimeout,
headers: httpConfig.headers);
if (httpConfig.httpClientAdapter != null) {
_dio.httpClientAdapter = httpConfig.httpClientAdapter!;
}
}

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.