flutter Dio()网络请求

 

Flutter JSON 字符串和 Map 类型的转换

// 使用 dart:convert 包来实现 JSON 与 Map 之间的转换
import 'dart:convert';

var mapData = {"name": "张三", "age": "20"};
var strData = '{"name":"张三","age":"20"}';

// 使用 json.encode() 将 Map 转换为 JSON 字符串
print(json.encode(mapData));

// 使用 json.decode() 将 JSON 字符串转化为 Map 类型
print(json.decode(strData));

Flutter 使用官方http库进行网络请求

// 官方http库的使用方法可参考其官方文档链接
https://pub.dev/packages/http

Flutter Dio 库的介绍

// Dio 是 Dart 的强大的 HTTP 请求库,提供了多种高级功能
// Dio 支持如下特性:
// - Restful API
// - FormData
// - 请求拦截器
// - 请求取消
// - Cookie 管理
// - 文件上传/下载
// - 超时管理
// - 自定义适配器等等...
// 可以在以下链接查看 Dio 的详细文档和源代码

https://pub.dev/packages/dio
Dio 官方中文文档

使用官方http库的Flutter代码示例

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

class HttpPage extends StatefulWidget {
  HttpPage({Key key}) : super(key: key);

  _HttpDemoState createState() => _HttpDemoState();
}

class _HttpDemoState extends State<HttpPage> {

  List _list = [];

  @override
  void initState() {
    super.initState();
    this._getData();
  }

  _getData() async {
    // 定义API的请求URL
    var apiUrl = "http://a.itying.com/api/productlist";

    // 使用http库发送GET请求
    var result = await http.get(apiUrl);

    // 判断请求是否成功
    if (result.statusCode == 200) {
      print(result.body);
      setState(() {
        this._list = json.decode(result.body)["result"];
      });
    } else {
      print("请求失败,状态码: ${result.statusCode}");
    }
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
        appBar: AppBar(
          title: Text("请求数据Demo"),
        ),
        // 判断数据是否加载完成,完成则展示ListView,否则显示加载中...
        body: this._list.length > 0
            ? ListView(
                children: this._list.map((value) {
                  return ListTile(
                    title: Text(value["title"]),
                  );
                }).toList(),
              )
            : Text("加载中...")
    );
  }
}

Flutter 使用Dio库进行HTTP请求

// 使用 dio 3.0.9 版本,首先在pubspec.yaml中添加
// dio: ^3.0.9

// 导入必要的包
import 'dart:convert';
import 'package:flutter/material.dart';
import 'package:dio/dio.dart';

// 定义UpDown StatefulWidget
class UpDown extends StatefulWidget {
  UpDown({Key key});
  _UpDown createState() => _UpDown();
}

class _UpDown extends State<UpDown> {
  var list = [];
  var page = 1;
  var pageFlag = true;
  var _scrollController = ScrollController();

  @override
  void initState() {
    super.initState();
    _getData();
    // 上拉加载逻辑
    _scrollController.addListener(() {
      var _scrollTop = _scrollController.position.pixels;  // 获取滚动条下拉的距离
      var _scrollHeight = _scrollController.position.maxScrollExtent;  // 获取整个页面的高度
      if(_scrollTop >= _scrollHeight - 20) {
        _getData();
      }
    });
  }

  // 获取数据方法
  _getData() async {
    if(pageFlag == false) return;  // 判断是否有更多数据可加载
    var response = await Dio().get('http://www.phonegap100.com/appapi.php?a=getPortalList&catid=20&page=${page}');
    var res = json.decode(response.data)['result'];
    setState(() {
      list.addAll(res);
      page++;
    });
    if(res.length < 20) {
      setState(() {
        pageFlag = false;  // 若返回数据少于20条,则表示没有更多数据了
      });
    }
  }

  // 下拉刷新方法
  Future<void> _onRefresh() async {
    await Future.delayed(
      Duration(milliseconds: 2000), () {
        list = [];
        page = 1;
        _getData();
      }
    );
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(title: Text('上拉加载-下拉刷新')),
      body: list.length > 0 ? RefreshIndicator(
        onRefresh: _onRefresh,
        child: ListView.builder(
          controller: _scrollController,
          itemCount: list.length,
          itemBuilder: (context, index) {
            return Column(
              children: <Widget>[
                Container(
                  padding: EdgeInsets.only(top: 5, bottom: 5, left: 5),
                  alignment: Alignment.centerLeft,
                  child: Text('${list[index]['title']}', maxLines: 1, overflow: TextOverflow.ellipsis),
                ),
                Divider(),
                index == list.length - 1 ? getMoreTips(flag: this.pageFlag) : SizedBox()
              ],
            );
          },
        ),
      ) : getMoreTips(flag: this.pageFlag)
    );
  }
}

// 底部加载更多提示组件
class getMoreTips extends StatelessWidget {
  var flag = true;
  getMoreTips({Key key, this.flag}) : super(key: key);

  @override
  Widget build(BuildContext context) {
    return Center(
      child: flag ? Row(  // 若flag为true,显示加载中,否则显示没有更多数据
        mainAxisAlignment: MainAxisAlignment.center,
        children: <Widget>[
          Text('正在加载...'),
          SizedBox(width: 10),
          CircularProgressIndicator(strokeWidth: 2)
        ],
      ) : Column(
        mainAxisAlignment: MainAxisAlignment.center,
        children: <Widget>[
          Text('没有更多数据了'),
          SizedBox(height: 10),
        ],
      ),
    );
  }
}

Dio封装完成的代码 带拦截器  可以直接复制使用

import 'dart:convert';
import 'package:dio/dio.dart';
import 'utils.dart';

class DioHttp {
  Dio _dio = Dio();

  DioHttp() {
    _initOptions();
    _addInterceptors();
  }

  void _initOptions() async {
    var tokens = await Storage.getString('token');
    _dio.options.baseUrl = ''; // TODO: 设置为你的baseURL
    _dio.options.connectTimeout = 15000;
    _dio.options.receiveTimeout = 15000;
    // 可以在这里添加公共的 header 和其他设置
   _dio.options.headers = {
        'Authorization': 'Bearer your_token_here',
        'Custom-Header': 'custom_value',
    };
  _dio.options.contentType = 'application/x-www-form-urlencoded';
  _dio.options.queryParameters = {
    'api_key': 'your_api_key',
    };
  }

  void _addInterceptors() {
    _dio.interceptors.add(
      InterceptorsWrapper(
        onRequest: (options) async {
          // 在这里添加你的token或者其他请求之前需要设置的信息
          // options.headers["token"] = tokens; // 示例
          return options;
        },
        onResponse: (response) {
          return response; // 在这里对返回的数据进行处理,转换成你需要的格式
        },
        onError: (error) {
          formatError(error); // 在这里统一处理错误
          return error;
        },
      ),
    );
  }

  Future _request(String method, String url,
      {Map<String, dynamic> data, Function success, Function error}) async {
    try {
      Response response;
      if (method == 'GET') {
        response = await _dio.get(url, queryParameters: data);
      } else if (method == 'POST') {
        response = await _dio.post(url, data: data);
      }
      if (response.statusCode == 200) {
        var res = json.decode(response.data)['result'];
        if (success != null) {
          success(res);
        }
      } else {
        if (error != null) {
          error(response);
        }
      }
    } catch (e) {
      if (error != null) {
        error(e);
      }
    }
  }

  Future get(String url,
      {Map<String, dynamic> data, Function success, Function error}) async {
    return _request('GET', url, data: data, success: success, error: error);
  }

  Future post(String url,
      {Map<String, dynamic> data, Function success, Function error}) async {
    return _request('POST', url, data: data, success: success, error: error);
  }

  // 下载文件
  Future download(String url, String saveUrl,
      {Function success, Function error, onReceiveProgress}) async {
    try {
      var response = await _dio.download(
        _dio.options.baseUrl + url, saveUrl,
        onReceiveProgress: onReceiveProgress ?? () {},
      );

      if (response.statusCode == 200) {
        var res = json.decode(response.data)['result'];
        if (success != null) {
          success(res);
        }
      } else {
        if (error != null) {
          error(response);
        }
      }
    } catch (e) {
      if (error != null) {
        error(e);
      }
    }
  }

  // 使用FormData发送POST请求
  Future formData(String url, FormData data,
      {Function success, Function error}) async {
    return _request('POST', url, data: data, success: success, error: error);
  }

  void formatError(DioError e) {
    if (e.type == DioErrorType.CONNECT_TIMEOUT) {
      print("连接超时");
    } else if (e.type == DioErrorType.SEND_TIMEOUT) {
      print("请求超时");
    } else if (e.type == DioErrorType.RECEIVE_TIMEOUT) {
      print("响应超时");
    } else if (e.type == DioErrorType.RESPONSE) {
      print("出现异常404 503");
    } else if (e.type == DioErrorType.CANCEL) {
      print("请求取消");
    } else {
      print("未知错误");
    }
  }
}

final dioHttp = DioHttp(); // 创建DioHttp的单例,供全局使用


get请求使用方法

  dioHttp.get('https://api.example.com/items',
  data: {'param1': 'value1'},
  success: (data) {
    print('Request successful with data: $data');
  },
  error: (error) {
    print('Request failed with error: $error');
  }
);

post请求使用方法

dioHttp.post('https://api.example.com/items',
  data: {'key1': 'value1', 'key2': 'value2'},
  success: (data) {
    print('Request successful with data: $data');
  },
  error: (error) {
    print('Request failed with error: $error');
  }
);

download请求使用方法

  dioHttp.download('下载的文件的相对路径', '保存文件的绝对路径',
    onReceiveProgress: (received, total) {
        if (total != -1) {
            print("${(received / total * 100).floor()}%");
        }
    },
    success: (res) {
        print("下载成功:$res");
    },
    error: (err) {
        print("下载错误:$err");
    }
);

formData请求使用方法

  var formData = FormData.fromMap({
    'file': await MultipartFile.fromFile('文件的绝对路径', filename: 'filename.png'),
    'name': 'sample',
});

dioHttp.formData('您的API的相对路径', formData,
    success: (res) {
        print("成功:$res");
    },
    error: (err) {
        print("错误:$err");
    }
);

posted on 2020-02-24 23:17  完美前端  阅读(6621)  评论(0)    收藏  举报

导航