├── Example
├── json.gif
├── parse.gif
├── pyqt571.png
└── use.gif
├── README.md
├── Test
├── EmptyResp.dart
├── EmptyTest.json
├── IgnoreMapResp.dart
├── IgnoreMapTest.json
├── ListTopResp.dart
├── ListTopTest.json
├── ListWithStringResp.dart
├── ListWithStringTest.json
├── ListsResp.dart
├── ListsTest.json
├── RegionResp.dart
├── RegionTest.json
├── WanResp.dart
├── WanTest.json
├── pubspec.lock
├── pubspec.yaml
├── test.dart
└── test.sh
├── check_version.py
├── formatter.py
├── logo.ico
├── logo.png
├── logo.qrc
├── logo_rc.py
├── mainwindow.py
├── mainwindow.ui
├── template_code.py
├── tools.py
└── version
/Example/json.gif:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/debuggerx01/JSONFormat4Flutter/5b24ca47bce33524e0c1919c87f7c76a1457f8fb/Example/json.gif
--------------------------------------------------------------------------------
/Example/parse.gif:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/debuggerx01/JSONFormat4Flutter/5b24ca47bce33524e0c1919c87f7c76a1457f8fb/Example/parse.gif
--------------------------------------------------------------------------------
/Example/pyqt571.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/debuggerx01/JSONFormat4Flutter/5b24ca47bce33524e0c1919c87f7c76a1457f8fb/Example/pyqt571.png
--------------------------------------------------------------------------------
/Example/use.gif:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/debuggerx01/JSONFormat4Flutter/5b24ca47bce33524e0c1919c87f7c76a1457f8fb/Example/use.gif
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # JSONFormat4Flutter
2 | 受zzz40500/GsonFormat启发,将JSONObject格式的String解析成dart语言的实体类
3 |
4 | ## 本工具已迁移至空安全(2021–3–6)
5 | dart 语言更新为 null-safety 语法后,本工具生成的实体类代码就无法通过静态检查,具体细节可以参考[迁移Flutter项目到空安全的血泪史——有血、有泪、有💩](http://www.debuggerx.com/2021/03/07/migrate-flutter-project-to-null-safety/)。
6 |
7 | 主要的问题有:
8 | 1. 实例的变量需要在声明时初始化,或者在类的构造方法中进行初始化;
9 | 2. 类的工厂方法不允许返回 null;
10 | 3. 复杂逻辑下的可达性分析和空安全类型提升并不完美(例如对数组字段生成的赋值代码,循环中的 list 对象逻辑上不会为 null,但是语法检查器还是会将其判定为不安全的)
11 |
12 | 针对如上问题,本次更新做出如下修改:
13 | 1. 所有字段的类型均设置为可空,事实上由于我们无法保证 json 字符串输入的可靠性,不管设计如何确实所有字段都是有可能为空的;
14 | 2. 新增 `parse(jsonStr)` 静态方法,用于替代之前的工厂构造函数,推荐在项目中优先使用该方法进行解析;
15 | 3. 将数组字段的泛型也全部设置为可空的,并通过添加 `!` 标识符解决语法检查认为数组字段可能为空不可操作的问题。
16 |
17 | 除此之外,由于发现某些三方库会尝试调用对象的 `toJson()` 方法来实现打印输出或序列化,所以添加 `String toJson() => this.toString();` 的方法映射。
18 |
19 | See More: [JSONFormat4Flutter v0.9 更新说明](https://www.debuggerx.com/2021/04/20/jsonformat4flutter-v0-9-nullsafety/)
20 |
21 |
22 | ## 详细介绍说明(掘金):[在Flutter开发过程中快速生成json解析模板类的工具](https://juejin.im/post/5b4e04bbe51d45198c018e6e)
23 |
24 | ## 使用演示操作:
25 |
26 | 
27 |
28 |
29 | ## 使用说明
30 | #### 1.界面操作 (参考录屏:[parse.gif](https://github.com/debuggerx01/JSONFormat4Flutter/blob/master/Example/parse.gif))
31 | 1. 工具运行以后,先将复制好的json字符串粘贴到左侧文本框,然后点击'格式化'按钮;如果提示出错请检查json是否合法
32 | 2. 格式化成功后左侧json将会按照缩进格式化显示,并且右侧表格将显示分析得出的json结构,'Fields'列显示层级和原始分析数据,'Name'列显示每个字段的名称,'Type'列用于设定字段的数据类型
33 | 1. 对于普通数据类型(int、 double、 boolean、 String),Types列的类型将会自动给出,请尽量避免在上面滚动鼠标滚轮导致类型选择改变
34 | 2. 对于值null的字段,Types列的类型会自动设置为Object,并以黄色背景作为警告。此时如果直接生成代码也是可以使用的,只是该字段在使用时可能需要手动强转,所以建议在知晓该字段实际类型情况下尽量补全json字符串后再点击'格式化',或者在类型下拉框中指定实际的基本数据类型
35 | 3. 对于自定义对象类型(或者说字典/Map),'Fields'的对应输入框将留空并设为红色背景,需要您手动输入类型名称,并请注意:
36 | 1. 任意一个字段没有输入类型名时点击代码生成按钮,都将弹出警告提示并拒绝生成代码
37 | 2. 设置类型名时可以参考同一行'Name'栏的值进行设置以方便使用时识别字段,一般情况下推荐直接将'Name'栏内容首字母大写作为类型名
38 | 3. 但是需要注意,类型名不可与'Name'栏内容完全相同,且不能是dart中的关键字,否则生成的代码将包含语法错误
39 | 4. 一般情况下第一行的数据类型为对象且'Name'栏内容为空,设置第一列的'Types'即为生成的bean的顶级对象类名,推荐使用'该json的作用+Resp/Bean'形式进行命名以方便管理
40 | 4. 对于数组类型,'Types'栏将被自动设置,并且:
41 | 1. 数组的泛型类型取决于数组的内容的类型,也就是下一行设置的类型;当数组下一行的内容类型变化时泛型也会自动改变
42 | 2. 支持数组的嵌套泛型传递
43 | 3. 支持空数组,并且生成的代码中其泛型会被设置为dynamic
44 | 5. 特殊的,如果json本身的顶层级不是对象而是数组,那么需要为第一行的'Name'栏设置类型名称,获取顶层级数组数据的方式为对象bean.list
45 | 3. 确认设置无误后,点击'生成Bean'按钮,左侧json显示栏的内容将被替换为生成的代码,可以使用鼠标键盘全选复制,或者直接点击下方的'复制'按钮,然后将代码粘贴到IDE中,完成解析流程
46 |
47 |
48 | #### 2.生成代码说明 (参考录屏:[use.gif](https://github.com/debuggerx01/JSONFormat4Flutter/blob/master/Example/use.gif))
49 |
50 | 1. 反序列化(json字符串->对象)
51 |
将生成的代码粘贴到dart源文件中后,即可以在任意地方导包使用,一般方法为(以http.get请求为例):
52 | ```java
53 | var response = await HTTP.get(url);
54 | var resp = BeanResp(response.body);
55 | ```
56 | 也就是说,将请求到的json内容作为参数传递给BeanResp的默认构造函数,这样生成的resp对象即是请求到内容的实体。
57 | 需要说明的是,默认构造既可以传入json的原始字符串,也可以传入已经用原生json.decode()方法解析过的json对象(这主要是为了照顾使用dio库进行数据请求时结果数据会被自动解析成json对象的情况)。
58 | 只有顶级对象拥有默认构造方法,而其他子层级对象将使用xxx.fromJson()的命名构造进行对象创建。
59 |
60 | 2. 序列化(对象->json字符串)
61 |
与官方样例的处理方式不同,直接调用对象的toString()方法即可得到json字符串完成序列化操作
62 |
63 | 3. 手动创建对象
64 |
为了方便大部分使用场景下的便利性,bean的默认构造函数被用来实现反序列化,所以如果想要在代码中手动传参创建bean对象,可以使用xxx.fromParams()命名构造来完成。
65 |
66 | ## 简易运行方式:
67 | 在 [Release](https://github.com/debuggerx01/JSONFormat4Flutter/releases) 页面中,选择下载对应平台最新的二进制文件后——
68 | #### linux:
69 | 在程序目录打开终端后执行:chmod u+x Formatter_linux && ./Formatter_linux
70 | #### mac:
71 | 在程序目录打开终端后执行:chmod u+x Formatter_mac && ./Formatter_mac
72 | #### windows:
73 | 直接双击运行 Formatter_win.exe
74 | ## 源码运行(以MAC为例)
75 | 没有python运行环境的用户需要先安装python
76 |
77 | mac中可以使用如下命令安装
78 | ```
79 | brew install python3
80 | brew install pip3
81 | ```
82 | pip3是python3的包管理工具
83 |
84 | brew 可以参考下面的链接
85 |
86 | https://brew.sh/index_zh-cn
87 |
88 |
89 |
90 | 运行库的时候会可能会提示
91 | ```
92 | Traceback (most recent call last):
93 | File "formater.py", line 8, in
94 | from mainwindow import *
95 | File "/Users/cjl/IdeaProjects/flutter/sxw-flutter-app/JSONFormat4Flutter/mainwindow.py", line 9, in
96 | from PyQt5 import QtCore, QtGui, QtWidgets
97 | ModuleNotFoundError: No module named 'PyQt5'
98 |
99 | ```
100 |
101 | 这时候可以直接用
102 | `pip3 install PyQt5`
103 | `pip3 install pyperclip`
104 | 等待安装完成
105 |
106 | ``(注:brew安装最新版python3可能会出现ssl模块丢失导致pip3无法正常使用,此时也可以考虑直接在python官网下载pkg包方式安装python)``
107 |
108 | 后面使用就是在命令行敲入
109 | `python3 formatter.py`
110 |
111 | ## 已知问题
112 | + mac下从文本框复制出的文字直接粘贴到 idea/android studio 中报错 " lllegal character '65279' "
113 |
114 | 参考 [issue1](https://github.com/debuggerx01/JSONFormat4Flutter/issues/1) ,如下图,使用5.7.1及之前版本的pyqt5
115 |
116 | 
117 |
118 | ## build
119 | - Linux:
120 | ```shell
121 | nuitka3 --clang --standalone --windows-disable-console --linux-onefile-icon=logo.png --output-dir=output --show-progress --plugin-enable=qt-plugins --onefile formatter.py
122 | ```
123 | - Windows:
124 | ```shell
125 | pyinstaller -F -w -i logo.ico formatter.py
126 | ```
127 |
--------------------------------------------------------------------------------
/Test/EmptyResp.dart:
--------------------------------------------------------------------------------
1 | import 'dart:convert' show json;
2 |
3 | class EmptyResp {
4 | Qwe? qwe;
5 |
6 | EmptyResp.fromParams({this.qwe});
7 |
8 | factory EmptyResp(Object jsonStr) => jsonStr is String
9 | ? EmptyResp.fromJson(json.decode(jsonStr))
10 | : EmptyResp.fromJson(jsonStr);
11 |
12 | static EmptyResp? parse(jsonStr) =>
13 | ['null', '', null].contains(jsonStr) ? null : EmptyResp(jsonStr);
14 |
15 | EmptyResp.fromJson(jsonRes) {
16 | qwe = jsonRes['qwe'] == null ? null : Qwe.fromJson(jsonRes['qwe']);
17 | }
18 |
19 | @override
20 | String toString() {
21 | return '{"qwe": $qwe}';
22 | }
23 |
24 | String toJson() => this.toString();
25 | }
26 |
27 | class Qwe {
28 | List? asd;
29 | List