精华内容
下载资源
问答
  • 主要介绍了Swift编程中的泛型解析,是Swift入门学习中的基础知识,需要的朋友可以参考下
  • C# JSON 泛型解析

    2014-09-15 22:12:13
    多层嵌套的JSON字符串也可以解析泛型T的属性要和JSON字符串反序列化的对象属性一致。
  • 最近在公司实习,要写一个解析Json的工具类。...使用GSON和泛型解析约定格式的JSON字符串 公司解析Json字符串格式常见以下两种: // data 为 object 的情况 {"code":"0","message":"success","data":{}} // data 为 a

    最近在公司实习,要写一个解析Json的工具类。本蒟蒻在翻阅了众多博客中,终于得到了一点收获,故写下这篇博客记录一下。

    本博客只是提供解决办法的思路,泛型封装可能没有那么完美,敬请原谅。

    参考博客:

    Gson 使用总结 高级用法

    搞定Gson泛型封装

    Gson解析list

    使用GSON和泛型解析约定格式的JSON字符串

    公司解析Json字符串格式常见以下两种:

    // data 为 object 的情况
    {"code":"0","message":"success","data":{}}
    // data 为 array 的情况
    {"code":"0","message":"success","data":[]}
    

    首先泛型封装Result类

    /**
    	lombok工具偷懒神器
    	导入依赖
    	<!-- https://mvnrepository.com/artifact/org.projectlombok/lombok -->
        <dependency>
        	<groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
            <version>1.18.20</version>
            <scope>provided</scope>
        </dependency>
    */
    
    import lombok.AllArgsConstructor;
    import lombok.Data;
    import lombok.NoArgsConstructor;
    
    @Data //提供getter,setter方法
    @AllArgsConstructor //提供有参构造方法 (可以没有)
    @NoArgsConstructor	//提供无参构造方法 (一定要有!)
    public class Result<T>{
        private int code;
        private String msg;
        private T data;
    }
    

    测试类(Grade.class / CarInfo.class)

    import lombok.AllArgsConstructor;
    import lombok.Data;
    import lombok.NoArgsConstructor;
    
    @Data
    @AllArgsConstructor
    @NoArgsConstructor
    public class Grade {
        private String course;
        private int score;
    //    private String level;
    }
    
    
    import lombok.AllArgsConstructor;
    import lombok.Data;
    import lombok.NoArgsConstructor;
    
    @Data
    @AllArgsConstructor
    @NoArgsConstructor
    public class CarInfo {
        private int id;
        private int carId;
        private String carNum;
        private int listType;
        private int ownerId;
        private String owner;
        private int parkType;
        private String parkTypeStr;
        private String parkinglotCode;
    }
    

    Gson泛型封装工具类

    import com.example.springbootdemo.domain.Result;
    import com.google.gson.*;
    import com.google.gson.reflect.TypeToken;
    
    import java.lang.reflect.Type;
    import java.util.ArrayList;
    import java.util.List;
    
    @SuppressWarnings("all")
    public class GsonUtils {
    
        /**
         * Gson对象的各种配置
         * @return
         */
        public static Gson getGson(){
            Gson gson = new GsonBuilder()
                    //序列化null
                    .serializeNulls()
                    // 设置日期时间格式,另有2个重载方法
                    // 在序列化和反序化时均生效
                    .setDateFormat("yyyy-MM-dd hh:mm:ss")
                    // 禁此序列化内部类
                    .disableInnerClassSerialization()
                    //生成不可执行的Json(多了 )]}' 这4个字符)
                    //.generateNonExecutableJson()
                    //禁止转义html标签
                    .disableHtmlEscaping()
                    //格式化输出
                    .setPrettyPrinting()
                    .create();
            return gson;
        }
    
        /**
         * 数组对象解析
         * @param jsonData
         * @param clazz
         * @param <T>
         * @return
         */
        public static <T> List<T> parseJsonToList(String jsonData, Class<T> clazz) {
            //Json的解析类对象
            JsonParser parser = new JsonParser();
            //将JSON的String 转成一个JsonArray对象
            JsonArray jsonArray = parser.parse(jsonData).getAsJsonArray();
            Gson gson = getGson();
            ArrayList<T> resultList = new ArrayList<>();
            for (JsonElement jsonElement : jsonArray) {
                T t = gson.fromJson(jsonElement, clazz);
                resultList.add(t);
            }
            return resultList;
        }
    
        /**
         * 处理 data 为 object 的情况
         * @param jsonData
         * @param clazz
         * @param <T>
         * @return
         */
        public static <T> Result<T> fromJsonObject(String jsonData, Class<T> clazz) {
            Gson gson = getGson();
            Type type = new TypeToken<Result<T>>(){}.getType();
            return gson.fromJson(jsonData,type);
        }
    
        /**
         * 处理 data 为 array 的情况
         * @param jsonData
         * @param clazz
         * @param <T>
         * @return
         */
        public static <T> Result<List<T>> fromJsonArray(String jsonData, Class<T> clazz){
            Gson gson = getGson();
            Type type = new TypeToken<Result<List<T>>>(){}.getType();
            return gson.fromJson(jsonData, type);
        }
    }
    

    Gson测试类

    /**
    	需要导入Junit依赖
    	<!-- https://mvnrepository.com/artifact/junit/junit -->
    	<dependency>
    		<groupId>junit</groupId>
            <artifactId>junit</artifactId>
            <version>4.12</version>
            <scope>test</scope>
        </dependency>
    */
    import com.example.springbootdemo.domain.*;
    import com.google.gson.Gson;
    import org.junit.Test;
    
    import java.util.List;
    
    @SuppressWarnings("all")//压制警告(有波浪线看起来实在太难受了)
    public class GsonTest {
    
        @Test
        public void test_fromJsonObject(){
            //创建需要需要解析的实体类
            Result<Grade> gradeRes = new Result<>(500, "操作失败", new Grade("Math", 100));
    
            Gson gson = GsonUtils.getGson();
            //转化成json字符串
            String json = gson.toJson(gradeRes);
    
            //data是Object的情况
            Result<Grade> result = GsonUtils.fromJsonObject(json, Grade.class);
            
            //解析出Result中的属性
            System.out.println(result.getdataCode());
            System.out.println(result.getMsg());
    
            //由于data属性也是一个对象,再嵌套解析一次,就可以得到需要data实体类信息
            String toJson = gson.toJson(result.getData());
            Grade grade = gson.fromJson(toJson, Grade.class);
            System.out.println(grade.getCourse());
    
        }
    
        @Test
        public void test_fromJsonArray(){
            //得到需要解析的Json字符串
            String jsonData = "{\"code\": 200,\"msg\": \"success\",\"data\": [{\"course\": \"Chinese\",\"score\":95},{\"course\":\"Math\",\"score\":21}]}";
            
            //解析外层的Result类
            Result<List<Grade>> listResult = GsonUtils.fromJsonArray(jsonData, Grade.class);
            
            //得到code 和 msg 信息
            System.out.println(listResult.getCode());
            System.out.println(listResult.getMsg());
            
            //解析内层data列表对象信息
            Gson gson = GsonUtils.getGson();
            String toJson = gson.toJson(listResult.getData());
            List<Grade> grades = GsonUtils.parseJsonToList(toJson, Grade.class);
            for (Grade grade : grades) {
                System.out.println(grade.getCourse());
            }
        }
    
        @Test
        public void test_more(){
            //思路同上,多加练习一遍
            
            String jsonData = "{\"code\":200,\"msg\":\"操作成功\",\"data\":[{\"id\":728,\"carId\":728,\"carNum\":\"浙G32T36\",\"listType\":0,\"ownerId\":null,\"owner\":null,\"parkType\":1,\"parkTypeStr\":\"普通车\",\"parkinglotCode\":\"\"},{\"id\":727,\"carId\":727,\"carNum\":\"浙G33586\",\"listType\":0,\"ownerId\":null,\"owner\":null,\"parkType\":1,\"parkTypeStr\":\"普通车\",\"parkinglotCode\":\"\"},{\"id\":726,\"carId\":726,\"carNum\":\"浙G08KV6\",\"listType\":0,\"ownerId\":null,\"owner\":null,\"parkType\":1,\"parkTypeStr\":\"普通车\",\"parkinglotCode\":\"\"},{\"id\":725,\"carId\":725,\"carNum\":\"浙GD86632\",\"listType\":0,\"ownerId\":520,\"owner\":\"方振宇\",\"parkType\":1,\"parkTypeStr\":\"普通车\",\"parkinglotCode\":\"\"},{\"id\":724,\"carId\":724,\"carNum\":\"浙G5H865\",\"listType\":0,\"ownerId\":null,\"owner\":null,\"parkType\":1,\"parkTypeStr\":\"普通车\",\"parkinglotCode\":\"\"},{\"id\":723,\"carId\":723,\"carNum\":\"浙G06L28\",\"listType\":0,\"ownerId\":null,\"owner\":null,\"parkType\":1,\"parkTypeStr\":\"普通车\",\"parkinglotCode\":\"\"},{\"id\":720,\"carId\":720,\"carNum\":\"浙G8H292\",\"listType\":0,\"ownerId\":null,\"owner\":null,\"parkType\":1,\"parkTypeStr\":\"普通车\",\"parkinglotCode\":\"\"},{\"id\":719,\"carId\":719,\"carNum\":\"浙G10H5V\",\"listType\":0,\"ownerId\":null,\"owner\":null,\"parkType\":1,\"parkTypeStr\":\"普通车\",\"parkinglotCode\":\"\"},{\"id\":718,\"carId\":718,\"carNum\":\"浙G75M27\",\"listType\":0,\"ownerId\":1178,\"owner\":\"胡迪潇\",\"parkType\":1,\"parkTypeStr\":\"普通车\",\"parkinglotCode\":\"\"},{\"id\":717,\"carId\":717,\"carNum\":\"浙GD13226\",\"listType\":0,\"ownerId\":null,\"owner\":null,\"parkType\":1,\"parkTypeStr\":\"普通车\",\"parkinglotCode\":\"\"},{\"id\":714,\"carId\":714,\"carNum\":\"浙G543KZ\",\"listType\":0,\"ownerId\":null,\"owner\":null,\"parkType\":1,\"parkTypeStr\":\"普通车\",\"parkinglotCode\":\"\"},{\"id\":713,\"carId\":713,\"carNum\":\"浙AP1J17\",\"listType\":0,\"ownerId\":1178,\"owner\":\"胡迪潇\",\"parkType\":1,\"parkTypeStr\":\"普通车\",\"parkinglotCode\":\"\"},{\"id\":712,\"carId\":712,\"carNum\":\"浙G2HP00\",\"listType\":0,\"ownerId\":null,\"owner\":null,\"parkType\":1,\"parkTypeStr\":\"普通车\",\"parkinglotCode\":\"\"},{\"id\":705,\"carId\":705,\"carNum\":\"浙G9X6Z2\",\"listType\":0,\"ownerId\":null,\"owner\":null,\"parkType\":1,\"parkTypeStr\":\"普通车\",\"parkinglotCode\":\"\"}]}";
            Result<List<CarInfo>> listResult = GsonUtils.fromJsonArray(jsonData, CarInfo.class);
            System.out.println(listResult.getCode());
            System.out.println(listResult.getMsg());
            Gson gson = GsonUtils.getGson();
            String toJson = gson.toJson(listResult.getData());
            List<CarInfo> carInfos = GsonUtils.parseJsonToList(toJson, CarInfo.class);
            for (CarInfo carInfo : carInfos) {
                System.out.println(carInfo.getCarNum());
            }
        }
    }
    

    总结:解析步骤

    • 得到需要解析的Json字符串
    • 分情况对于data是一个对象 和 是一个对象列表调用对应的方法解析出外层Result的code和msg信息
    • 再对内层data对象,仿照上一步再解析一次
    • 输出测试是否能到对象的内部属性信息即可
    展开全文
  • } } } 五、JSON解析 这里BaseBean泛型解析 使用插件FlutterJsonBeanFactory生成dart class实体类,androidStudio用户可以下载FlutterJsonBeanFactory插件,然后重启AS 泛型解析这边是刚好看到一锅子鱼这位兄弟的的...

    dio是Flutter中文网开源的一个强大的Dart Http请求库,支持Restful API、FormData、拦截器、请求取消、Cookie管理、文件上传/下载、超时等...

    最近想用flutter写个商城项目,下载一些demo后发现dio都不封装下就使用,像使用flutter的大多数都是Android开发转过来的,习惯性封装okhttp,将 Response 里返回的数据在工具类里处理好再返回业务层处理,从而大大减少代码量,使之更加清晰简洁,接下来代码走起...

     

     

    目录

    一、示例使用

    二、依赖库

    三、创建一个Dio实例以及Dio封装

    四、Dio拦截器

    五、JSON解析


     

    一、示例使用

     

    一个登陆操作的post请求

    var APILongin="http://192.168.1.144:8085/sso/login";
    
    _LoginPost() {
        ///入参
        Map<String, dynamic> map = Map();  
          map.putIfAbsent("username", () => "10086");
          map.putIfAbsent("password", () => "132456";
          DioUtils.instance.postHttp<TokenBeanEntity>(url: APILongin,parameters: map,onSuccess:            
         (datas){ 
            print(datas);
             
          }, onError: (error){
                    print("error");
          });
        }
    }
    
    _LoginPost() {
        ///入参
        Map<String, dynamic> map = Map();  
          map.putIfAbsent("username", () => "10086");
          map.putIfAbsent("password", () => "132456";
          DioUtils.instance.postHttp<TokenBeanEntity>(url: APILongin,parameters: map,onSuccess:            
         (datas){ 
            print(datas);
             
          }, onError: (error){
                    print("error");
          });
        }
    }
    
    // patch put  delect get post 都可以使用,添加 method 即可
    _LoginPut() {
        ///入参
        Map<String, dynamic> map = Map();  
          map.putIfAbsent("username", () => "10086");
          map.putIfAbsent("password", () => "132456";
          DioUtils.instance.getHttp<TokenBeanEntity>(url: APILongin,method : DioUtils.GET ,parameters: map,onSuccess:            
         (datas){ 
            print(datas);
             
          }, onError: (error){
                    print("error");
          });
        }
    }

    不需要返回参数

     

    第一种方式
    /// 无参数返回 get
     get DioUtils.instance.getHttp<UserBeanEntity>(url:"http://192.168.1.144:8085/sso/info" );
    
    
    /// 无参数返回 post 
     get DioUtils.instance.postHttp<UserBeanEntity>(url:"http://192.168.1.144:8085/sso/info" );
    
    
    第二种方式
    /// 无参数返回 get
     DioUtils.instance.postHttp<UserBeanEntity>(url:"http://192.168.1.144:8085/sso/info" ,
    method : DioUtils.GET  );
    
    
    /// 无参数返回 post
      DioUtils.instance.postHttp<UserBeanEntity>(url:"http://192.168.1.144:8085/sso/info" ,
    method : DioUtils.POST);
    
    /// 无参数返回 delete
      DioUtils.instance.postHttp<UserBeanEntity>(url:"http://192.168.1.144:8085/sso/info" ,
    method : DioUtils.DELETE);
    
     

     

     

    二、依赖库

    打开pubspec.yaml ,添加dio依赖即可,然后pubget

    dependencies:
      flutter:
        sdk: flutter
        dio: ^3.0.9 /// 添加flutter中文网最新的即可

     

    三、创建一个Dio实例以及Dio封装

      创建DioUtils.dart工具类

    import 'dart:convert';
    
    import 'package:dio/dio.dart';
    import 'package:mall/api/api.dart';
    import 'package:mall/http/BaseBean.dart';
    import 'package:mall/http/LogInterceptors.dart';
    
    class DioUtils {
      static var dio;
      static var httpUtil;
    
      static DioUtils get instance => _getInstance();
      static DioUtils _getInstance() {
        if (httpUtil == null) {
          httpUtil = DioUtils();
        }
        return httpUtil;
      }
    
      static const String API_PREFIX = 'https://novel.dkvirus.com/api/v1';
      static const int CONNECT_TIMEOUT = 10000;
      static const int RECEIVE_TIMEOUT = 10000;
    
      static const String GET = 'get';
      static const String POST = 'post';
      static const String PUT = 'put';
      static const String PATCH = 'patch';
      static const String DELETE = 'delete';
    
      ///Get请求
      void getHttp <T>( {  String url, parameters, Function(T t) onSuccess,  Function(String error) onError, }) async {
        try {
          Dio dio = createInstance();
          Response response = await dio.get(Api.BASE_URL);
          response=  await dio.get((url==null||url.isEmpty)?Api.BASE_URL : url,queryParameters: parameters);
          getResponse(url: url,method :GET ,parameters: parameters,onSuccess: onSuccess,onError: onError);
        } catch (e) {
          print(e);
        }
      }
    
      ///Post请求 && put delect...
      void postHttp<T>(
          {  String url,
            String method,
            parameters,
            Function(T t) onSuccess,
            Function(String error) onError,
          })  async {
    
        ///定义请求参数
        parameters = parameters ?? {};
        getResponse(url: url,parameters: parameters,onSuccess: onSuccess,onError: onError);
      }
      void getResponse<T>({  String url, String method, parameters, Function(T t) onSuccess,  Function(String error) onError, }) async {
        try {
          Response response;
          Dio dio = createInstance();
          switch(method){
            case GET:
              response=  await dio.get((url==null||url.isEmpty)?Api.BASE_URL : url, queryParameters: parameters);
              break;
            case PUT:
              response=  await dio.put((url==null||url.isEmpty)?Api.BASE_URL : url, queryParameters: parameters);
              break;
            case PATCH:
              response=  await dio.patch((url==null||url.isEmpty)?Api.BASE_URL : url, queryParameters: parameters);
              break;
            case DELETE:
              response=  await dio.delete((url==null||url.isEmpty)?Api.BASE_URL : url, queryParameters: parameters);
              break;
            default:
              response=  await dio.post((url==null||url.isEmpty)?Api.BASE_URL : url, data: parameters);
              break;
          }
    /// 拦截http层异常码
          if (response.statusCode == 200) {
    /// 这里做baseBena泛型解析,封装 并拦截后台code异常码,可拦截自定义处理 
            BaseBean<T>bean=BaseBean.fromJson(response.data);
            if(bean.code==200&&onSuccess != null){
    /// 返回泛型Bean
              onSuccess( bean.data);
            }else{
              onError(bean.message);
            }
          } else {
            throw Exception('statusCode:${response.statusCode}+${response.statusMessage}');
          }
        } catch (e) {
          print('请求出错:' + e.toString());
          onError(e.toString());
        }
      }
      /// @ url 请求链接
      ///@ parameters 请求参数
      ///@ metthod 请求方式
      ///@ onSuccess 成功回调
      ///@ onError 失败回调
      Future<Map> request<T>(String url,
          {parameters,
            method,
            Function(T t) onSuccess,
            Function(String error) onError}) async {
        parameters = parameters ?? {};
        method = method ?? 'GET';
    
        /// 请求处理
        parameters.forEach((key, value) {
          if (url.indexOf(key) != -1) {
            url = url.replaceAll(':$key', value.toString());
          }
        });
    
        Dio dio = createInstance();
        //请求结果
        var result;
        try {
          Response response = await dio.request(url,
              data: parameters, options: new Options(method: method));
          result = response.data;
          if (response.statusCode == 200) {
            if (onSuccess != null) {
              var data = json.decode(response.data) ;
              onSuccess(data);
            }
          } else {
            throw Exception('statusCode:${response.statusCode}');
          }
        } on DioError catch (e) {
          print('请求出错:' + e.toString());
          onError(e.toString());
        }
    
        return result;
      }
    /// 初始化DIO
      Dio createInstance() {
        if (dio == null) {
          /// 全局属性:请求前缀、连接超时时间、响应超时时间
          var options = BaseOptions(
            connectTimeout: 15000,
            receiveTimeout: 15000,
            //responseType: ResponseType.plain,
            validateStatus: (status) {
              // 不使用http状态码判断状态,使用AdapterInterceptor来处理(适用于标准REST风格)
              return true;
            },
            //  baseUrl: "http://poetry.huhustory.com/",
          );
          dio = new Dio(options);
    /// 增加拦截器并添加heands头 token
          dio.interceptors.add(LogInterceptors(dio));
        }
    
        return dio;
      }
      /// 清空 dio 对象
      clear() {
        dio = null;
      }
    }

      

    四、Dio拦截器

    import 'package:dio/dio.dart';
    import 'package:mall/utils/shared_preferences_util.dart';
    
    ///日志拦截器
    class LogInterceptors extends InterceptorsWrapper {
      Dio dio;
    
      LogInterceptors(this.dio);
    
      @override
      Future onRequest(RequestOptions options) async {
        print("========================请求数据===================");
        print("【请求baseUrl】${options.uri}");
    //    print("【请求path】${options.path}");
    //    print("【请求headers】${options.headers.toString()}");
        print("【请求参数】${options.data.toString()}");
        dio.lock();
         await SharedPreferencesUtils.getToken().then((token) {
          if(token==null||token.toString().isEmpty){
            return;
          }
          Map<String,String> parms = {"Authorization" : "Bearer "+token};
          options.headers.addAll(parms);
        });
        dio.unlock();
        return options;
        return super.onRequest(options);
      }
    
      @override
      Future onResponse(Response response) {
        print("【返回statusCode】${response.statusCode}");
    //    print("【返回headers】${response.headers.toString()}");
    //    print("【返回extra】${response.extra.toString()}");
        print("【返回data】${response.data.toString()}");
        return super.onResponse(response);
      }
    
      @override
      Future onError(DioError err) {
        print("========================请求错误===================");
        formatError(err);
        return super.onError(err);
      }
    
      ///  error统一处理
      void formatError(DioError e) {
        if (e.type == DioErrorType.CONNECT_TIMEOUT) {
          print(e.hashCode.toString() + "连接超时");
        } else if (e.type == DioErrorType.SEND_TIMEOUT) {
          print(e.hashCode.toString() + "请求超时");
        } else if (e.type == DioErrorType.RECEIVE_TIMEOUT) {
          print(e.hashCode.toString() + "响应超时");
        } else if (e.type == DioErrorType.RESPONSE) {
          print(e.hashCode.toString() + "出现异常404 503");
        } else if (e.type == DioErrorType.CANCEL) {
          print(e.hashCode.toString() + "请求取消");
        } else {
          print("message =${e.message}");
        }
      }
    }
    

    五、JSON解析

     

    这里BaseBean<UserBeanEntity>泛型解析 使用插件FlutterJsonBeanFactory生成dart class实体类,androidStudio用户可以下载FlutterJsonBeanFactory插件,然后重启AS

    泛型解析这边是刚好看到一锅子鱼这位兄弟的的博客改写的,大家可以去看下

    创建 BaseBean<T> ,安装好FlutterJsonBeanFactory的时候new JsonToDartBeanAction,会自动生成json_convert_content.dart文件在项目中,并且会在JsonConvert里生成fromJsonAsT方法

    import 'package:mall/generated/json/base/json_convert_content.dart';
    
    ///convert和FlutterJsonBeanFactory结合解析
    class BaseBean<T> {
    	T data;
    	int code;
    	String message;
    
    	BaseBean({this.data, this.code, this.message});
    
    	BaseBean.fromJson(Map<String, dynamic> json) {
    		if (json['data'] != null&&json['data']!='null') {
    			data = JsonConvert.fromJsonAsT<T>(json['data']);
    		}
    		code = json['code'];
    		message = json['message'];
    	}
    
    	Map<String, dynamic> toJson() {
    		final Map<String, dynamic> data = new Map<String, dynamic>();
    		if (this.data != null) {
    			data['data'] = this.data;
    		}
    		data['code'] = this.code;
    		data['message'] = this.message;
    		return data;
    	}
    }
    
    import 'package:mall/generated/json/base/json_convert_content.dart';
    
    class TokenBeanEntity with JsonConvert<TokenBeanEntity> {
    	String tokenHead;
    	String token;
    }
    
    

     

    完结...


    展开全文
  • flutter 封装dio+json泛型解析

    千次阅读 2020-07-03 14:33:55
    是FlutterJsonBeanFactory生成的,判断了Object或List类型分别解析 使用 HttpManager.getInstance().get("banner/json", null, (data) { BaseEntity> baseEntity = BaseEntity.fromJson(data); baseEntity.data....

    通过例子比较了

    HttpClient,http和dio,github star和功能丰富性,选择在项目中使用dio请求网络;
    json_serializable+json_annotation可以作为json序列化方式,不喜欢这种方式;

    我选择的在https://javiercbk.github.io/json_to_dart/把基类json生成dart class实体类,

    其他类使用插件FlutterJsonBeanFactory生成dart class实体类,插件安装后记得重启IDE

    pubspec.yaml 添加 dio依赖

    dio: ^3.0.9

    网络工具类

    import 'dart:convert';
    import 'dart:io';
    
    import 'package:dio/dio.dart';
    
    class HttpManager {
      static HttpManager _instance;
    
      static HttpManager getInstance() {
        if (_instance == null) {
          _instance = new HttpManager();
        }
        return _instance;
      }
    
      HttpManager() {
        dio = createInstance();
      }
    
      /// global dio object
      static Dio dio;
    
      /// default options
      static const String _BASE_URL = "https://www.wanandroid.com/";
      static const int _CONNECT_TIMEOUT = 15000;
      static const int _RECEIVE_TIMEOUT = 15000;
    
      /// http request methods
      static const String GET = 'get';
      static const String POST = 'post';
      static const String PUT = 'put';
      static const String PATCH = 'patch';
      static const String DELETE = 'delete';
    
      get<T>(
          String url, FormData param, Function onSuccess, Function onError) async {
        requestHttp<T>(
          url,
          param: param,
          method: GET,
          onSuccess: onSuccess,
          onError: onError,
        );
      }
    
      post<T>(
          String url, FormData param, Function onSuccess, Function onError) async {
        requestHttp<T>(
          url,
          param: param,
          method: POST,
          onSuccess: onSuccess,
          onError: onError,
        );
      }
    
      /// T is Map<String,dynamic>  or List<dynamic>
      static requestHttp<T>(
        String url, {
        param,
        method,
        Function(T map) onSuccess,
        Function(String error) onError,
      }) async {
        dio = createInstance();
        try {
          Response response = await dio.request(
            url,
            data: param,
            options: new Options(method: method),
          );
          if (response.statusCode == HttpStatus.ok) {
            onSuccess(json.decode(response.data));
          } else {
            onError("【statusCode】${response.statusCode}");
          }
        } on DioError catch (e) {
          /// 打印请求失败相关信息
          print("【请求出错】${e.toString()}");
          onError(e.toString());
        }
      }
    
      /// 创建 dio 实例对象
      static Dio createInstance() {
        if (dio == null) {
          /// 全局属性:请求前缀、连接超时时间、响应超时时间
          var options = new BaseOptions(
            baseUrl: _BASE_URL,
            connectTimeout: _CONNECT_TIMEOUT,
            receiveTimeout: _RECEIVE_TIMEOUT,
            responseType: ResponseType.plain,
    //        contentType: Headers.jsonContentType,
          );
          dio = new Dio(options);
          dio.interceptors.add(new LogInterceptors());
        }
        return dio;
      }
    
    //  /// request method
    //  static Future<Map> request<T>(
    //      String url, {
    //        param,
    //        method,
    //        Function onSuccess,
    //        Function onError,
    //      }) async {
        param = param ?? {};
    //
    //    /// restful 请求处理
    //    /// /gysw/search/hist/:user_id        user_id=27
    //    /// 最终生成 url 为     /gysw/search/hist/27
    //    param.forEach((key, value) {
    //      if (url.indexOf(key) != -1) {
    //        url = url.replaceAll(':$key', value.toString());
    //      }
    //    });
    //
    //    dio = createInstance();
    //    var result;
    //    try {
    //      Response response = await dio.request(
    //        url,
    //        data: param,
    //        options: new Options(method: method),
    //      );
    //      result = json.decode(response.data);
    //      if (response.statusCode == HttpStatus.ok) {
    //        onSuccess(result);
    //      } else {
    //        onError("【statusCode】${response.statusCode}");
    //      }
    //    } on DioError catch (e) {
    //      /// 打印请求失败相关信息
    //      print("【请求出错】${e.toString()}");
    //      onError(e.toString());
    //    }
    //    return result;
    //  }
      /// 清空 dio 对象
      static clear() {
        dio = null;
      }
    }
    
    ///日志拦截器
    class LogInterceptors extends InterceptorsWrapper {
      @override
      Future onRequest(RequestOptions options) {
        print("【请求baseUrl】${options.baseUrl}");
        print("【请求path】${options.path}");
        print("【请求headers】${options.headers.toString()}");
        //todo 参数拦截
        print("【请求参数】${options.data.toString()}");
        return super.onRequest(options);
      }
    
      @override
      Future onResponse(Response response) {
        print("【返回statusCode】${response.statusCode}");
        print("【返回headers】${response.headers.toString()}");
        print("【返回extra】${response.extra.toString()}");
        print("【返回data】${response.data.toString()}");
        return super.onResponse(response);
      }
    
      @override
      Future onError(DioError err) {
        print(err.toString());
        print(err.response?.toString());
        return super.onError(err);
      }
    }

    相应基类定义

    ///convert和FlutterJsonBeanFactory结合解析
    class BaseEntity<T> {
      T data;
      int errorCode;
      String errorMsg;
    
      BaseEntity({this.data, this.errorCode, this.errorMsg});
    
      BaseEntity.fromJson(Map<String, dynamic> json) {
        if (json['data'] != null&&json['data']!='null') {
          data = JsonConvert.fromJsonAsT<T>(json['data']);
        }
        errorCode = json['errorCode'];
        errorMsg = json['errorMsg'];
      }
    
      Map<String, dynamic> toJson() {
        final Map<String, dynamic> data = new Map<String, dynamic>();
        if (this.data != null) {
          data['data'] = this.data;
        }
        data['errorCode'] = this.errorCode;
        data['errorMsg'] = this.errorMsg;
        return data;
      }
    }

    JsonConvert.fromJsonAsT<T>(json['data']); 是FlutterJsonBeanFactory生成的,判断了Object或List类型分别解析

    使用

    HttpManager.getInstance().get("banner/json", null, (data) {
          BaseEntity<List<BannerEntity>> baseEntity = BaseEntity.fromJson(data);
          baseEntity.data.forEach((element) {
            print(element.imagePath);
          });
        }, (error) {
          ToastUtil.showToastCenter(error);
        });

    post请求

    var map = Map<String, String>();
        map["username"] = "江渚清沨";
        map["password"] = "xxxxx";
        FormData formData = FormData.fromMap(map);
        HttpManager.getInstance().post("user/login", formData, (data) {
          BaseEntity<UserEntity> baseModel = BaseEntity.fromJson(data);
          print("解析${baseModel.errorMsg}");
        }, (error) {
          ToastUtil.showToastCenter(error);
        });

    代码地址  https://gitee.com/jiangzhuqingfeng/flutter_demo.git

    展开全文
  • java_泛型解析

    2019-04-30 17:35:52
    泛型 在java中,泛型是无处不在,当然,泛型的基本思维和概念是简单,可是在他后面有容器类,是非常重要的 1、 基本概念和原理 泛型 : 就是广泛的类型。类,接口,和方法代码 可以应用于非常广泛的类型,代码...

    泛型

    在java中,泛型是无处不在,当然,泛型的基本思维和概念是简单,可是在他后面有容器类,是非常重要的

    1、 基本概念和原理

    1. 泛型 : 就是广泛的类型。类,接口,和方法代码 可以应用于非常广泛的类型,代码与它们能够操作的数据类型不再绑定在一起,同一套代码可以用于多种数据类型

    泛型类

    1. 代码展现

    public class Pair<T>{
        T first;
        T second;
        public Pair(T first , T second){
            this.first = first;
            this.second = second;
        }
        public T getFirst(){
            return first;
        }
        public T getScond(){
            return second;
        }
    }
    

    2. 代码的类型就是T ,

    3. T 表示的就是**类型参数 ** ,泛型就是类型参数化,处理的数据类型不是固定的,而是可以作为参数传入

    public static void main(String[] args){
        Pair<Integer> minmax = new Pair<Integer>(1,100);
        Integer min = minmax.getFirst();
        Integet max = minmax.getSecond();
    }
    

    4. 在<> 中就是要传入的参数,

    5. 在泛型类中,类型参数可以多个,只需要用逗号隔开。

    public class Pair<U,V>{
        U first;
        V second;
        public Pair(U first , V second){
            this.first = first;
            this.second = second;
        }
        public U getFirst(){
            return first;
        }
        public V getScond(){
            return second;
        }
    }
    

    6. 使用多参数的泛型类

    Pair<Integer,String> minmax = new Pair<>(1,"小我")

    7. 为什么 不是用Object 而是使用泛型呢,两者有什么区别

    • 在java中 有 java编译器和java虚拟机 ,编译器将java 源代码 转换为 .class文件,虚拟机加载并运行.class文件。
    • 对于泛型类,java编译器会将泛型代码转换为普通的非泛型代码,就像上面的普通Pair类代码及其使用代码一样,将类型参数T擦除,替换为Object,插入必要的强制类型转换。
    • java虚拟机实际执行的时候,它 是不知道泛型这回事的,只知道普通的类和代码

    8. 泛型的好处

    1. 更好的安全性
    2. 更好的可读性
    3. 如果使用Object ,代码写错,不会有错误提示,但是在运行的时候,会报错

    容器类

    1. 什么是容器类

    1. 简单说: 就是容纳并管理多项数据的类,数组就是用来管理多项数据的,但数组有很多限制,比如长度,插入,删除,效率比较低

    2. 就比如,前面实现的动态数组,就是一个容器,,

      动态数组博客地址

    3. 作为一个容器类,他容纳的数据类型是作为参数传递过来的

    泛型方法

    1. 栗子

    public static <T> int indexOf(T[] arr , T elm){
        for(int i=0; i< arr.length;i++){
            if(arr[i].equals(elm)){
                return i;
            }
        }
        return -1;
    }
    
    1. 在调用这个寻找的方法,不需要指定类型

    泛型接口

    1. 栗子

    public interface Comparable<T>{
        public int compareTo(T o);
    }
    public interface Comparator<T>{
        intt compare(T o1,T o2);
        boolean equals(Object obj);
    }
    

    2. 实际使用的注意

    1. 实现接口,应该指定具体的类型,。

    类型参数的限定

    在java中,参数必须为给定的上界类型或其子类型,这个限定是通过extends 关键字来表示的,

    1. 上界为某个具体类

    • 比如 上面的Pair类,可以定义一个子类NuymberPair ,限定两个类型参数必须为Number,

    • 代码:

      public class NumberPair<U extends Number,V extends Number> extends Pair<U,V>{
          public NumberPair(U first , V second){
              super(first,second);
          }
      }
      
    • 如果限制了,,就只能使用这个一个类型。

    • 指定 边界后,类型擦除时,就不会转换为object 了,而是转换为他的边界类型

    2. 上界为某个接口

    • 比如算法中使用的Comparable 接口

      public static <T extends Comoparable> T max(T[] arr)}{
          T max = arr[0];
          for(int i=1;i< arr.length; i++){
              if(arr[i].compareTo(max) > 0){
                  max = arr[i];
              }
          }
          return max;
      }
      
    • max方法 实现类型参数 设置了一个边界 Comparable ,T 必须实现Comparable 接口 ,

    • 但是 上述 ----- 会显示 警告信息: 因为Comparable 是一个泛型接口,他也需要一个类型接口

      public static <T extends Comparable<T>> T max(T[] arr){}
      
    • 对于 上面的 令人费解的语法形式, 叫做 递归类型限制 可以解读 -———— T 表示 一种数据类型,必须实现Comparable接口,且必须可以与相同类型的元素进行比较。

    3. 上界为其他类型参数

    上面的限定都是指定一个明确的类或接口,java支持一个类型参数以另一个类型参数作为上界。

    • 根据上面的类,添加一个方法

      public void addAll(DynamicArray<E> c){
          for(int i=0; i< c.size ; i++){
              add(c.get(i))
          }
      }
      
    • 如果 像上面写的,发现会有一些局限性,,,

      DynamicArray<Number> numbers = new DynamicArray<>();
      DynamicArray<Integer> ints = new DynamicArray<>();
      ints.add(100);
      numbers.addAll(ints);//会显示报错
      
      • 将子类的容器,加入父类的容器,会报错, ,破坏了类型安全的保证

      • 原因是 : DynamicArray 并不是 DynamicArray 的 子类,虽然Integer 是Number的子类,但不是相关的,所以不能辅助,,这点很重要

      • 改变代码

        public <T extends E> void addAll(DynamicArray<E> c){
            for(int i=0; i< c.size ; i++){
                add(c.get(i))
            }
        }
        
      • E 是 DynamicArray 的类型参数,T是 addAll 的类型参数,T 的上界限定为 E ,这样就可以了

    总结

    1. 泛型 是计算机 程序中一种重要的思维方式,他将数据结构 和算法 与 数据类型 相分离,让同一套数据结构和算法 能够应用于各种数据类型,而且保证类型安全,提供可读性。

    2、解析通配符

    1. 更简洁的参数类型限定

    1. 将上面的add 方法替换

      public void addAll(DynamicArray<? extends E> c){
          for(int i=0; i< c.size ; i++){
              add(c.get(i))
          }
      }
      
    2. 这个方法 没有定义类型参数,c 的类型 是DynamicArray<? extends E> ,? 表示通配符,<? extends E> 表示限定通配符

    3. 为什么 两种不同的写法,,但是效果是一样的

      1. 用于定义类型参数,它声明一个类型参数T ,可放在泛型类定义中类名后面,泛型方法返回值前面
      2. <? extends E> 用于==实例化类型==参数,它用于实例化泛型变量中的类型参数,只是这个具体类型参数是未知的,只知道他是E或 E的某个子类型

    2. 理解通配符

    1. 无限定通配符 : DynamicArray<?>

    2. 上面的indexOf 方法就可以这样使用

      public static int indexOF(DynamicArray<?> arr, object elm);
      or
      public static <T> indexOF(DynamicArray<T> arr, object elm);
      
    3. 但是上面的 两种通配符 都有一个重要的限制 : 只能读,不能写

    DynamicArray<Integer> ints = new DynamicArray<>();
    DynamicArray<? extends Number> numbers = ints;
    Integer a = 200;
    numbers.add(a);//错误
    numbers.add((Number)a);//错误
    numbers.add((Object)a);//错误
    
    • 因为无法判断类型 ,所以直接禁止掉了
    1. 但是也不是 什么时候,都可以使用无限定通配符

      1. 如果参数类型之间有依赖关系,也只能使用类型参数
      2. 如果 返回值 依赖于 类型参数,也不能用通配符

    总结

    • 通配符形式都可以用类型参数的形式替代,通配符能做的,类型参数也能做
    • 通配符可以减少类型参数,形式更加的简单,所以能用就用
    • 如果类型参数之间有依赖关系,或者返回值依赖类型参数,或者需要写操作,则不能使用通配符
    • 通配符和类型参数往往配合使用

    3. 超类型通配符

    1. 写法为<? super E> 称为超类型通配符,表示 E的某个父类型,

    2. 例子代码

      public void copyTo(DynamicArray<E> dest){
          for(int i=0;i<size;i++){
              dest.add(get(i));
          }
      }
      
    3. 但是 子 将Integer对象加入 Number容器 会编译错误, 但是可以通过 超类型通配符解决

    public void copyTo(DynamicArray<? super E> dest){
        for(int i=0;i<size;i++){
            dest.add(get(i));
        }
    }
    
    1. 还有另一个场合就是 — Comparable/Comparator 接口

      1. 如果当 base 类 实现 Comparable接口 , child没有 实现,,那么当他们根据 实例变量 进行比较,,使用前面所说的max方法比较,会报错,,

      2. 因为, child 实现的不是Comparable 而是 Comparable ,

      3. 所以修改max方法

        public static <T extends Comoparable<? super T>> T max(T[] arr)}
        
    2. 通配符比较

      1. <? super E> 灵活,或比较,让对象可以写入父类型的容器,使父类型容器的比较方法 应用于子类对象,它不能 被类型 参数形式替代
      2. <?> and <? extends E> 用于灵活读取,使方法可以读取E 或E的任意子类型的容器对象,他们可以用类型参数代替,通配符更加方便
    展开全文
  • android使用gson和泛型解析服务器回调的封装
  • java.lang.ClassCastException: ...be cast to X 有问题的写法: data = (A) JSON.parseObject(str,A.class); 修改之后 data = JSON.parseObject(str, new TypeReference<A<...
  • 因为最近在做Gson解析网络数据的时候遇到一个现象,当我们在服务器拿到的Json数据,一般格式都是比较统一的,只是内容有一定的变化,具体事例如下: // data 为 object 的情况 {"code":"0","message":"success",...
  • 泛型解析JSON数据封装

    千次阅读 2017-08-24 16:45:20
    返回的数据进行解析,这时我们就可以使用此种解析方式来解析。 Gson解析 public class HttpUtils { private static Gson mGson; public static void getRequest (String url, Map, String> ...
  • C#Json泛型解析

    2018-07-17 16:54:25
    需要注意的是,创建类的名字要和Json里的名字一模一样,顺序也要一样,才能使用泛型来自动完成解析。 Json里面对象的键值必要要和定义的类里面的字段或者属性保持一致; Jsons[] arrayJson = JsonMapper.To...
  • 这样如果传的不是泛型,而是一个包含泛型的类(比如公共的返回bean),最后解析出来的T是LinkedTreeMap,比如这样: Type type = new TypeToken<BaseResponse<T>>() {}.getType(); BaseResponse jsonBean = gson....
  • 泛型解析

    2019-05-21 10:45:00
    泛型 1、泛型类 public class Pig<A,B,C> { private A pname; private B page; private...
  • Java 泛型解析

    2021-02-14 15:25:37
    泛型解析 1.泛型概述 1.1 什么是泛型 1.2 为什么引入泛型 2. 集合中使用泛型 3. 自定义泛型类 4. 自定义泛型方法 5. 通配符 1.泛型概述 1.1 什么是泛型 泛型是 JDK5 出现的新特性。泛型的本质是类型参数化,即在不...
  • 在Retrofit网络请求数据,使用泛型解析json时,出现了com.google.gson.internal.LinkedTreeMap cannot be cast to com.xylife.community.bean.Exercise的异常,折腾了好久总算解决了。 先看下异常log:java.lang....
  • 前言 整理一下Java泛型的相关知识,算是比较基础...其所操作的数据类型被指定为一个参数(type parameter)这种参数类型可以用在类、接口和方法的创建中,分别称为泛型类、泛型接口、泛型方法。 泛型泛型类(g...
  • 在进行网络请求的时候,返回结构体内的data不一定是什么类型,本文记录如何解析各个类型
  • retrofit请求网络时,针对泛型解析

    千次阅读 2016-01-22 17:31:59
    由于在定义的BaseResponse类中data的类型是泛型,是在运行时动态给定的,所以gson解析时如果data对应的是jsonObject则会解析成LinkedTreeMap,如果是JsonArray则会解析成ArrayList public class BaseResponse T...
  • Android Gson 泛型解析

    千次阅读 2019-04-11 19:37:13
    解析 bean 类: public class ResponseObj<T> { private String code; private String toastMessage; private T data; public String getCode() { return code; } public voi...
  • Java泛型解析(02):通配符限定  考虑一个这种场景。计算数组中的最大元素。 [code01] public class ArrayUtil { public static &lt;T&gt; T max(T[] array) { if (array == null || 0 == array.....
  • Java泛型解析

    2020-03-11 12:10:29
    泛型之前 泛型 1、Java中的泛型是什么 ? 使用泛型的好处和意义是什么 2、编译器是如何处理泛型的 3、什么是类型擦除 4、什么是泛型中的限定通配符和非限定通配符 5、通配符 6、泛型带来的问题 7、总结 8、...
  • Gson使用泛型解析

    千次阅读 2015-02-25 10:33:20
    Gson是Google开发出来的一个快捷解析JSON的工具包,避免了传统的JSONArray、JSONObject的繁琐代码解析,使得程序开发对JSON的... 使用GSON和泛型解析约定格式的JSON串。  背景介绍:  1.使用GSON来进行JS
  • Java泛型解析(01):认识泛型

    千次阅读 2014-10-12 16:32:39
    Java从1.0版本到现在的8,中间Java5中发生了一个很重要的变化,那就是泛型机制的引入。Java5引入了泛型,主要还是为了满足在1999年指定的最早Java规范之一。经过了5年左右的时间,专家组定义了一套泛型规范,实现后...
  • Fast JSON 泛型解析

    2018-01-31 16:10:00
    2019独角兽企业重金招聘Python工程师标准>>> ...
  • java泛型解析

    2013-06-07 16:48:08
    泛型(Generic type 或者 generics)是对 Java 语言的类型系统的一种扩展,以支持创建可以按类型进行参数化的类。可以把类型参数看作是使用参数化类型时指定的类型的一个占位符,就像方法的形式参数是运行时传递的值...
  • Java实现泛型解析工具类-GenericsUtils背景代码实现 背景 在很多编程场景中,我们需要指导某个对象是属于那个泛型类型的对象或者是那个泛型类型的子类对象,有时需要指导方法返回值对应的泛型参数实际什么类型,那么...
  • Java基础之泛型解析

    2020-10-02 11:35:49
    什么是泛型 泛型就是广泛的类型,同一套代码可以在多种类型中使用,使代码的可重用性更高。泛型是JDK1.5加的新特性。 为什么使用泛型 加入现在有对int类型数值求和的需求,那我们可能会这样写: public int sumInt...
  • gson引用泛型解析

    千次阅读 2016-08-24 17:21:44
    android需要跟服务端交互数据,返回数据时json数据,需要解析,引用泛型很大程度上简化代码的解析。1、引入jar: compile 'com.google.code.gson:gson:2.7'2、返回数据类型大致类型: (1){“code”:”0”,”message...
  • gson 解析泛型和将泛型转为json字符串

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 65,177
精华内容 26,070
关键字:

泛型解析