美文网首页flutter语音学习
Flutter+retrofit +dio+rxdart网络请求

Flutter+retrofit +dio+rxdart网络请求

作者: 禄子_c79b | 来源:发表于2022-04-26 17:34 被阅读0次

    pubspec.yaml:

    dependencies:
    rxdart: ^0.23.1
    retrofit: '>=3.0.0 <4.0.0'
    logger: any #for logging purpose

    dev_dependencies:
    retrofit_generator: any
    build_runner: '>1.3.0 <4.0.0'//用于生成.g文件
    json_serializable: '>4.4.0'//生成实体

    json_serializable代码在线生成网址
    运行:flutter packages pub run build_runner build 会生成 .g文件
    报错 flutter packages get
    part 'RestClient.g.dart'; //必须配置,否则无法生成.g文件

    BaseError

    abstract class BaseError {
      final int? code;
      final String? message;
    
      BaseError({this.code, this.message});
    }
    
    class NeedLogin implements BaseError {
      @override
      int get code => 401;
    
      @override
      String get message => "请先登录";
    }
    
    class NeedAuth implements BaseError {
      @override
      int get code => 403;
    
      @override
      String get message => "非法访问,请使用正确的token";
    }
    
    class UserNotExist implements BaseError {
      @override
      int get code => 408;
    
      @override
      String get message => "用户不存在";
    }
    
    class UserNameEmpty implements BaseError {
      @override
      int get code => 405;
    
      @override
      String get message => "用户名不能为空";
    }
    
    class PwdNotMatch implements BaseError {
      @override
      int get code => 409;
    
      @override
      String get message => "用户密码不正确";
    }
    
    class PwdEmpty implements BaseError {
      @override
      int get code => 406;
    
      @override
      String get message => "用户密码不能为空";
    }
    
    class OtherError implements BaseError {
      final int? statusCode;
      final String? statusMessage;
    
      OtherError({this.statusCode, this.statusMessage});
    
      @override
      int? get code => statusCode;
    
      @override
      String? get message => statusMessage;
    }
    

    HeaderInterceptor

    ///    author : luzi
    ///    date   : 2021/7/11
    ///    desc   : 请求头拦截器
    class HeaderInterceptor extends Interceptor {
      @override
      Future<void> onRequest(
        RequestOptions options,
        RequestInterceptorHandler handler,
      ) async {
        Map<String, dynamic> headers = options.headers;
        headers['clientId'] = 1; //渠道(1.APP 2.Web)
        if (Platform.isAndroid) {
          headers['systemName'] = 'Android'; //系统名称
        } else if (Platform.isIOS) {
          headers['systemName'] = 'iOS'; //系统名称
        }
    
        var time = DateTime.now().millisecondsSinceEpoch;
        headers['ts'] = time; //时间戳
        String sign = getParamsStr(options, time);
        headers['sign'] = sign; //参数加密签名
        headers['language'] = Get.locale?.countryCode ?? 'MY'; //语言环境
        headers['Accept'] = 'application/json';
        options.headers = headers;
        handler.next(options);
      }
    
      getParamsStr(RequestOptions options, int time) {
        StringBuffer stringBuffer = new StringBuffer();
        String? paramsStr;
        var method = options.method;
        if (method == 'GET') {
          if (options.queryParameters.isNotEmpty) {
            String query = options.uri.query;
            var splitArray = query.split('&');
            var splayTreeMap = new SplayTreeMap();
            splitArray.forEach((split) {
              var splitChild = split.split('=');
              splayTreeMap[splitChild[0]] = Uri.encodeQueryComponent(splitChild[1]);
            });
            paramsStr = json.encode(splayTreeMap);
            if (paramsStr.isNotEmpty) {
              stringBuffer.write('$paramsStr&');
            } else {
              stringBuffer.write('{}&');
            }
          } else {
            stringBuffer.write('{}&');
          }
        } else if (method == 'POST') {
          var data = options.data;
          if (data is FormData) {
            if (data.fields.isNotEmpty) {
              String replace = data.fields
                  .join(",")
                  .replaceAll('MapEntry', '')
                  .replaceAll('(', '')
                  .replaceAll(')', '');
              paramsStr = replace;
              if (paramsStr.isNotEmpty) {
                stringBuffer.write('{$paramsStr}&');
              } else {
                stringBuffer.write('{}&');
              }
            } else {
              stringBuffer.write('{}&');
            }
          } else {
            paramsStr = jsonEncode(data);
            if (paramsStr.isNotEmpty) {
              stringBuffer.write('$paramsStr&');
            } else {
              stringBuffer.write('{}&');
            }
          }
        }
        // NativeUtils.sendNativeData(NativeUtils.NATIVE_LOG, paramsStr.toString());
        // print(paramsStr.toString());
        stringBuffer.write('ts=$time&');
        stringBuffer.write('tmpsign=${DioManager.getInstance().signKey}');
        String toString = stringBuffer.toString().replaceAll("\"", "");
        // NativeUtils.sendNativeData(NativeUtils.NATIVE_LOG, toString);
        // print(toString);
        // Get.log.printInfo(info: '拼接后:$toString');
        var content = new Utf8Encoder().convert(toString);
        var digest = md5.convert(content);
        String md5Encode = hex.encode(digest.bytes).toUpperCase();
        Get.log.printInfo(info: 'MD5:$md5Encode');
        return md5Encode;
      }
    }
    

    BaseDio

    class BaseDio {
      BaseDio._(); // 把构造方法私有化
    
      static BaseDio? _instance;
    
      static BaseDio? getInstance() {  // 通过 getInstance 获取实例
        _instance ??= BaseDio._();
    
        return _instance;
      }
    
      Dio getDio() {
        final Dio dio = Dio();
        dio.options = BaseOptions(receiveTimeout: 55000, connectTimeout: 66000); // 设置超时时间等 ...
        dio.interceptors.add(HeaderInterceptor()); // 添加拦截器,如 token之类,需要全局使用的参数
        dio.interceptors.add(PrettyDioLogger(  // 添加日志格式化工具类
          requestHeader: true,
          requestBody: true,
          responseBody: true,
          responseHeader: false,
          compact: false,
        ));
    
        return dio;
      }
    
      BaseError getDioError(Object obj) {  // 这里封装了一个 BaseError 类,会根据后端返回的code返回不同的错误类
        switch (obj.runtimeType) {
          case DioError:
             if ((obj as DioError).type == DioErrorType.response) {
              final response = (obj as DioError).response;
              if (response!.statusCode == 401) {
                return NeedLogin();
              } else if (response!.statusCode == 403) {
                return NeedAuth();
              } else if (response.statusCode == 408) {
                return UserNotExist();
              } else if (response.statusCode == 409) {
                return PwdNotMatch();
              } else if (response.statusCode == 405) {
                return UserNameEmpty();
              } else if (response.statusCode == 406) {
                return PwdEmpty();
              } else {
                return OtherError(
                  statusCode: response.statusCode,
                  statusMessage: response.statusMessage,
                );
              }
            }
        }
    
        return OtherError();
      }
    }
    
    

    RestApi

    part 'RestClient.g.dart'; //必须配置,否则无法生成.g文件
    
    @RestApi(baseUrl: "https://uat.../")
    abstract class RestClient {
      factory RestClient({Dio? dio, String? baseUrl}) {
        dio ??= BaseDio.getInstance()!.getDio();
        return _RestClient(dio, baseUrl: baseUrl);
      }
    
      @POST("user/getImgCode.do")
      // Future<Task> getTasks(@Body()Task task);
      Future<Entity> getTasks(@Body() loginparms task);
    }
    
    //
    // @JsonSerializable()
    // class Task {
    //   String? imgToken;
    //   String? img;
    //
    //   Task({this.imgToken, this.img});
    //
    //   factory Task.fromJson(Map<String, dynamic> json) => _$TaskFromJson(json);
    //   Map<String, dynamic> toJson() => _$TaskToJson(this);
    // }
    @JsonSerializable()
    class Entity extends Object {
      @JsonKey(name: 'data')
      Data data;
    
      Entity(
        this.data,
      );
    
      factory Entity.fromJson(Map<String, dynamic> srcJson) =>
          _$EntityFromJson(srcJson);
    
      Map<String, dynamic> toJson() => _$EntityToJson(this);
    }
    
    @JsonSerializable()
    class Data extends Object {
      @JsonKey(name: 'imgToken')
      String imgToken;
    
      @JsonKey(name: 'img')
      String img;
    
      Data(
        this.imgToken,
        this.img,
      );
    
      factory Data.fromJson(Map<String, dynamic> srcJson) =>
          _$DataFromJson(srcJson);
    
      Map<String, dynamic> toJson() => _$DataToJson(this);
    }
    
    @JsonSerializable()
    class loginparms extends Object {
    
      @JsonKey(name: 'parameter')
      Parameter parameter;
    
      @JsonKey(name: 'versionCode')
      String versionCode;
    
      loginparms(this.parameter,this.versionCode,);
    
      factory loginparms.fromJson(Map<String, dynamic> srcJson) => _$loginparmsFromJson(srcJson);
    
      Map<String, dynamic> toJson() => _$loginparmsToJson(this);
    
    }
    
    
    @JsonSerializable()
    class Parameter extends Object {
    
      Parameter();
    
      factory Parameter.fromJson(Map<String, dynamic> srcJson) => _$ParameterFromJson(srcJson);
    
      Map<String, dynamic> toJson() => _$ParameterToJson(this);
    
    

    调用

    Future<void> clickLike() async {
        try {
          print('你好============123456789--0}');
      
          Parameter parameter=Parameter();
          loginparms loginparm= loginparms(parameter,"");
          Entity data = await RestClient().getTasks(loginparm); // 使用非常简单一句代码即可
          // ImageCodeBean data = await RestClient().getTasks(map); // 使用非常简单一句代码即可
          print('你好============123456789--5${data.data.imgToken}');
        } catch (e) {
          error: BaseDio.getInstance()!.getDioError(e);
          //拿到BaseError对应自定义message错误信息
          print('你好============123456789--1${BaseDio.getInstance()!.getDioError(e).message}');
    
        }
      }
    

    可参照:https://www.psvmc.cn/article/2020-05-12-flutter-start-07-http-json.html

    相关文章

      网友评论

        本文标题:Flutter+retrofit +dio+rxdart网络请求

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