flutter简单封装属于自己的网络库

flutter简单封装属于自己的网络库

刚入坑flutter,虽然已经有更强大dio网络库了,但还是要学会自己封装一下,了解一下dart原生网络的实现
所谓自己动手,风衣足食,按照自己的代码习惯去做了个封装

Dart 没有像 Java 用单独的关键字 interface 来定义接口,用 class声明的类或者用abstract抽象类就可以是接口,然后可以通过关键字 implements来实现一个或多个接口。但这种方式也有局限性,因为Dart不能创建内部类,有些时候我们要像java那样直接在一个方法内去实现一个接口的回调,又不想在当前类实现这个接口,例如在java下实现一个接口回调

HttpUtil.instance.get("https://www.baidu.com",new Callback(){
	@override
  	void onFailure(int errCode, String errMsg) {
    	// TODO: implement onFailure
    	print(errMsg);
  	}
	@override
	void onResponse(String responseStr) {
	   // TODO: implement onResponse
	   print(responseStr);
	}
});

我们可以通过类似js那样的函数回调去实现,感觉这样行的通

HttpUtil.instance.get("https://www.baidu.com",
      //回调成功
      onResponse: (responseStr){
        print(responseStr);
      },
      //回调失败
      onFailure: (errCode,errMsg){
        print(errMsg);
      },
    );

下面直接贴实现的代码

  • 函数的定义
/// 通过typedef给函数取个别名
typedef void OnResponse(String responseStr); //相当于Function(String responseStr);
typedef void OnFailure(int errCode,String errMsg);//相当于Function(int errCode,String errMsg);
  • 回调接口的定义
///用抽象类实现接口
abstract class Callback{
  void onResponse(String responseStr);
  void onFailure(int errCode,String errMsg);
}
  • HttpUtil.dart
/// Create [HttpUtil] by Lonsho in 2020-04-20.
/// @Description: TODO 网络请求库
/// @Version:1.0
import 'dart:convert' show utf8,jsonEncode;
import 'dart:io' show HttpClient,ContentType,HttpStatus;
class HttpUtil {
  static HttpUtil _httpUtil;
  static HttpClient _httpClient;
  
  static HttpUtil get instance => _getInstance();
  static HttpUtil  getInstance() => _getInstance();

  /// 使用工厂模式创建单例模式
  factory HttpUtil() =>_getInstance();

  HttpUtil._(){
    ///初始化
    _httpClient =  HttpClient();
  }
  static HttpUtil _getInstance(){
      if(_httpUtil == null){
        _httpUtil = HttpUtil._();
      }
      return _httpUtil;
  }
  /// get请求
  /// [url] 请求链接
  /// [paramsMap] 请求参数
  /// [callback] 请求回调接口,如果设置了函数回调,此接口会失效
  /// [onResponse] 请求成功函数回调
  /// [onFailure] 请求失败函数回调
  /// [contentType] 可选设置请求类型
  /// [headers] 可选设置请求头
  Future<String> get(String url,{ Callback callback,
  		OnResponse onResponse,
        OnFailure onFailure,
        String contentType,
        Map<String,String> headers
      }) async{
    String result = "";
    try{
      var request = await _httpClient.getUrl(Uri.parse(url));
      if(headers!=null){
        headers.forEach((key,val){
          request.headers.add(key, val);
        });
      }
      request.headers.contentType =  _initContentType(contentType);
      var response = await request.close(); //获取网络请求响应
      if(response.statusCode == HttpStatus.ok){ //http status 200
        result = await response.transform(utf8.decoder).join();//响应内容
        if(onResponse!=null)
          onResponse(result);
        else
          callback?.onResponse(result);
      }else{
        result  ="Error postting url: $url \nHttp status ${response.statusCode}";
        if(onFailure!=null)
          onFailure(response.statusCode,result);
        else
          callback?.onFailure(response.statusCode,result);
      }
    }catch(exception){
      if(onFailure!=null)
        onFailure(0,"error => $exception");
      else
        callback?.onFailure(0,"error => $exception");
      result = "error => $exception";
    }finally{
      _httpClient.close();
    }
    return result;
  }
  /// post请求
  /// [url] 请求链接
  /// [paramsMap] 请求参数
  /// [callback] 请求回调接口,如果设置了函数回调,此接口会失效
  /// [onResponse] 请求成功函数回调
  /// [onFailure] 请求失败函数回调
  /// [contentType] 可选设置请求类型
  /// [headers] 可选设置请求头
  Future<String> post(String url,Map<String,dynamic> paramsMap,
      {Callback callback,
        OnResponse onResponse,
        OnFailure onFailure,
        String contentType,
        Map<String,String> headers
      }) async{
    var params ="";
    String result = "";
    try{
   	  //如果contentType为application/json,则需要将参数转为jsonString,否则无法正常请求
      if(contentType!=null && contentType.toLowerCase().startsWith("application/json")){
        params = jsonEncode(paramsMap);
      }else{
      	 //表单方式提交,拼接参数
         if(paramsMap!=null){
         paramsMap.forEach((key,val){
            if(params!='') params +="&";
            params+="$key=$val";
          });
        }
      }
      var request = await _httpClient.postUrl(Uri.parse(url));
      if(headers!=null){ //设置headers
        headers.forEach((name,value){
          if(request.headers.value(name)==null) //如果 header不存在
            request.headers.add(name, value); //添加header
          else
            request.headers.set(name, value); //修改header
          
        });
      }
      request.headers.contentType = _initContentType(contentType);
      request.write(params); //将参数提交到request上去
      var response = await request.close(); //获取网络请求响应
        if(response.statusCode == HttpStatus.ok){ //http status 200
          result = await response.transform(utf8.decoder).join(); //响应内容
          if(onResponse!=null) 
              onResponse(result); //请求成功函数回调
          else
              callback?.onResponse(result); //请求成功接口回调
          return result;
        } else {
          result  ="Error postting url: $url \nHttp status ${response.statusCode}";
          if(onFailure!=null)
            onFailure(response.statusCode,result);//请求失败函数回调
          else
            callback?.onFailure(response.statusCode,result);//请求失败接口回调
        }
    }catch(exception){
      //抛出异常
      if(onFailure!=null)
          onFailure(0,"error => $exception"); 
      else
          callback?.onFailure(0,"error => $exception");
      result = "error => $exception";
    } finally{
      _httpClient.close();
    }
    return result;
  }
  ///获取请求头
  ContentType _initContentType(String contentType){
    if(contentType!=null  && contentType.length!=0)
      return ContentType.parse(contentType);
    else
      return ContentType("application","x-www-form-urlencoded");
  }
 }
使用方法
  • 函数回调
void main() async{
	 HttpUtil.instance.get("https://www.baidu.com",
      //成功
      onResponse: (responseStr){
        print(responseStr);
      },
      //失败
      onFailure: (errCode,errMsg){
        print(errMsg);
      },
    );
}
  • 链式回调
void main() async{
	 HttpUtil.instance.get("https://www.baidu.com")
	 .then((res){
	 	print(res);
	 });
}
  • 接口回调
class NetTest implements Callback{
	void main() async{
		//内部实现接口
		 HttpUtil.instance.get("https://www.baidu.com",
	      //回调接口
	      callback:this,
	    );
	    //外部类实现接口
	    HttpUtil.instance.get("https://www.baidu.com",
	      //回调接口
	      callback:MyNetCallback(),
	    );
	}
	@override
  	void onFailure(int errCode, String errMsg) {
    	// TODO: implement onFailure
    	print(errMsg);
  	}
	@override
	void onResponse(String responseStr) {
	   // TODO: implement onResponse
	   print(responseStr);
	}
}
class MyNetCallback implements Callback{
	@override
  	void onFailure(int errCode, String errMsg) {
    	// TODO: implement onFailure
    	print(errMsg);
  	}
	@override
	void onResponse(String responseStr) {
	   // TODO: implement onResponse
	   print(responseStr);
	}
}
  • 同步请求

由于默认都是异步请求,如果需要用到同步请求,可以通过设置await关键字来阻塞线程实现同步

void main() async{
	 await HttpUtil.instance.get("https://www.baidu.com",
      //成功
      onResponse: (responseStr){
        print(responseStr);
      },
      //失败
      onFailure: (errCode,errMsg){
        print(errMsg);
      },
    );
    //直接赋值
    String result = await HttpUtil.instance.get("https://www.baidu.com");
    print(result);
}

如果有写得不好的地方,欢迎指正

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值