用Dart写的DartBean秒速生成器

294 阅读2分钟

DartBean项目缘由

之前开发时,用的FlutterJsonBeanFactory,确实非常好用。 也遇到一些问题

  • 有时,会引入一些无用的类,却不能清理,有强迫症的太难受了。
  • 一行定义多个变量时,无法正确识别。
  • 日期类型不能全局自定义。
  • 不支持把接口字段解析到私有变量。
  • 枚举支持不太方便。
  • 不支持纯Dart项目(非Flutter项目)

使用.Part

来实现Bean功能感觉简洁很多。

用户原始代码

@JsonSerializable()
class UserCompany {
  late String name;
  late String catchPhrase;
  late String bs;
}

自动补全后的用户代码

@JsonSerializable()
class UserCompany {
  late String name;
  late String catchPhrase;
  late String bs;

  static UserCompany fromJson(dynamic json) => _$UserCompanyFromJson(json);

  Map<String, dynamic> toJson() => _$UserCompanyToJson(this);
}

生成的 .part 文件

UserCompany _$UserCompanyFromJson(Map<String, dynamic> json) {
  final it = UserCompany();
  it.name = $JSON.convert<String>(json['name']) ?? it.name;
  it.catchPhrase = $JSON.convert<String>(json['catchPhrase']) ?? it.catchPhrase;
  it.bs = $JSON.convert<String>(json['bs']) ?? it.bs;
  return it;
}

Map<String, dynamic> _$UserCompanyToJson(UserCompany it) => {
      'name': it.name,
      'catchPhrase': it.catchPhrase,
      'bs': it.bs,
    };

特性说明

  • 支持为纯字段的Bean生成辅助方法,并引入依赖。
  • 支持JsonField注解
  • 兼容官方JsonKey部分功能(name, ignore, includeToJson, includeFromJson)
  • 支持枚举(配合JsonValue使用)
  • 支持自定义的JsonConverter
  • 支持全局配置基本类型解析(包括DateTime)
  • 支持全局配置和当前项目配置,项目中的缺省项继承全局配置
  • 支持基本类型 全局默认值设定

特别说明

基本兼容FlutterJsonBeanFactory的JsonField注解,不支持isEnum特性。

用户配置

.json_bean.toml

#TOML https://toml.io/cn/

#genDirName = 'gen'
#clickableFileLink = false
#ignoreOfficialBean = true
#flattenBean = false
#autoDefaultValueStyle = false
#jsonSupportFileName = 'json_support.dart'
#jsonCastFileName = 'json_cast.dart'
#jsonCastParamName = '$JSON'
#fromJsonParamName = 'json'
#toJsonParamName = 'it'
#fromJsonType = 'static'
#dartFormatterPageWidth = 160

配置文件格式须为 TOML

当前项目配置

执行命令后,会在当前项目下生成一个(.json_bean.toml)配置文件,包含当前使用的默认配置值,配置为注释状态,可取消注释以调整值。

全局配置

请在系统的环境变量中配置 JSON_BEAN_CONFIG=全路径配置文件地址

Platform.environment['JSON_BEAN_CONFIG'] <- full path of xx_json_bean.toml;

配置项说明

  /// the name of dir stored all generated files
  @JsonKey(defaultValue: 'gen')
  late String genDirName;

  ///full file path or not in console log<br/>
  /// 'my_project/lib/bean.dart' <- clickable then navigate to source code <br/>
  /// 'bean.dart' <- not clickable
  @JsonKey(defaultValue: false)
  late bool clickableFileLink;

  ///OfficialBean: file.contains("part 'file_name.g.dart';") <br/>
  ///use json_serializable for unsupported feature of dart_bean
  @JsonKey(defaultValue: true)
  late bool ignoreOfficialBean;

  ///when json2bean, add beanName to Json child bean as prefix or not<br/>
  @JsonKey(defaultValue: true)
  late bool flattenBean;

  ///support parse null json to default value or not. <br/>
  ///eg: late int a; when null json, a=0;
  @JsonKey(defaultValue: false)
  late bool autoDefaultValueEnable;

  @JsonKey(defaultValue: 'json_support.dart')
  late String jsonSupportFileName;

  @JsonKey(defaultValue: 'json_cast.dart')
  late String jsonCastFileName;

  @JsonKey(defaultValue: r'$JSON')
  late String jsonCastParamName;

  @JsonKey(defaultValue: 'json')
  late String fromJsonParamName;

  @JsonKey(defaultValue: 'it')
  late String toJsonParamName;

  ///fromJson method style 'static' or 'factory'
  @JsonKey(defaultValue: 'static')
  late String fromJsonType;

  ///line width for generated files
  @JsonKey(defaultValue: 160)
  late int dartFormatterPageWidth;

更多信息,请参考测试用例。

  • /test/feature_test.dart
  • /test/gen_test.dart

常见问题

基本类型全局默认值设定

通过Json自动生成的Bean文件,所有非空变量默认为late。用户可以根据情况手动调整为可空的,或设定一个默认值。 还可以不做调整,但启用全局默认值功能,启用方式如下:

配置 autoDefaultValueStyle = true #默认为false

用户定义变量时,可申明默认值,申明式默认值优先级高于全局默认值。

自定义JsonConverter来解析List变量时,C无法获取到正确类型。

//$DefaultJSONConvert只是JSONConvert的默认实现,用户可自定义实现,然后赋值给$JSON就行。
//$nullDefaultFromJson只是默认的实现,用户可自行修改方法实现,以满足业务需求。
$DefaultJSONConvert.nullDefaultFromJson = $nullDefaultFromJson;
    
dynamic $nullDefaultFromJson<M, C>(bool? buildDefaultValue) {
  if (buildDefaultValue == false) return null;
  if (M == List) return <C>[];//自定义JsonConverter来解析List<C>变量时,C无法获取到正确类型。
  if (M == Map) return {};
  
  final type = M.toString();
  switch (type) {
    case 'int':
      return 0;
    case 'bool':
      return false;
    case 'double':
      return 0.0;
    case 'String':
      return '';
  }
  return null;
}

使用方法

切换到dart_bean/bin目录,通过以下命令编译,得到 json_bean.exe

dart compile exe json_bean.dart

dart2part.png

json2bean.png

触发Json2Bean时,会弹出一个输入框,用户需要输入参数 beanName

bean name(include path relative to libDir) for json2bean,
eg:'data/user_info' -> lib/data/user_info.dart
root bean -> class UserInfo{}

shortcut.png