• Flutter json 和 对象之间的转换


    这里写的是 Flutter 自带的 convertjson 转换。下面以 3 个实例来说明。

    一、自定义对象中不再嵌套其他对象:

    class Student {
      String name;
      int age;
    
      Student({
        required this.name,
        required this.age,
      });
    
      /// 因为调用 jsonDecode 把 json 串转对象时,jsonDecode 方法的返回值是 map 类型,无法直接转成 Student 对象
      factory Student.fromJson(Map<String, dynamic> parsedJson) {
        return Student(
          name: parsedJson['name'],
          age: parsedJson['age'],
        );
      }
    
      /// 这个方法在对象转json的时候自动被调用
      Map toJson() {
        Map map = Map();
        map["name"] = this.name;
        map["age"] = this.age;
        return map;
      }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    对象转 json 抽成方法了:
    String _getJsonStr() {
      Student student = Student(name: "pig", age: 33);
      String jsonStr = jsonEncode(student);
      return jsonStr;
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5

    调用如下:

     String data = _getJsonStr();
     print("data = $data");
    
    • 1
    • 2

    输出如下:
    在这里插入图片描述

    json 串转对象
    String jsonStr = _getJsonStr();
    var data = jsonDecode(jsonStr);
    print("data = $data, runtimeType = ${data.runtimeType}");
    
    • 1
    • 2
    • 3

    输出如下:
    在这里插入图片描述
    可以看出这个 data 类型是 map 类型,此时还没有转成 Student 对象。
    要转成 Student 需要如下调用:

     Student st = Student.fromJson(data);
     print("st runtimeType = ${st.runtimeType}, st name = ${st.name}");
    
    • 1
    • 2

    在这里插入图片描述
    通过 Student.fromJson 的方法,把 map 转成 Student 对象,Student.fromJson 是定义在 Student 类中的,如下:

     /// 因为调用 jsonDecode 把 json 串转对象时,jsonDecode 方法的返回值是 map 类型,无法直接转成 Student 对象
     factory Student.fromJson(Map<String, dynamic> parsedJson) {
       return Student(
         name: parsedJson['name'],
         age: parsedJson['age'],
       );
     }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7

    方法很简单,就是把 map 中的数据取出来,构造成 Student 对象。

    对象中嵌套对象

    Student 类中嵌套 Grade 对象:

    class Student {
      String name;
      int age;
      Grade grade;
    
      Student({required this.name,
        required this.age,
        required this.grade,
      });
    
      factory Student.fromJson(Map<String, dynamic> parsedJson) {
        return Student(
          name: parsedJson['name'],
          age: parsedJson['age'],
          grade: Grade.fromJson(parsedJson['grade']),
        );
      }
    
      Map toJson() {
        Map map = Map();
        map["name"] = this.name;
        map["age"] = this.age;
        map["grade"] = this.grade;
        return map;
      }
    }
    
    class Grade {
      String className;
      String title;
    
      Grade({required this.className, required this.title});
    
      factory Grade.fromJson(Map<String, dynamic> parsedJson) {
        return Grade(
          className: parsedJson['className'],
          title: parsedJson['title'],
        );
      }
    
      Map toJson() {
        Map map = Map();
        map["className"] = this.className;
        map["title"] = this.title;
        return map;
      }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47

    没什么大的改变,主要就是 Student.fromJson 中获取 grade 的方式和获取普通变量的方式不一样,如下:

      factory Student.fromJson(Map<String, dynamic> parsedJson) {
        return Student(
          name: parsedJson['name'],
          age: parsedJson['age'],
          grade: Grade.fromJson(parsedJson['grade']),
        );
      }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7

    因为 parsedJson['grade'] 得到的仍然是 map 类型,所以需要通过 Grade.fromJson 方法转成 Gradle 对象。

    除了嵌套对象外还嵌套对象集合

    Student 中除了包含 Grade 对象外,还包含 Address 的列表。

    各个类的定义如下:

    class Student {
      String name;
      int age;
      Grade grade;
      List<Address> addressList;
    
      Student(
          {required this.name,
            required this.age,
            required this.grade,
            required this.addressList});
    
      factory Student.fromJson(Map<String, dynamic> parsedJson) {
        /// addressList 是列表 和 grade 的处理方式不一样
        /// 方式 1
        List<Address> addressL = [];
        var list = parsedJson['addressList'];
        for (var address in list) {
          addressL.add(Address.fromJson(address));
        }
    
        /// 方式 2,显然方式2的更加优雅
        List<Address> addressL2 = (parsedJson['addressList'] as List<dynamic>)
            .map((e) => Address.fromJson(e))
            .toList();
    
        return Student(
          name: parsedJson['name'],
          age: parsedJson['age'],
          grade: Grade.fromJson(parsedJson['grade']),
          addressList: addressL2,
        );
      }
    
      Map toJson() {
        Map map = Map();
        map["name"] = this.name;
        map["age"] = this.age;
        map["grade"] = this.grade;
        map['addressList'] = this.addressList;
        return map;
      }
    }
    
    
    class Grade {
      String className;
      String title;
    
      Grade({required this.className, required this.title});
    
      factory Grade.fromJson(Map<String, dynamic> parsedJson) {
        return Grade(
          className: parsedJson['className'],
          title: parsedJson['title'],
        );
      }
    
      Map toJson() {
        Map map = Map();
        map["className"] = this.className;
        map["title"] = this.title;
        return map;
      }
    }
    
    class Address {
      String street;
      String district;
    
      Address({required this.street, required this.district});
    
      factory Address.fromJson(Map<String, dynamic> parsedJson) {
        return Address(
          street: parsedJson['street'],
          district: parsedJson['district'],
        );
      }
    
      Map toJson() {
        Map map = Map();
        map["street"] = this.street;
        map["district"] = this.district;
        return map;
      }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59
    • 60
    • 61
    • 62
    • 63
    • 64
    • 65
    • 66
    • 67
    • 68
    • 69
    • 70
    • 71
    • 72
    • 73
    • 74
    • 75
    • 76
    • 77
    • 78
    • 79
    • 80
    • 81
    • 82
    • 83
    • 84
    • 85
    • 86

    主要的区别依然是 Student.fromJson

    factory Student.fromJson(Map<String, dynamic> parsedJson) {
        /// addressList 是列表 和 grade 的处理方式不一样
        /// 方式 1
        List<Address> addressL = [];
        var list = parsedJson['addressList'];
        for (var address in list) {
          addressL.add(Address.fromJson(address));
        }
    
        /// 方式 2,显然方式2的更加优雅
        List<Address> addressL2 = (parsedJson['addressList'] as List<dynamic>)
            .map((e) => Address.fromJson(e))
            .toList();
    
        return Student(
          name: parsedJson['name'],
          age: parsedJson['age'],
          grade: Grade.fromJson(parsedJson['grade']),
          addressList: addressL2,
        );
      }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21

    上面的 var list = parsedJson['addressList']; 获取的类型是 List,是无法直接转成 List< Address>,所以需要遍历 list ,然后通过 Address.fromJson(address)list 里面的对象转成 Address 类型。

    上面基本就说完了,其实你可以看看 json_serializable 这个插件,其实也是通过注解来实现上面类似的代码。

  • 相关阅读:
    美国一声令下,NVIDIA损失超350亿,国产芯片迅速顶上
    蓝桥杯刷题_day10
    【React】组件实例三大属性state、props、refs
    计网总结☞应用层
    多张图解,一扫你对多线程问题本质的所有误区
    【C++心愿便利店】No.5---构造函数和析构函数
    上采样,下采样,卷积,反卷积,池化,反池化,双线性插值【基本概念分析】
    牛客—— JZ36 二叉搜索树与双向链表
    关于SQL优化的辟谣
    CAD进阶练习(五)
  • 原文地址:https://blog.csdn.net/zhujiangtaotaise/article/details/125904813