flutter 反序列化

一、内联反序列化

把JSON字符串转换成 Map<String, dynamic> 或者 List<dynamic>

import 'dart:convert';

main(List<String> args) {
  JsonCodec json = new JsonCodec();

  String str = '{"name":"tom"}';
  Map<String, dynamic> a = json.decode(str);
  print(a["name"]);

  String str1 = '["a","b"]';
  List<dynamic> b = json.decode(str1);
  print(b.length);

  String str3 = '{"name": "John Smith","email": "john@example.com"}';
  var c = json.decode(str3);
  print(c.runtimeType); //Map<String, dynamic>

  String str4 = '{"name": "John Smith","email": ["a","b"]}';
  var d = json.decode(str4);
  print(d.runtimeType); //Map<String, dynamic>

  String str5 = '{"name": "John Smith","email": {"a":"o","b":"p"}}';
  var e = json.decode(str5);
  print(e.runtimeType); //<String, dynamic>


  // String str6 = '{"name": "John Smith","email": {"a","b"}}';
  // var f = json.decode(str6); //FormatException: Unexpected character 报错
  // print(e.runtimeType);
}

 复杂些的比如

'{"age":19,"name":["tom","liu","wu"]}'    ??
 
 

二、把字符串转成类对象

import 'dart:convert';

main(List<String> args) {
  String str = '{"age":19,"name":"tom"}';
  Map map = jsonDecode(str);
  Student user = Student.ds(map);
  print(user.age);
}

class Student {
  int age;
  String name;
  //Student(this.age, this.name);
  Student.ds(Map<String, dynamic> json)
      : age = json['age'],
        name = json['name'];
}

 

三、自动反序列化

使用 json_serializable    https://pub.dev/packages/json_serializable

说明:用指令生成文件是在flutter中进行的,实际测试是在vscode中执行的。

不知道为什么flutter下使用flutter pub run build_runner build 正常,但是vscode中使用dart里的指令pub run build_runner build 生成不了文件。还有各式各样的版本问题,折腾了很久,感觉还不成熟

 

测试版本
Flutter 1.20.4 • channel stable
Dart SDK version: 2.9.2
导入包的版本

dependencies:
  flutter:
    sdk: flutter
  json_annotation: ^3.0.0

dev_dependencies:
  flutter_test:
    sdk: flutter
  build_runner: ^1.6.7
  json_serializable: ^3.2.2

 user.dart

import 'package:json_annotation/json_annotation.dart';

part 'user.g.dart';

@JsonSerializable()
class User {
  User(this.name, this.email);

  String name;
  String email;

  factory User.fromJson(Map<String, dynamic> json) => _$UserFromJson(json);
  Map<String, dynamic> toJson() => _$UserToJson(this);
}

*.g.dart里 *要跟文件名相同

在flutter项目的根目录下,也就是有pubspec.yaml文件夹下,使用指令:flutter pub run build_runner build

如果想要自动序列化使用指令:flutter pub run build_runner watch

 生成后的文件 user.g.dart

// GENERATED CODE - DO NOT MODIFY BY HAND

part of 'user.dart';

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

User _$UserFromJson(Map<String, dynamic> json) {
  return User(
    json['name'] as String,
    json['email'] as String,
  );
}

Map<String, dynamic> _$UserToJson(User instance) => <String, dynamic>{
      'name': instance.name,
      'email': instance.email,
    };

 使用

import 'dart:convert';
import './user.dart';

main(List<String> args) {
  String jsonString = '{"name": "John", "email": "abc@163.com"}';
  //序列化成map
  Map<String, dynamic> map = jsonDecode(jsonString);
  //转成对象
  User user = User.fromJson(map);
  print(user.email);
  //json
  print(user.toJson());
}

 

反序列化嵌套json

结构

 user.dart

import 'address.dart';
import 'package:json_annotation/json_annotation.dart';
part 'user.g.dart';

@JsonSerializable()
class User {
  String firstName;
  Address address;

  User(this.firstName, this.address);

  factory User.fromJson(Map<String, dynamic> json) => _$UserFromJson(json);
  Map<String, dynamic> toJson() => _$UserToJson(this);
}

address.dart

import 'package:json_annotation/json_annotation.dart';
part 'address.g.dart';

@JsonSerializable()
class Address {
  String street;
  String city;

  Address(this.street, this.city);

  factory Address.fromJson(Map<String, dynamic> json) => _$AddressFromJson(json);
  Map<String, dynamic> toJson() => _$AddressToJson(this);
}

生成后的代码

user.g.dart

// GENERATED CODE - DO NOT MODIFY BY HAND

part of 'user.dart';

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

User _$UserFromJson(Map<String, dynamic> json) {
  return User(
    json['firstName'] as String,
    json['address'] == null
        ? null
        : Address.fromJson(json['address'] as Map<String, dynamic>),
  );
}

Map<String, dynamic> _$UserToJson(User instance) => <String, dynamic>{
      'firstName': instance.firstName,
      'address': instance.address,
    };

这里有个问题,不知道为什么生成的这个user.g.dart文件在as中不报错,但是在vscode中报错

稍微改了一下,改成

  return User(
    json['firstName'] as String,
    json['address'] = Address.fromJson(json['address'] as Map<String, dynamic>),
  );

address.g.dart

// GENERATED CODE - DO NOT MODIFY BY HAND

part of 'address.dart';

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

Address _$AddressFromJson(Map<String, dynamic> json) {
  return Address(
    json['street'] as String,
    json['city'] as String,
  );
}

Map<String, dynamic> _$AddressToJson(Address instance) => <String, dynamic>{
      'street': instance.street,
      'city': instance.city,
    };

测试运行

import 'dart:convert';
import './user.dart';

main(List<String> args) {
   String jsonString = '{"firstName": "John", "address": {"street":"女贞路45号","city":"霍格沃茨"}}';
  //序列化成map
   Map<String, dynamic> map = jsonDecode(jsonString);
  //转成对象
   User user = User.fromJson(map);
   print(user.firstName);
   //
   print(user.address.city);
  //json
  print(user.toJson());
}

 

对象都成功输出了

但是嵌套类转JSON的这个结果不是想要的.

 修改user.dart

//括号里添加 
@JsonSerializable(explicitToJson: true)
class User {
  String firstName;
  Address address;

修改user.g.dart

User _$UserFromJson(Map<String, dynamic> json) {
  return User(
    json['firstName'] as String,
    //上面已经修改过
    json['address'] = Address.fromJson(json['address'] as Map<String, dynamic>),
  );
}

这个转json问题flutter里能成功,在vscode里纯dart方式失败?

 修改user.g.dart 不是个好方法,使用指令时肯定有重新变回去了。

posted @ 2020-08-07 20:18  富坚老贼  阅读(488)  评论(0编辑  收藏  举报