Code Monkey home page Code Monkey logo

jsonformat4flutter's Introduction

JSONFormat4Flutter

受zzz40500/GsonFormat启发,将JSONObject格式的String解析成dart语言的实体类

本工具已迁移至空安全(2021–3–6)

dart 语言更新为 null-safety 语法后,本工具生成的实体类代码就无法通过静态检查,具体细节可以参考迁移Flutter项目到空安全的血泪史——有血、有泪、有💩

主要的问题有:

  1. 实例的变量需要在声明时初始化,或者在类的构造方法中进行初始化;
  2. 类的工厂方法不允许返回 null;
  3. 复杂逻辑下的可达性分析和空安全类型提升并不完美(例如对数组字段生成的赋值代码,循环中的 list 对象逻辑上不会为 null,但是语法检查器还是会将其判定为不安全的)

针对如上问题,本次更新做出如下修改:

  1. 所有字段的类型均设置为可空,事实上由于我们无法保证 json 字符串输入的可靠性,不管设计如何确实所有字段都是有可能为空的;
  2. 新增 parse(jsonStr) 静态方法,用于替代之前的工厂构造函数,推荐在项目中优先使用该方法进行解析;
  3. 将数组字段的泛型也全部设置为可空的,并通过添加 ! 标识符解决语法检查认为数组字段可能为空不可操作的问题。

除此之外,由于发现某些三方库会尝试调用对象的 toJson() 方法来实现打印输出或序列化,所以添加 String toJson() => this.toString(); 的方法映射。

See More: JSONFormat4Flutter v0.9 更新说明

使用演示操作:

使用说明

1.界面操作 (参考录屏:parse.gif)

  1. 工具运行以后,先将复制好的json字符串粘贴到左侧文本框,然后点击'格式化'按钮;如果提示出错请检查json是否合法
  2. 格式化成功后左侧json将会按照缩进格式化显示,并且右侧表格将显示分析得出的json结构,'Fields'列显示层级和原始分析数据,'Name'列显示每个字段的名称,'Type'列用于设定字段的数据类型
    1. 对于普通数据类型(int、 double、 boolean、 String),Types列的类型将会自动给出,请尽量避免在上面滚动鼠标滚轮导致类型选择改变
    2. 对于值null的字段,Types列的类型会自动设置为Object,并以黄色背景作为警告。此时如果直接生成代码也是可以使用的,只是该字段在使用时可能需要手动强转,所以建议在知晓该字段实际类型情况下尽量补全json字符串后再点击'格式化',或者在类型下拉框中指定实际的基本数据类型
    3. 对于自定义对象类型(或者说字典/Map),'Fields'的对应输入框将留空并设为红色背景,需要您手动输入类型名称,并请注意:
      1. 任意一个字段没有输入类型名时点击代码生成按钮,都将弹出警告提示并拒绝生成代码
      2. 设置类型名时可以参考同一行'Name'栏的值进行设置以方便使用时识别字段,一般情况下推荐直接将'Name'栏内容首字母大写作为类型名
      3. 但是需要注意,类型名不可与'Name'栏内容完全相同,且不能是dart中的关键字,否则生成的代码将包含语法错误
      4. 一般情况下第一行的数据类型为对象且'Name'栏内容为空,设置第一列的'Types'即为生成的bean的顶级对象类名,推荐使用'该json的作用+Resp/Bean'形式进行命名以方便管理
    4. 对于数组类型,'Types'栏将被自动设置,并且:
      1. 数组的泛型类型取决于数组的内容的类型,也就是下一行设置的类型;当数组下一行的内容类型变化时泛型也会自动改变
      2. 支持数组的嵌套泛型传递
      3. 支持空数组,并且生成的代码中其泛型会被设置为dynamic
    5. 特殊的,如果json本身的顶层级不是对象而是数组,那么需要为第一行的'Name'栏设置类型名称,获取顶层级数组数据的方式为对象bean.list
  3. 确认设置无误后,点击'生成Bean'按钮,左侧json显示栏的内容将被替换为生成的代码,可以使用鼠标键盘全选复制,或者直接点击下方的'复制'按钮,然后将代码粘贴到IDE中,完成解析流程

2.生成代码说明 (参考录屏:use.gif)

  1. 反序列化(json字符串->对象)
    将生成的代码粘贴到dart源文件中后,即可以在任意地方导包使用,一般方法为(以http.get请求为例):

    var response = await HTTP.get(url);
    var resp = BeanResp(response.body);

    也就是说,将请求到的json内容作为参数传递给BeanResp的默认构造函数,这样生成的resp对象即是请求到内容的实体。 需要说明的是,默认构造既可以传入json的原始字符串,也可以传入已经用原生json.decode()方法解析过的json对象(这主要是为了照顾使用dio库进行数据请求时结果数据会被自动解析成json对象的情况)。 只有顶级对象拥有默认构造方法,而其他子层级对象将使用xxx.fromJson()的命名构造进行对象创建。

  2. 序列化(对象->json字符串)
    与官方样例的处理方式不同,直接调用对象的toString()方法即可得到json字符串完成序列化操作

  3. 手动创建对象
    为了方便大部分使用场景下的便利性,bean的默认构造函数被用来实现反序列化,所以如果想要在代码中手动传参创建bean对象,可以使用xxx.fromParams()命名构造来完成。

简易运行方式:

Release 页面中,选择下载对应平台最新的二进制文件后——

linux:

在程序目录打开终端后执行:chmod u+x Formatter_linux && ./Formatter_linux

mac:

在程序目录打开终端后执行:chmod u+x Formatter_mac && ./Formatter_mac

windows:

直接双击运行 Formatter_win.exe

源码运行(以MAC为例)

没有python运行环境的用户需要先安装python

mac中可以使用如下命令安装

brew install python3
brew install pip3

pip3是python3的包管理工具

brew 可以参考下面的链接

https://brew.sh/index_zh-cn

运行库的时候会可能会提示

Traceback (most recent call last):
  File "formater.py", line 8, in <module>
    from mainwindow import *
  File "/Users/cjl/IdeaProjects/flutter/sxw-flutter-app/JSONFormat4Flutter/mainwindow.py", line 9, in <module>
    from PyQt5 import QtCore, QtGui, QtWidgets
ModuleNotFoundError: No module named 'PyQt5'

这时候可以直接用 pip3 install PyQt5 pip3 install pyperclip 等待安装完成

(注:brew安装最新版python3可能会出现ssl模块丢失导致pip3无法正常使用,此时也可以考虑直接在python官网下载pkg包方式安装python)

后面使用就是在命令行敲入 python3 formatter.py

已知问题

  • mac下从文本框复制出的文字直接粘贴到 idea/android studio 中报错 " lllegal character '65279' "

参考 issue1 ,如下图,使用5.7.1及之前版本的pyqt5

build

  • Linux:
nuitka3 --clang --standalone --windows-disable-console --linux-onefile-icon=logo.png --output-dir=output --show-progress --plugin-enable=qt-plugins --onefile formatter.py
  • Windows:
pyinstaller -F -w -i logo.ico formatter.py

jsonformat4flutter's People

Contributors

caijinglong avatar debuggerx01 avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar

jsonformat4flutter's Issues

mac 使用问题

未能打开文稿“Formatter_mac”。文本编码“Unicode (UTF-8)”不适用。

json本身的顶层级不是对象而是数组,解析报错

image

[{"a":"xx","b":"bbb"},{"a":"xx","b":"bbbb"},{"a":"xx","b":"bbbbb"}]

image

dui对于这种整个json就是一个数组的,设置的没问题,解析报错
type 'String' is not a subtype of type 'int' of 'index'

我看了下,生成的代码jsonRes['json_list'],这里明显有问题,json_list这个key是不存在的,所以报错了

image

个人感觉对于这种类型,直接当做数组item的json来处理,额外再提供一下数组解析的方法就好了

IDEA plugin

怎么不把这个搞成 IDEA plugin 呢,这样不就方便很多了嘛。

关于生成class的构造函数的疑问

发现生成的class中只有一个带参的构造函数,如果我不直接传jsonStr进去,而是想初始化一个空的class。给class一个默认构造函数,给转换构造函数加一个命名是不是更好?

Json

{ "name": "BeJson", "email": "http://www.bejson.com", "list": [ "Google", "baidu", "facebook" ] }

Class,嵌套class以此类推

  class UserModel {

  String email;
  String name;
  List<String> list;

  UserModel(){
    list = [];
  }

  UserModel.byJson(jsonStr) {
  var jsonRes = json.decode(jsonStr);

    email = jsonRes['email'];
    name = jsonRes['name'];
    list = [];

  for (var listItem in jsonRes['list']){
    
      list.add(listItem);
    }
  }

初学dart,语法还不太熟,请见谅

tostring的问题,建议

看到tostring里面大佬做了很多处理,但是发现还有问题,比如string是“”的时候。。tostring的字符串没法正常转换json。

建议生成类似这样的

 Map<String, dynamic> toJson() => {
        'id': id,
      };
  @override
  String toString() {
    // TODO: implement toString
    return json.encode(toJson());
  }

谢谢

exe二次生成bean卡死崩溃

你好,感谢开源贡献。
我在使用过程中发现:首次生成bean没有问题,当程序窗口没有关闭的情况下再次复制另一个json格式化之后,点击红色区域命名的时候程序会卡死直至崩溃,望查验。

获取不到解析内容

image
获取data里面有数据,用这个FollowList followList = new FollowList(data);,解析不了是什么原因

你好发现一个问题 在解析数组的时候会出点小问题

result数据为{"result":[{"name":"测试分类1","id":"1"},{"name":"测试分类3","id":"3"},{"name":"测试分类","id":"5"}]}
for (var resultItem in jsonRes['result']){

  result.add(new ListBean.fromJson(resultItem));
}

无法转换 会 'String' is not a subtype of type 'int' of 'index'

生成错误

发生错误在通过以下:
{
"x":{
"q":[],
"t":[],
"e":[{}]
}
}

macos下生成不成功

按照操作步骤执行生成后,只有“import 'dart:convert' show json;”这一句

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.