Administrator
Administrator
Published on 2025-06-10 / 2 Visits
0
0

json序列化和反序列化

自行实现(笨办法)

class LoginData{
  final int code;
  final String msg;
  final List<DataItem> data;

  LoginData({required this.code, required this.msg, required this.data});

  @override
  String toString() => 'LoginData(code: $code, msg: $msg, data: $data)';


  static LoginData fromString(String json) {
    Map<String, dynamic> p = jsonDecode(json);
    return LoginData(code: p["code"] as int, msg: p["msg"] as String, data: (p["data"] as List).map((item){
      return DataItem(id: item["id"] as int, name: item["name"] as String);
    }).toList());
  }
}
class DataItem{
  final int id;
  final String name;

  DataItem({required this.id, required this.name});

  @override
  String toString() => 'DataItem(id: $id, name: $name)';
}
void main(){
  const json = '{"code":200,"msg":"成功","data":[{"id":1,"name":"2"}]}';
  print(LoginData.fromString(json));
}

第三方依赖

自动将dynamic、Map、List等转换成对应的class实例

安装

pubsepc.yaml:

dependencies:
  json_annotation: ^4.9.0

dev_dependencies:
  build_runner: ^2.4.15
  json_serializable: ^6.9.5

创建class

假设有JSON如:{"code":200,"msg":"成功","data":[{"id":1,"name":"2","data2":[{"id":3,"name":"4"}]}]}

import 'dart:convert';

import 'package:json_annotation/json_annotation.dart';

part 'LoginDataModel.g.dart'; //假设当前文件为LoginDataModel.dart,在.dart前面加.g,不可自定义

@JsonSerializable()
class LoginData{
  final int code;
  final String msg;
  List<DataItem> data;

  LoginData({required this.code, required this.msg, required this.data});

  @override
  String toString() => 'LoginData(code: $code, msg: $msg, data: $data)';

}
@JsonSerializable()
class DataItem{
  final int id;
  final String name;
  final List<ThreeData> data2;

  DataItem({required this.id, required this.name, required this.data2});

  @override
  String toString() => 'DataItem(id: $id, name: $name, data2: $data2)';
}

@JsonSerializable()
class ThreeData{ //第三层结构
  final int id;
  final String name;

  ThreeData({required this.id, required this.name});

  @override
  String toString() => 'ThreeData(id: $id, name: $name)';
}

生成代码

flutter pub run build_runner build #弃用

dart run build_runner build #用这个

执行后会生成LoginDataModel.g.dart文件,其中内容:

// GENERATED CODE - DO NOT MODIFY BY HAND

part of 'LoginDataModel.dart';

// **************************************************************************
// JsonSerializableGenerator
// **************************************************************************

LoginData _$LoginDataFromJson(Map<String, dynamic> json) => LoginData(
  code: (json['code'] as num).toInt(),
  msg: json['msg'] as String,
  data:
      (json['data'] as List<dynamic>)
          .map((e) => DataItem.fromJson(e as Map<String, dynamic>))
          .toList(),
);

Map<String, dynamic> _$LoginDataToJson(LoginData instance) => <String, dynamic>{
  'code': instance.code,
  'msg': instance.msg,
  'data': instance.data,
};

DataItem _$DataItemFromJson(Map<String, dynamic> json) =>
    DataItem(id: (json['id'] as num).toInt(), name: json['name'] as String);

Map<String, dynamic> _$DataItemToJson(DataItem instance) => <String, dynamic>{
  'id': instance.id,
  'name': instance.name,
};

添加工厂函数

DataItem和ThreeData这样的子数据结构(json深层结构)必须实现fromJson。

LoginData.fromString可以随意实现,只需传入_$LoginDataFromJson的参数正确并返回LoginData类型

@JsonSerializable()
class LoginData{
  final int code;
  final String msg;
  List<DataItem> data;

  LoginData({required this.code, required this.msg, required this.data});

  @override
  String toString() => 'LoginData(code: $code, msg: $msg, data: $data)';

  factory LoginData.fromString(String str){
    Map<String,dynamic> json = jsonDecode(str);
    return _$LoginDataFromJson(json);
  }
  
}
@JsonSerializable()
class DataItem{
  final int id;
  final String name;
  final List<ThreeData> data2;

  DataItem({required this.id, required this.name, required this.data2});

  @override
  String toString() => 'DataItem(id: $id, name: $name, data2: $data2)';

  factory DataItem.fromJson(Map<String, dynamic> arg1) => _$DataItemFromJson(arg1);
}

@JsonSerializable()
class ThreeData{
  final int id;
  final String name;

  ThreeData({required this.id, required this.name});

  @override
  String toString() => 'ThreeData(id: $id, name: $name)';

  factory ThreeData.fromJson(Map<String, dynamic> arg1) => _$ThreeDataFromJson(arg1);
}

类再转成Map、List

这样的结构就可以用jsonEncode反序列化成标准的JSON文本,重点是所有下级结构类都要转成Map或List否则jsonEncode会报错


Map<String, dynamic> loginDataToJson(LoginData arg){
  Map<String, dynamic> p = {
    'code': arg.code,
    'msg': arg.msg,
    'data': arg.data.map((e){
      return {
        'id': e.id,
        'name': e.name,
        'data2': e.data2.map((e){
          return {
            'id': e.id,
            'name': e.name,
          };
        }).toList()
      };
    }).toList()
  };

  return p;
}

调用

import 'package:flutter_scan/DataModel/LoginDataModel.dart';

void main(){
  const json = '{"code":200,"msg":"成功","data":[{"id":1,"name":"2","data2":[{"id":3,"name":"4"}]}]}';
  var parsedJson = LoginData.fromString(json);
  print(parsedJson);
  print(loginDataToJson(parsedJson));
}


Comment