Flutter use json_model parse json file generated dart

A, json_serializable using procedure

1.集成json_serializable

pubspec.yaml add the following dependency

dependencies:
  json_annotation: ^2.0.0

dev_dependencies: build_runner: ^1.0.0 json_serializable: ^2.0.0 

Add finished, remember to take flutter packages get

2. Generate file

In the implementation of the project root directory to generate xxx.g.dart flutter packages pub run json_model 

3. Analytical and serializing

Note guide packageimport 'dart:convert';

///json转model
String jsonString = '{"name": "Tony","email": "[email protected]"}' Map userMap = json.decode(jsonString); var user = User.fromJson(userMap); ///model转json String jsonEncode = json.encode(user); print(jsonEncode);

Second, the automatic generation template

This requires each site to generate the json to be converted into Model, then we generated directly in the local command to the next just to write a user.json file and then executed. After each such json structure modification can directly modify the json file can then execute the command, and json structure can exist locally for easy viewing.

1. json_model

Integrated json_model
dev_dependencies: 
  json_model: ^ 0.0 . 2 # latest version
use
  1. Create a "jsons" directory named in the project root directory;
  2. Json create or copy files to "jsons" directory;
  3. Run pub run json_model (Dart VM project) or flutter packages pub run json_model (Flutter in) command to generate Dart model classes generated files by default in the "lib / models" directory

Specific documentation Address: https://github.com/flutterchina/json_model

2. a little small optimization

Above directly into the plug-in package is very convenient, but using encountered a little problem:

  • Like generated model json file name and file name, file name, if underlined _generated when the class name is underlined, but I used to use camelCase
  • Ibid., When the field name is underlined _, the generated field is also underlined, in order to use camelCase need to manually add above the field@JsonKey(name: 'user_name')
  • Automatically parse data type only supports bool num Map Listseveral common types, if the DateTimetype or other types of fields can only be resolved to a String.
  • The resulting model is not perfect formatting, obsessive-compulsive disorder have had to manually format it

If you feel so unfriendly or have their own writing habits then it yourself. I changed a bit here to get your way:

  • Class names, field names camelCase
  • Support DateTimetype (the latter there are other support can be added)
  • Perfect format

Practice: do not use json_model, do it yourself

  1. Create a "jsons" directory named in the project root directory;
  2. Json create or copy files to "jsons" directory;
  3. Created in the root directory of the project  mo.dartfile, as follows:
Import 'DART: Convert For' ; 
Import 'DART: IO' ; 
Import 'Package Penalty for: path / path.dart' AS path; 

const TAG = "\ $" ; 
const SRC = "./json"; // JSON directory 
const DIST = "lib / Models /"; // output model directory 

void Walk () {
   // iterate JSON catalog generation template 
  var the src = new new directory (the SRC);
   var List = src.listSync ();
   var template = "import 'package:json_annotation/json_annotation.dart';\r\n%t\npart '%s.g.dart';\r\n\r\n@JsonSerializable()\r\nclass %s {\r\n  %s();\r\n\r\n  %sfactory %s.fromJson(Map<String, dynamic> json) => _\$%sFromJson(json);\r\n\r\n  Map<String, dynamic> toJson() => _\$%sToJson(this);\r\n}\r\n";
  File file;
  list.forEach((f) {
    if (FileSystemEntity.isFileSync(f.path)) {
      file = new File(f.path);
      var paths = path.basename(f.path).split(".");
      String name = paths.first;
      if (paths.last.toLowerCase() != "json" || name.startsWith("_")) return;
      if(name.startsWith ( "_")) return ;
       // The following template to generate 
      var Map = JSON.decode (file.readAsStringSync ());
       // to avoid repetition of the same package introduced, we import statement Set to store generated . 
      var SET = new new the Set <String> (); 
      the StringBuffer attrs = new new the StringBuffer (); 
      (AS Map the Map <String, Dynamic> ) .forEach ((Key, V) {
         IF (key.startsWith ( "_")) return ;
         // / ############################# 
        // / process key contains "_", the hump and into plus @JsonKey (name = "Key") 
        IF (key.contains ( "_"
          attrs.write('@JsonKey(name: "$key")');
          attrs.write("\r\n  ");
          attrs.write(getType(v, set, name));
          attrs.write(" ");
          attrs.write(changeToCamelCase(key, false));
          attrs.writeln(";");
          attrs.write("\r\n  ");
        } else {
          attrs.write(getType(v, set, name));
          attrs.write(" ");
          attrs.write(key);
          attrs.writeln(";");
          attrs.write("\r\n  ");
        }
      });
      String className = "";
      /// #############################
      ///处理有"_"时class不是驼峰命名
      if (name.contains("_")) {
        className = changeToCamelCase(name, true);
      } else {
        className = name[0].toUpperCase() + name.substring(1);
      }
      var dist = format(template, [
        name,
        className,
        className,
        attrs.toString(),
        className,
        className,
        className 
      ]); 
      ;var _import = set.join ( "; \ R & lt \ n-" ); 
      _import + = _import.isEmpty "?": ";" ; 
      dist = dist.replaceFirst ( "% T" , _import);
       // the resulting output template 
      new new File ( "$ $ name.dart the dIST" ) .writeAsStringSync (dist); 
    } 
  }); 
} 
// / ################### ########## 
// / rev camelCase 
// / Are big big hump 
String changeToCamelCase (String Word, BOOL big) {
   iF (word.contains ( "_" )) { 
    String the Result = " " 
    List <String> words = word.split("_");
    for (var value in words) {
      result += (value[0].toUpperCase() + value.substring(1).toLowerCase());
    }
    return big ? result : (result[0].toLowerCase() + result.substring(1));
  } else {
    return big
        ? word[0].toUpperCase() + word.substring(1)
        : word[0].toLowerCase() + word.substring(1);
  }
}

String changeFirstChar(String str, [bool upper = true]) {
  return (upper ? str[0].toUpperCase() : str[0].toLowerCase()) +
      str.substring(1);
}

//将JSON类型转为对应的dart类型
String getType(v, Set<String> set, String current) {
  current = current.toLowerCase();
  if (v is bool) {
    return "bool";
  } else if (v is num) {
    return "num";
  } else if (v is Map) {
    return "Map<String,dynamic>";
  } else if (v is List) {
    return "List";
  } else if (v is String) {
    /// #############################
    ///添加DateTime类型
    try {
      DateTime dateTime = DateTime.parse(v);
      if (dateTime != null) {
        return "DateTime";
      }
    } catch (e) {}

    //处理特殊标志
    if (v.startsWith("$TAG[]")) {
      var className = changeFirstChar(v.substring(3), false);
      if (className.toLowerCase() != current) {
        set.add('import "$className.dart"');
      }
      /// #############################
      /// 自定义model类型名字大驼峰命名
      return "List<${changeToCamelCase(className, true)}>";
    } else if (v.startsWith(TAG)) {
      var fileName = changeFirstChar(v.substring(1), false);
      if (fileName.toLowerCase() != current) {
        set.add('import "$fileName.dart"');
      changeToCamelCase (fileName,return/ Custom model type the name of a large hump naming/// #############################//
      }
      
       to true);
    }
    return "String";
  } else {
    return "String";
  }
}

//替换模板占位符
String format(String fmt, List<Object> params) {
  int matchIndex = 0;
  String replace(Match m) {
    if (matchIndex < params.length) {
      switch (m[0]) {
        case "%s":
          return params[matchIndex++].toString();
      }
    } else {
      throw new Exception("Missing parameter for string format");
    }
    throw new Exception("Invalid format string: " + m[0].toString());
  }

  return fmt.replaceAllMapped("%s", replace);
}

void main() {
  walk();
}

 

Here is a way to generate a model and a template, Json_model's predecessor, from here

Where the comment contains "#############################" place to be modified over the place, everyone can have their own needs modify.

  1. Created in the root directory of the project mo.shfile, as follows:
#!/usr/bin/env bash
dart mo.dart
flutter packages pub run build_runner build --delete-conflicting-outputs

This is the script, execute the command with the pack

Note: If you do not dart environment variable configuration, you need to configure it: (Mac under)
  • vim ~/.bash_profile
  • Add toexport PATH=your flutter path/flutter/bin/cache/dart-sdk/bin:$PATH
  • source ~/.bash_profile
  • dart --versionThe version number to the normal display
  1. After the configuration above are just a step to the next project root directory sh mo.sh, ok, get everything perfect, for everyone to see results
     
 
 
 
 

重要参考:
https://www.jianshu.com/p/b20514e16e10
https://book.flutterchina.club/chapter10/json_model.html

 

 

Guess you like

Origin www.cnblogs.com/cap-rq/p/11797175.html