JsonBuilder初出茅庐

  互联网这股东风不久前刮到了甘凉国,国王老甘独具慧眼,想赶紧趁着东风未停大力发展移动互联网,因为他笃信布斯雷的理论:“站在风口上,猪都能飞起来”。无奈地方偏僻落后,国内无可用之才啊。老甘一筹莫展的低头凝思应声被打断,“启奏陛下,有四个从东土大唐来的和尚前来更换通关文牒”,听到“东土大唐”四个字,老甘心头一喜,答道:“请他们去正堂等候”。

唐僧:贫僧唐三藏,自东土大唐而来,前往西天拜佛求经,今途径贵国,恳请陛下更换通关文牒。
国王:高僧从东方而来,想必对互联网略知一二。
唐僧:贫僧也是略有耳闻,不过我的徒儿对此颇有研究。
国王:寡人现有一需求,还请高僧帮忙处理一下,事成之后,定放你们西行。需求文档一会发你。
唐僧:遵命,谢陛下。
国王:(发文档),@三藏。
唐僧:收到。
唐僧:@悟净,处理下文档中的需求。
沙僧:收到。

  对接接口繁琐复杂,还要多方联调。悟空虽然水平高,但是脾气不好,怕打起来;八戒好吃懒惰,恐难当此任;悟净,为师只有辛苦你了。唐僧心里想到此,不由得叹气一声。

沙僧:师傅,这文档写的乱七八糟、语句不通,很多入参、出参模糊不清,对方测试环境时好时坏,给他们打电话,他们说很忙暂时没时间管我。
唐僧:悟净,这些为师都知道。程序员都没什么文化,注释、文档总是写不好;而且非常苦逼,总是熬夜加班,所以没有时间。你应该理解以下。
沙僧:哎。。。入参报文格式为json,且非常复杂,我拼了一上午报文,每次都返回入参报文格式不正确。
唐僧:你是怎么拼json格式的报文呢?
沙僧:传统方法啊,先用Map和List组合好,再转成json字符串。
唐僧:如果json非常复杂的话,要定义好多Map和List,光起些好点儿的名字就够头大的,还要再互相嵌套起来,稍有不慎,很容易出错。真是够够的了。而且要写很多代码。
沙僧:谁说不是呢,师傅有什么好方法吗?
唐僧:json结构你应该很熟悉,它是一个自我嵌套的递归结构。那我们就来设计一个构建器来直接构建json字符串,就叫JsonBuilder吧。
沙僧:我突然想起StringBuilder,它的流式api非常好用,快捷方便。只是字符串是一维的,只有先后顺序,但json是二维的,既有先后顺序,还有内外顺序。
唐僧:你说的内外顺序其实就是父子关系,这也很好处理。
  1)只需维护一个指向当前级别的指针,如果只是添加简单的key-value,当前级别保持不变。
  2)如果添加了复合value(子节点),当前指针指向新添加的级别(深入一级),此时该级别就成了新的当前级别。
  3)当前级别结束后只需回到父级别(退出一级),此时父级别就又成了新的当前级别,如此往复下去即可。
沙僧:师傅,恕徒儿愚钝,您讲的太抽象了,能不能举个例子。
唐僧:看下面的json,

{
  "string":"编程新说",
  "int":33,
  "boolean":true,
  "double":3.14,
  "null":null,
  "sub1":{
    "string":"编程新说",
    "int":33,
    "boolean":true,
    "double":3.14,
    "null":null
  },
  "sub2":[
    {
      "string":"编程新说",
      "int":33,
      "boolean":true,
      "double":3.14,
      "null":null
    },
    {
      "string":"编程新说",
      "int":33,
      "boolean":true,
      "double":3.14,
      "null":null
    }
  ],
  "sub3":[
    "编程新说",
    33,
    true,
    3.14,
    null
  ]
}
  1)首先指针指向最外层级别,此时添加5个简单的key-value,整个添加过程级别保持不变,即这5个值都添加给了当前级别。
  2)然后添加sub1节点,它是一个复合节点,所以当前指针指向新添加的节点级别,此时添加5个简单的key-value,都添加给了sub1,结束后指针回退到上一级。
  3)此时再添加sub2,当前指针指向sub2,因sub2是一个数组,也是复合节点。
  4)数组里包含的又是复合节点,只不过没有名字而已。添加一个无名字节点,当前指针指向该节点,此时可以为它添加5个key-value,然后回到上一级,即数组级别
  5)然后添加第二个无名字节点,为它添加5个key-value,回到上一级,再回到上一级。
  6)然后添加sub3,因为它的value都是简单值,所以添加value时当前级别不变,停留在数组级别。完成之后回到上一级,即最外层级别。
沙僧:这么一讲解倒是非常直观,层次也很清晰,所见即所得。还是师傅厉害。
唐僧:为师也没那么厉害了,只是趁着你们打妖怪的时候,多琢磨了一会儿。说起来简单,实现起来还是有些许难度的,要不你来试试。可以参考这个示例。

JsonBuilder jb = new JsonBuilder();
jb.kv("string", "编程新说")
.kv("int", 33)
.kv("boolean", true)
.kv("double", 3.14)
.kv("null", null)
.ko("sub1")
    .kv("string", "编程新说")
    .kv("int", 33)
    .kv("boolean", true)
    .kv("double", 3.14)
    .kv("null", null)
.end()
.ka("sub2")
    .io()
        .kv("string", "编程新说")
        .kv("int", 33)
        .kv("boolean", true)
        .kv("double", 3.14)
        .kv("null", null)
    .end()
    .io()
        .kv("string", "编程新说")
        .kv("int", 33)
        .kv("boolean", true)
        .kv("double", 3.14)
        .kv("null", null)
    .end()
.end()
.ka("sub3")
    .iv("编程新说")
    .iv(33)
    .iv(true)
    .iv(3.14)
    .iv(null)
.end();
沙僧:好的,只是这变量名字有点。。。但别光我一人啊,也让广大群众试试吧。

  悟净得到师傅的指点后,有一点小小的豁然开朗,决定自己去实现一把。但想到又开始去对接口,不由得叹气一声,哎。。。

 

PS:也可以按照此方法写一个MapBuilder。
PS:也可以按照此方法写一个XmlBuilder。

 

 

(完)

 

编程新说


用独特的视角说技术

 

转载于:https://www.cnblogs.com/lixinjie/p/json-builder.html

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/249901.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Nexus介绍

转自:https://www.cnblogs.com/wincai/p/5599282.html 开始在使用Maven时,总是会听到nexus这个词,一会儿maven,一会儿nexus,当时很是困惑,nexus是什么呢,为什么它总是和maven一起被提到呢&#…

vue-cli 打包

一项目打包 1 打包的配置在 build/webpack.base.conf.js文件下 常量config在vue/config/index.js 文件下配置,__dirname是定义在项目的全局变量,是当前文件所在项目的文件夹的绝对路径。 2 需要修改vue/config/index.js 文件下的将build对象下的assets…

乘风破浪:LeetCode真题_010_Regular Expression Matching

乘风破浪:LeetCode真题_010_Regular Expression Matching 一、前言 关于正则表达式我们使用得非常多,但是如果让我们自己写一个,却是有非常大的困难的,我们可能想到状态机,确定,非确定状态机确实是一种解决…

vue项目工程中npm run dev 到底做了什么

npm install 安装了webpack框架中package.json中所需要的依赖 2.安装完成之后,需要启动整个项目运行,npm run 其实执行了package.json中的script脚本,npm run dev的执行如下 3.底层相当执行webpack-dev-server --inline --progress --confi…

bat等大公司常考java多线程面试题

1、说说进程,线程,协程之间的区别 简而言之,进程是程序运行和资源分配的基本单位,一个程序至少有一个进程,一个进程至少有一个线程.进程在执行过程中拥有独立的内存单元,而多个线程共享内存资源,减少切换次数,从而效率更高.线程是进程的一个实体,是cpu调度和分派的基本单位,是比…

offset系列,client系列,scroll系列回顾

一 scroll系列属性 ——滚动1 scrollHeight/scrollWidth 标签内部实际内容的高度/宽度ele.scrollHeight 有两种情况,当内容超出盒子范围后,返回的是内容的高度,包括padding,从顶部内侧到内容的最外部分。当内容不超出盒子范围…

项目开发中的自我总结

最近忙的要死,因为新开发了两个项目.现在已经测试完毕了,准备部署到线上了. 然后不能白忙活吧,忙活完也得写点总结和经验吧,以后也有个记录. 1.一个bootstrapjquerylayuilaravel 5.4开发的一个后台系统 比较朴素 2.一个前后端分离的vuelaravel 5.4 开发的商家系统 我只负责后端…

数组黑科技(偏性能方面)未完待更新...

数组去重最优解:Array.prototype.unique function () {var tmp new Map();return this.filter(item > {return !tmp.has(item) && tmp.set(item,1);})}搭配使用 Array.from(foo); // ["f", "o", "o"]let s new Set([f…

控制台添加log4net

1.添加nuget包 log4net 2.app.config配置 <?xml version"1.0" encoding"utf-8"?> <configuration> <configSections><section name"log4net" type"log4net.Config.Log4NetConfigurationSectionHandler, log4net&quo…

touchWX 自定义组件以及传值

创建如图文件 index.wxc: <template><view class"wx-test" bindtap"handleTap">{{ msg }}{{dataIndex}}</view> </template> <script>export default {properties: {dataIndex: {type: String,value: default value,}},data…

vue 初始框架

VueJs讲解初始框架 一、启动项目 第一步&#xff1a;cmd进入项目文件里&#xff0c;运行npm run dev 启动项目 这里说明启动端口号是8080 第二步&#xff1a;往页面输入&#xff1a;localhost:8080 二、解析渲染步骤 先看整体框架样式和index.html&#xff1a; 从上面我…

Country Road Aizu - 2104

题目链接&#xff1a; https://vjudge.net/problem/Aizu-2104 题解&#xff1a; 咋说啊&#xff0c;一言难尽&#xff0c;花了半小时写出来的&#xff0c;卡了十分钟才恍然大明白是排序。 具体就是让每个村子都通上电&#xff0c;变压器在的村子&#xff0c;与变压器连线点线长…

IdentityServer4【QuickStart】之使用asp.net core Identity

使用asp.net core Identity IdentityServer灵活的设计中有一部分是可以将你的用户和他们的数据保存到数据库中的。如果你以一个新的用户数据库开始&#xff0c;那么&#xff0c;asp.net core Identity是一个选择。这个示例演示了如何在IdentityServer中使用asp.net core Ientit…

vue demo1

1.开发工具 试过sublime&#xff0c;现在转战vscode&#xff0c;觉得很顺手&#xff0c;总之啥工具习惯就好。 vscode用着不错的插件&#xff0c;推荐安装。 2.项目目录介绍 vue-cli生成的项目目录有点多&#xff0c;初看有点懵&#xff0c;梳理一下会好很多。 ├── ind…

CentOS下防御或减轻DDoS攻击方法(转)

查看攻击IP 首先使用以下代码&#xff0c;找出攻击者IP netstat -ntu | awk {print $5} | cut -d: -f1 | sort | uniq -c | sort -n 将会得出类似如下的结果&#xff1a; 1 114.226.9.132 1 174.129.237.157 1 58.60.118.142 1 Address 1 servers) 2 118.26.131.78 3 123.125.1…

vscode - 添加背景图片

首先&#xff0c;CtrlShiftP安装backround &#xff0c; 而后重启vscode会有默认的背景图片 修改背景图&#xff0c;可自定义三张 具体请看gif图 最开始时&#xff0c;发现png根本不是全透明&#xff0c;用ps处理了一下&#xff08;下列所有操作均字母组合&#xff09; 1.1 Ctr…

关于Vue.use()详解

问题 相信很多人在用Vue使用别人的组件时&#xff0c;会用到 Vue.use() 。例如&#xff1a;Vue.use(VueRouter)、Vue.use(MintUI)。但是用 axios时&#xff0c;就不需要用 Vue.use(axios)&#xff0c;就能直接使用。那这是为什么呐&#xff1f; 答案 因为 axios 没有 install。…

分布式工具的一次小升级⏫

前言 之前在做 秒杀架构实践 时有提到对 distributed-redis-tool 的一次小升级&#xff0c;但是没有细说。 其实主要原因是&#xff1a; 秒杀时我做压测&#xff1a;由于集成了这个限流组件&#xff0c;并发又比较大&#xff0c;所以导致连接、断开 Redis 非常频繁。 最终导致获…

浅谈vue $mount()

Vue 的$mount()为手动挂载&#xff0c;在项目中可用于延时挂载&#xff08;例如在挂载之前要进行一些其他操作、判断等&#xff09;&#xff0c;之后要手动挂载上。new Vue时&#xff0c;el和$mount并没有本质上的不同。 具体见代码&#xff1a; 顺便附上vue渲染机制流程图&a…

论一个程序员的自我修养-从一张图片说起

故事起源 本来今天想写.NET Core实战之CMS系统第十五篇文章的。哈&#xff0c;奈何今天在新生命人脉群里面看到石头哥分享的一张图片&#xff0c;然后大家就议论了起来&#xff0c;不过我看的很懵逼&#xff0c;这图什么意思啊&#xff1f;当一个朋友讲述了这个图片背后的故事的…