美文网首页js css html
Dio网络封装以及数据转模型

Dio网络封装以及数据转模型

作者: woniu | 来源:发表于2022-08-01 12:28 被阅读0次

    一、为什么需要封装Dio

    1、迁移代码

    当组件库中的方法发生改变,需要迁移的时候,如果有多处地方用到,那么需要对使用到的每个文件都进行修改,非常的繁琐而且很容易出问题。

    2、请求库切换

    当不需要Dio库的时候,我们可以试随时方便切换到别的网络库。

    3、统一配置

    因为一个应用程序基本都是统一的配置方式,所以我们可以针对拦截器 、转换器 、 缓存 、统一处理错误 、代理配置、证书校验 等多个配置进行统一管理。

    二、使用单利模式进行Dio封装

    1、为什么使用单例模式?

    每个页面都会在进行网络请求,如果每次都要初始化一个dio,那么会增加系统不必要的开销,而使用单例模式对象一旦创建每次都是访问同一个对象,不会再实例化对象。

    2、创建单例类
    import 'package:dio/dio.dart';
    class HttpRequest {
      static final BaseOptions options = BaseOptions(baseUrl: "");
    
      static final Dio dio = Dio(options);
    
      static Future<T> request<T>(String url,
          {String method, Map<String, dynamic> params, Interceptor inter}) async {
        // 1.请求的单独配置
        Options options = Options(method: method);
        options.headers = httpHeaders;
    //    // 2.添加第一个拦截器
    //    Interceptor dInter =
    //        InterceptorsWrapper(onRequest: (RequestOptions options) {
    //      // 1.在进行任何网络请求的时候, 可以添加一个loading显示
    //
    //      // 2.很多页面的访问必须要求携带Token,那么就可以在这里判断是有Token
    //
    //      // 3.对参数进行一些处理,比如序列化处理等
    //      print("拦截了请求");
    //      return options;
    //    }, onResponse: (Response response) {
    //      print("拦截了响应");
    //      return response;
    //    }, onError: (DioError error) {
    //      print("拦截了错误");
    //      return error;
    //    });
    //
    //    List<Interceptor> inters = [dInter];
    //    if (inter != null) {
    //      inters.add(inter);
    //    }
    //
    //    dio.interceptors.addAll(inters);
        // 3.发送网络请求
        try {
          Response response =
              await dio.request(url, data: params, options: options);
          return response.data;
        } on DioError catch (e) {
          return Future.error(e);
        }
      }
    }
    
    const httpHeaders = {
      'Content-Type': 'application/json',
      'X-LC-Id': 'a4Cj1Hm5aMrdhob6xGw71B5A-gzGzoHsz',
      'X-LC-Key': 'XQaL1tUQC0DCQxBA9fpoR21C',
    };
    
    3、方法调用
       HttpRequest.request(url, method: 'GET').then((res) {
          var list = new GHAddressModel.fromJson(res).results;
          setState(() {
            this._list = list;
          });
        });
    
    /// 收货地址列表
    class GHAddressList extends StatefulWidget {
      @override
      _GHAddressListState createState() => _GHAddressListState();
    }
    
    class _GHAddressListState extends State<GHAddressList> {
      /// 地址列表
      var _list = [];
      GlobalKey _easyRefreshKey = new GlobalKey();
      _getAddressList() async {
        //addressDetails
        //shopAddress
        var url = "https://a4cj1hm5.api.lncld.net/1.1/classes/shopAddress";
        var c = Uri.encodeComponent('-createdAt');
        var d = Uri.encodeComponent('李');
        url = url + '?' + "order=" + c;
    
        HttpRequest.request(url, method: 'GET').then((res) {
          var list = new GHAddressModel.fromJson(res).results;
          setState(() {
            this._list = list;
          });
        });
      }
    
      void initState() {
        super.initState();
        this._easyRefreshKey.currentState;
      }
    
      void deactivate() {
        // 返回到当前页刷新
        var bool = ModalRoute.of(context).isCurrent;
        if (bool) {
          this._getAddressList();
        }
      }
    
      Widget ListItem(Results results) {
        return InkWell(
          onTap: () {},
          child: Container(
            margin: EdgeInsets.only(top: 5, bottom: 5),
            width: ScreenAdaper.getScreenWidth(),
            child: Column(
              children: <Widget>[
                Row(
                  mainAxisAlignment: MainAxisAlignment.spaceBetween,
                  children: <Widget>[
                    Row (
                      children: <Widget>[
                        Column(
                          crossAxisAlignment: CrossAxisAlignment.start,
                          children: <Widget>[
                            Container(
                              child: Row(
                                children: <Widget>[
                                  Container(
                                    width:50,
                                    child: Text(
                                      results.name,
                                      overflow: TextOverflow.ellipsis,
                                      style:TextStyle(
                                        fontSize: 18,
                                        fontWeight: FontWeight.bold,
                                      ),
                                    ),
                                  ),
                                  SizedBox(
                                    width: 10,
                                  ),
                                  Container(
                                    child: Text(
                                      results.phone,
                                      style: TextStyle(fontSize: 16,fontWeight: FontWeight.bold),
                                    ),
                                  ),
                                ],
                              ),
                            ),
                            Container(
                              width: ScreenAdaper.getScreenWidth() - 20 - 20 - 30,
                              child: Text(
                                results.province +
                                    results.city +
                                    results.area +
                                    results.detailsAddress,
                                style: TextStyle(fontSize: 14, color: Colors.black54),
                              ),
                            ),
                          ],
                        )
                      ],
                    ),
                    GestureDetector(
    
                      onTap: () {
                        Navigator.pushNamed(context, '/GHAddressEdit', arguments: {
                          'name': "${results.name}",
                          'zone': "${results.zone}",
                          'detailsAddress': "${results.detailsAddress}",
                          'phoneNumber': results.phone,
                          'objectId': results.objectId,
                        });
                      },
                      child: Container(
                        child: Icon(
                          Icons.edit,
                          size: 30,
                        ),
                      ),
                    ),
                  ],
                ),
                Divider(),
              ],
            )
          ),
        );
      }
    
      @override
      Widget build(BuildContext context) {
        ScreenAdaper.init(context);
        return Scaffold(
          appBar: AppBar(
            actions: <Widget>[
              TextButton(
                onPressed: () {
                  Navigator.pushNamed(context, '/GHAddressEdit');
                },
                child: Icon(Icons.add),
              )
            ],
            title: Text("地址管理"),
          ),
          body: Container(
              padding: EdgeInsets.all(20),
              child: EasyRefresh(
                firstRefresh: true,
                key:_easyRefreshKey,
                onRefresh: () async {
                  await this._getAddressList();
                },
                onLoad: () async {
                  await this._getAddressList();
                },
                child: ListView.builder(
                  itemBuilder: (context, index) {
                    return ListItem(this._list[index]);
                  },
                  itemCount: this._list.length,
                ),
              )),
        );
      }
    }
    

    三、数据转模型

    我们当然不能手写来实现,我们使用quickType来进行转化。
    数据请求后,转模型

       HttpRequest.request(url, method: 'GET').then((res) {
          var list = new GHAddressModel.fromJson(res).results;
          setState(() {
            this._list = list;
          });
        });
    

    GHAddressModel类型

    class GHAddressModel {
      List<Results> results;
    
      GHAddressModel({this.results});
    
      GHAddressModel.fromJson(Map<String, dynamic> json) {
        if (json['results'] != null) {
          results = new List<Results>();
          json['results'].forEach((v) {
            results.add(new Results.fromJson(v));
          });
        }
      }
    
      Map<String, dynamic> toJson() {
        final Map<String, dynamic> data = new Map<String, dynamic>();
        if (this.results != null) {
          data['results'] = this.results.map((v) => v.toJson()).toList();
        }
        return data;
      }
    }
    
    class Results {
      String province;
      String area;
      String city;
      String detailsAddress;
      String remark;
      String zone;
      String phone;
      String userId;
      String objectId;
      String updatedAt;
      String createdAt;
      String name;
      String isDefault;
      Where where;
    
      Results(
          {this.detailsAddress,
            this.remark,
      this.province,
      this.area,
      this.city,
            this.zone,
            this.phone,
            this.userId,
            this.objectId,
            this.updatedAt,
            this.createdAt,
            this.name,
            this.isDefault,
            this.where});
    
      Results.fromJson(Map<String, dynamic> json) {
        detailsAddress = json['detailsAddress'];
        if (detailsAddress == null) {
          detailsAddress = "暂无地址";
        }
        remark = json['remark'];
        zone = json['zone'];
        if (zone == null) {
          zone = "暂无地址";
        }
        phone = json['phone'];
        if (phone == null) {
          phone = "13800000000";
        }
        userId = json['userId'];
        objectId = json['objectId'];
        updatedAt = json['updatedAt'];
        createdAt = json['createdAt'];
        province = json['province'];
        city = json['city'];
        area = json['area'];
        name = json['name'];
        if (name == null) {
          name = "没有设置";
        }
        isDefault = json['isDefault'];
        where = json['where'] != null ? new Where.fromJson(json['where']) : null;
      }
    
      Map<String, dynamic> toJson() {
        final Map<String, dynamic> data = new Map<String, dynamic>();
        data['detailsAddress'] = this.detailsAddress;
        data['remark'] = this.remark;
        data['zone'] = this.zone;
        data['phone'] = this.phone;
        data['userId'] = this.userId;
        data['objectId'] = this.objectId;
        data['updatedAt'] = this.updatedAt;
        data['createdAt'] = this.createdAt;
        data['name'] = this.name;
        data['isDefault'] = this.isDefault;
        data['province'] = this.province;
        data['city'] = this.city;
        data['area'] = this.area;
    
    
        if (this.where != null) {
          data['where'] = this.where.toJson();
        }
        return data;
      }
    }
    
    class Where {
      String token;
      String userId;
      Where({this.token, this.userId});
      Where.fromJson(Map<String, dynamic> json) {
        token = json['token'];
        userId = json['userId'];
      }
    
      Map<String, dynamic> toJson() {
        final Map<String, dynamic> data = new Map<String, dynamic>();
        data['token'] = this.token;
        data['userId'] = this.userId;
        return data;
      }
    }
    

    相关文章

      网友评论

        本文标题:Dio网络封装以及数据转模型

        本文链接:https://www.haomeiwen.com/subject/iucrwrtx.html