{"id":20943366,"url":"https://github.com/kongzue/basejson","last_synced_at":"2025-05-14T00:32:36.642Z","repository":{"id":62632175,"uuid":"277532963","full_name":"kongzue/BaseJson","owner":"kongzue","description":"改进型 Json 解析库，快速解析 Json 为 Map 或 List 对象，甚至直接由 JsonList 创建列表可用的适配器。BaseJson 的目标不是能让 json 解析变得多快，而是让开发者能更轻松的完成 json 到 UI 的呈现😆","archived":false,"fork":false,"pushed_at":"2025-01-22T11:03:14.000Z","size":447,"stargazers_count":48,"open_issues_count":1,"forks_count":6,"subscribers_count":5,"default_branch":"master","last_synced_at":"2025-04-02T10:21:43.559Z","etag":null,"topics":["android","json","kongzue","util"],"latest_commit_sha":null,"homepage":"","language":"Java","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/kongzue.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":null,"code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2020-07-06T12:15:21.000Z","updated_at":"2025-03-25T02:22:12.000Z","dependencies_parsed_at":"2024-01-03T03:46:11.562Z","dependency_job_id":"b1e3ef72-44de-4a94-b799-4f8698a6a4a1","html_url":"https://github.com/kongzue/BaseJson","commit_stats":null,"previous_names":[],"tags_count":20,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/kongzue%2FBaseJson","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/kongzue%2FBaseJson/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/kongzue%2FBaseJson/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/kongzue%2FBaseJson/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/kongzue","download_url":"https://codeload.github.com/kongzue/BaseJson/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":254046519,"owners_count":22005613,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["android","json","kongzue","util"],"created_at":"2024-11-18T23:36:17.672Z","updated_at":"2025-05-14T00:32:31.623Z","avatar_url":"https://github.com/kongzue.png","language":"Java","funding_links":[],"categories":[],"sub_categories":[],"readme":"# BaseJson\n\n基于 org.json 的改进型 Json 解析库，快速解析 Json 为 Map 或 List 对象，甚至直接由 JsonList 创建列表可用的适配器。\n\n\u003ca href=\"https://github.com/kongzue/BaseJson/\"\u003e\n\u003cimg src=\"https://img.shields.io/badge/BaseJson-1.0.7-green.svg\" alt=\"BaseOkHttp\"\u003e\n\u003c/a\u003e\n\u003ca href=\"https://github.com/kongzue/BaseJson/releases\"\u003e\n\u003cimg src=\"https://img.shields.io/github/v/release/kongzue/BaseJson?color=green\" alt=\"Maven\"\u003e\n\u003c/a\u003e \n\u003ca href=\"https://jitpack.io/#kongzue/BaseJson\"\u003e\n\u003cimg src=\"https://jitpack.io/v/kongzue/BaseJson.svg\" alt=\"Jitpack.io\"\u003e\n\u003c/a\u003e \n\u003ca href=\"http://www.apache.org/licenses/LICENSE-2.0\"\u003e\n\u003cimg src=\"https://img.shields.io/badge/License-Apache%202.0-red.svg\" alt=\"License\"\u003e\n\u003c/a\u003e\n\u003ca href=\"http://www.kongzue.com\"\u003e\n\u003cimg src=\"https://img.shields.io/badge/Homepage-Kongzue.com-brightgreen.svg\" alt=\"Homepage\"\u003e\n\u003c/a\u003e\n\n## 简介\n\nBaseJson 的目标不是能让 json 解析变得多快，而是让开发者能更轻松的完成 json 到 UI 的呈现。\n\nBaseJson 直接将 json 以 Map 和 List 承载能更轻松的符合适配器、序列化的需求，也能更轻松的应对各种奇葩的、不符合规范的 json\n\n尽量减少异常的产生，尽量保证业务能够快速开发，更符合敏捷开发的需要，牺牲一定的性能我觉着也能接受吧😆\n\n- 将 Json 转换为 Map 或 List 的子类，可直接用于 Adapter，省去编写 Bean 的过程。\n- JsonMap 也可轻松与 JavaBean 互相转换。\n- 高容错设计，使用自定义 get 方法，无论如何绝不会出现空指针，哪怕类型错误，你也无须担心空指针异常；\n- 无缝衔接 Map 和 List，可随意通过 Map 或 List 直接转换为 Json 对象；\n- 借助 Map 和 List 的优势，`.isEmpty()`判空，`KeySet()`遍历、`Collections.sort()`排序等操作帮助你轻松完成解析。\n\n## Maven仓库或Gradle的引用方式\n\n### jitPack\n\n在项目根目录的 build.gradle(Project) 添加:\n\n```\nallprojects {\n    repositories {\n        ...\n        maven { url 'https://jitpack.io' }\n    }\n}\n```\n\n#### 最新版本：\n\n\u003ca href=\"https://jitpack.io/#kongzue/BaseJson\"\u003e\n\u003cimg src=\"https://jitpack.io/v/kongzue/BaseJson.svg\" alt=\"Jitpack.io\"\u003e\n\u003c/a\u003e \n\n在 build.gradle(app) 添加:\n\n```\ndependencies {\n        implementation 'com.github.kongzue:BaseJson:1.2.0'\n}\n```\n\n#### jCenter（已停止服务）：\n\n在dependencies{}中添加引用：\n\n```\nimplementation 'com.kongzue.basejson:basejson:1.0.7'\n```\n\n## 概念\n\n本组件对 Json 的定义如下：\n\n对于 Json 对象，为 JsonMap，对于 Json 集合，为 JsonList。\n\nJsonMap 是 Map 的子类，JsonList 是 List 的子类，本身各自具备 Map、List 的特点，适用于一切 Map、List 的使用场景。\n\n可通过 JsonBean 工具类，实现 JavaBean 与 JsonMap 之间的互相转换，这里使用了反射技术。\n\n在 get 值时，建议使用 JsonMap 和 JsonList 定义的 getString(key)、getBoolean(key) 等方法，使用 Map、List 原本的 get 依然可能获得空对象（null）。\n\n使用 JsonMap 和 JsonList 定义的 get 类方法不会有返回空对象的情况。\n\n## 由 String 创建 JsonMap/JsonList\n\n使用以下代码将 Json 文本解析为 JsonMap：\n\n```\nJsonMap data = new JsonMap(\"{\\\"key\\\":\\\"DFG1H56EH5JN3DFA\\\",\\\"token\\\":\\\"124ASFD53SDF65aSF47fgT211\\\"}\");\n```\n\n使用以下代码将 Json 文本解析为 JsonList：\n\n```\nJsonList list = new JsonList(\"[{\\\"answerId\\\":\\\"98\\\",\\\"questionDesc\\\":\\\"否\\\"},{\\\"answerId\\\":\\\"99\\\",\\\"questionDesc\\\":\\\"是\\\"}]\");\n```\n\n若 Json 文本不合法，或内容有错误，则可能返回 **空内容** 的 JsonMap/JsonList。\n\n## 读取值\n\n使用 JsonMap 和 JsonList 定义的 getString(key)、getBoolean(key) 等方法不会读取空指针。\n\n即，对于以下 Json：\n\n```\n{\n    \"key\":\"DFG1H56EH5JN3DFA\",\n    \"token\":\"124ASFD53SDF65aSF47fgT211\"\n}\n```\n\n若执行：\n\n```\nJsonMap data = JsonMap.parse(\"{\\\"key\\\":\\\"DFG1H56EH5JN3DFA\\\",\\\"token\\\":\\\"124ASFD53SDF65aSF47fgT211\\\"}\");\n\nString key = data.getString(\"key\");                     //获得“key”的值\nString name = data.getString(\"name\");                   //显然，这段 json 并没有“name”字段\nJsonMap data = data.getJsonMap(\"data\");                 //这段 json 中没有名为“data”的子 json 对象\nString age = data.getJsonMap(\"data\").getInt(\"age\");     //更不可能有“data”下的值“age”\n```\n\n上述 get 方法均不会报空指针错误，而是会获得该类型的默认空值，即：\n\n```\nkey = \"DFG1H56EH5JN3DFA\"\nname = \"\"\ndata = new JsonMap()    //返回空的 JsonMap 对象，可使用 isEmpty() 判空\nage = 0\n```\n\n对于默认状态可能为 0 的 int 类型的值，或本身可能为 \"\" 的 String 类型的值，可以使用如下方法来设置 defaultValue：\n\n```\nString name = data.getString(\"name\", \"zhangsan\");           //若该字段为空，则返回 “zhangsan”\nString age = data.getJsonMap(\"data\").getInt(\"age\", -1);     //若该字段为空，则返回 -1\n```\n\n弹性设计是为了避免不必要的空指针问题，但同时也兼顾判空的麻烦情况，减少代码所需要对空指针的额外判断。\n\n#### 在 JsonList 中查找\n\n对于 JsonList，要寻找其中**含有**已知 key=value 的 JsonMap，可使用 `.findJsonMap(key, value)` 来寻找其中符合结果的 JsonMap，例如：\n\n```java\n//查找某个符合 key=value 的结果：\nJsonMap result = jsonList.findJsonMap(\"key\", \"value\");\n// result 不会为 null，若需要判空请使用 result.isEmpty()\n\n//查找某个符合 key=value 的结果，并对其内容进行修改：\njsonList.findJsonMap(\"key\", \"value\")\n        .set(\"age\", 3);\n```\n\n#### JsonList 数据预处理\n\n当 JsonList 的数据全都是 JsonMap，且需要对 JsonMap 的数据内容进行预处理，那么可以通过以下方法实现：\n\n```java\nJsonList list = ...;\nlist.preprocessedJsonMapData(new JsonMapPreprocessingEvents() {\n    @Override\n    public JsonMap processingData(JsonMap originData) {\n        originData.set(\"goods_price_str\", \"¥\" + originData.getString(\"goods_price\"));\n        return originData;\n    }\n});\nSystem.out.println(list.toString());\n```\n\n上述代码会将 JsonList 中每个  JsonMap 的 `goods_price` 字段读取，并设置一个新的字段：`goods_price_str` ，使其值等于 \"¥\" + `goods_price`。\n\n## 当 Json 存在问题\n\n对于如下异常情况，也可以放心使用：\n\n```\n{\n    \"key\":\"DFG1H56EH5JN3DFA\",\n    \"token\":\"124ASFD53SDF65aSF47fgT211\",\n    \"name\":null,\n    \"data\":[],\n    \"list\":\"[{\"limitMoney\\\":\\\"26\\\",\\\"discountMoney\\\":\\\"3\\\"},{\\\"limitMoney\\\":\\\"40\\\",\\\"discountMoney\\\":\\\"4\\\"}]\"\n    \"age\":\"3\",\n    \"signed\":\"true\",\n}\n```\n\n对于上述 Json，与服务端约定 data 应为 Json 对象而非集合、name 应该有值但给出为 null、age 和 signed 的类型不对，使用本框架按照以下代码，依然能够正常解析：\n\n```\nString name = data.getString(\"name\");       //返回 “” 空值\nJsonMap data = data.getJsonMap(\"data\");     //返回空的 JsonMap 对象，可使用 isEmpty() 判空\nint age = data.getInt(\"age\");               //返回 3\nboolean signed = data.getBoolean(\"signed\"); //返回 true\nJsonList list = data.getList(\"list\");       //返回解析为 JsonList 的对象\nString list = data.getList(\"list\")\n                  .getJsonMap(0)\n                  .getInt(\"limitMoney\");    //返回 26\n```\n\n可见，在 BaseJson 中，类型并不是绝对的，不同类型可以进行“软”转换，以获得最符合预期的解析结果。\n\n你无需担心任何来自后端的异常情况，使用 BaseJson 解析都可以保证绝对不会出现空指针异常。\n\n## 输出 Json 文本\n\n你可以手动创建 JsonMap 或 JsonList，或使用现有的 Map、List 对象构建 JsonMap、JsonList。\n\n使用相应的`set(...)`方法添加值，然后使用`toString()`方法构建 Json 文本。\n\n```\nJsonMap data = ...;\nString jsonObj = data.toString();\n```\n\n## JsonMap 与 JavaBean 的互相转换\n\n使用 JsonBean 工具类，实现 JavaBean 与 JsonMap 之间的互相转换，这里使用了反射技术。\n\n请注意编译为 release 时的混淆设置，必须 keep 所有项目中用到的 JavaBean 及 com.kongzue.baseokhttp.util 下的工具类，否则可能在运行时出现问题。\n\n### 由 JsonMap 转换为 JavaBean\n\n例如现在已经有一个 JavaBean 对象 User，以及对应的数据 jsonMap，则：\n\n```\nUser user = JsonBean.getBean(jsonMap, User.class);\n```\n\n即可将 jsonMap 中的数据对应到 User 类中。\n\n请注意，JavaBean 对象中必须包含每个属性的对应 get、set 方法，且必须使用驼峰命名规则。\n\n支持 boolean 类型的数据获取方法以“is”开头的命名方式，例如“boolean isVIP()”或者“boolean getVIP()”都可以。\n\n### 由 JavaBean 转换为 JsonMap\n\n此时已经有一个设置好数据的 User 对象 user，要转换为 JsonMap：\n\n```\nJsonMap userJson = JsonBean.setBean(user);\n```\n\n转换后即可获得 JsonMap 对象。\n\n## 由 JsonList 直接生成适配器 Adapter\n\n可以使用 JsonList 的方法 `.createAdapter(context, layoutResId)` 直接生成可用于列表等组件的适配器 JsonListAdapter，也可以通过构造方法构建。\n\nJsonListAdapter 旨在帮助开发者快速并轻松的完成网络请求下来的 json 数据集到界面 UI 构建的过程，只需要对应好 json 数据集（JsonList）中每个 json 数据（JsonMap）中的键值对中的键（key），与制作布局时为其对应的 View 设置好一样的 `android:tag` 属性，即可完成数据对应绑定显示到 UI。\n\n```java\nJsonListAdapter adapter = new JsonListAdapter(me, R.layout.item_my_order_list, orderList);\nlistView.setAdapter(adapter);\n```\n\nJsonListAdapter 只需要指定上下文（context）、列表项布局资源ID（layoutResId）以及数据集（JsonList）即可自动根据 JsonList 的元素 JsonMap 中 key 对应在列表项布局中对应 tag 的 View 进行关系绑定，并直接为其赋值。\n\n\u003e **TextView 自动绑定:**\n\u003e 当数据为 String 时自动设置 setText；当数据为 int 时自动调用并设置为文本资源\n\u003e **ImageView 自动绑定:**\n\u003e 当数据为 int 时自动调用并设置为图像资源；当数据为 String 时自动设置图像 Uri；\n\n其它 View 或者具有自定义方法的情况可以使用重写 JsonListAdapter#bindEvents、或者使用 jsonListAdapter.setEvents(JsonListAdapterEvents#bindEvents) 来实现，例如：\n\n```java\nJsonListAdapter adapter = new JsonListAdapter(me, R.layout.item_my_order_list, orderList) {\n    /**\n     * 绑定事件\n     * 除非你要在列表项中处理某些控件的事务，例如单独指定 setOnClickListener，不然不建议使用\n     * 原则就是能尽量少的干涉执行过程就尽量少干涉，能提前预处理好就提前预处理好，\n     * 别搁运行过程中呼啦啦搞一大堆的逻辑处理，不然不卡你卡谁\n     *\n     * @param context    上下文\n     * @param itemView   列表项根布局\n     * @param viewHolder 所有子布局\n     * @param data       数据\n     * @param index      索引\n     * @param dataList   数据集\n     */\n    @Override\n    public void bindEvents(Context context, View itemView, JsonListAdapter.ViewHolder viewHolder, JsonMap data, int index, JsonList dataList) {\n      //...\n    }\n};\n```\n\n还有两个事件可供重写：\n\n```java\n/**\n * 预处理数据\n * 但不建议使用，更推荐在数据加载后，在网络请求或异步线程中完成所有数据的预处理，\n * 否则可能带来列表滑动过程的卡顿和性能问题。\n *\n * @param context    上下文\n * @param itemView   列表项根布局\n * @param viewHolder 所有子布局\n * @param data       数据\n * @param index      索引\n * @param dataList   数据集\n * @return 处理完的数据\n */\nJsonMap preprocessedData(Context context, View itemView, JsonListAdapter.ViewHolder viewHolder, JsonMap data, int index, JsonList dataList);\n\n/**\n * 设置数据\n * 我们已经预设了两种数据自动绑定的场景：例如，TextView 自动绑定:\n * {当数据为 String 时自动设置 setText；当数据为 int 时自动调用并设置为文本资源}\n * ImageView 自动绑定:\n * {当数据为 int 时自动调用并设置为图像资源；当数据为 String 时自动设置图像 Uri；}\n * 上述过程都是自动支持的，如果你有特殊需求或者其它组件需要设置，可以重写以下方法进行处理\n *\n * @param context  上下文\n * @param tag      子布局 view 的标签\n * @param view     子布局\n * @param data     数据\n * @param index    索引\n * @param dataList 数据集\n */\nvoid setData(Context context, String tag, View view, JsonMap data, int index, JsonList dataList);\n```\n\n上述方法也可以通过 `adapter.setEvents(JsonListAdapterEvents)` 接口来完成设置。\n\n### 一点骚操作\n\n假设 json 原文是这样的：\n```json\n[\n  {\n    \"extra_info\": {\n      \"content_name\": \"test name\"\n    },\n    \"data\": \"this is real data\"\n  }\n]\n```\n要适配 `extra_info` 里的 `content_name` 给一个 TextView，在 xml 中设置对应的数据 tag，可直接设置为：\n```xml\n\u003cTextView\n    ...\n    android:tag=\"extra_info.content_name\"\n/\u003e\n```\n\n## 开源协议\n\n```\nCopyright Kongzue BaseJson\n\nLicensed under the Apache License, Version 2.0 (the \"License\");\nyou may not use this file except in compliance with the License.\nYou may obtain a copy of the License at\n\n http://www.apache.org/licenses/LICENSE-2.0\n\nUnless required by applicable law or agreed to in writing, software\ndistributed under the License is distributed on an \"AS IS\" BASIS,\nWITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\nSee the License for the specific language governing permissions and\nlimitations under the License.\n```\n\n## 更新日志\n\n请前往 [Release Page](https://github.com/kongzue/BaseJson/releases) 查看\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fkongzue%2Fbasejson","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fkongzue%2Fbasejson","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fkongzue%2Fbasejson/lists"}