欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  IT编程

Java开发笔记(一百零八)JSON串的定义和解析

程序员文章站 2022-10-08 15:22:12
前面提到URL尾巴支持添加请求参数,具体格式形如“参数A名称=A参数值&参数B名称=B参数值”,可是这种格式只能传递简单的键值对信息,不能传递结构化数据,也无法传递数组形式的参数,因而它不适用于需要输入复杂参数的场合。为此人们发明了一种轻量级的数据交换格式JSON,它的数据格式完全独立于编程语言,不 ......

前面提到url尾巴支持添加请求参数,具体格式形如“参数a名称=a参数值&参数b名称=b参数值”,可是这种格式只能传递简单的键值对信息,不能传递结构化数据,也无法传递数组形式的参数,因而它不适用于需要输入复杂参数的场合。为此人们发明了一种轻量级的数据交换格式json,它的数据格式完全独立于编程语言,不但能够表达寻常的键值对信息,还支持表达数组形式的各类参数,从而满足了复杂参数的传输要求。
不过java的开发包并未提供相应的工具来处理json串,为此我们需要在工程中添加第三方json解析库,常见的json处理工具有阿里巴巴的fastjson,它的下载页面是http://repo1.maven.org/maven2/com/alibaba/fastjson/,最新的版本已经迭代到了1.2.56。若想在代码中使用fastjson的工具,则需先将它的jar包添加到工程的支持库,右击eclipse左边项目视图中的工程名称,在右键菜单中依次选择“build path”——“configure build path ...”。在弹出的新窗口中单击右边的libraries选项卡,接着单击右侧的“add jars...”按钮,在另一个弹窗中找到fastjson-1.2.56.jar,如下图所示。

Java开发笔记(一百零八)JSON串的定义和解析
然后单击ok按钮,回到前一个弹窗也单击ok按钮,完成fastjson的支持库引入操作。
接下来浏览一个购物订单的json串例子,具体内容见下:

{
	"user_info":{
		"name":"思无邪",
		"address":"桃花岛水帘洞123号",
		"phone":"15960238696"
	},
	"goods_list":[
		{
			"goods_name":"mate30",
			"goods_number":1,
			"goods_price":8888
		},
		{
			"goods_name":"格力*空调",
			"goods_number":1,
			"goods_price":58000
		},
		{
			"goods_name":"红蜻蜓皮鞋",
			"goods_number":3,
			"goods_price":999
		}
	]
}

 

从以上json串的内容可以梳理出它的基本格式定义,详细说明如下:
1、整个json串由一对花括号包裹,并且内部的每个结构都以花括号包起来;
2、参数格式类似键值对,其中键名与键值之间以冒号分隔,形如“键名:键值”;
3、两个键值对之间以逗号分隔;
4、键名需要用双引号括起来,键值为数字的话则无需双引号,为字符串的话仍需双引号;
5、json数组通过方括号表达,方括号内部依次罗列各个元素,具体格式形如“数组的键名:[元素1,元素2,元素3]”;
由此可见,json串的格式定义很简洁,层次结构也很清晰。使用fastjson解析json串更是方便,首先调用jsonobject的parseobject方法,得到某个json串的jsonobject对象,示例代码如下:

		// 根据json串获得jsonobject对象
		jsonobject object = jsonobject.parseobject(json);

 

接着就能对jsonobject对象开展进一步的操作,主要的处理方法说明如下:
getstring:获取指定键名的字符串。
getintvalue:获取指定键名的整型数。
getdoublevalue:获取指定键名的双精度数。
getbooleanvalue:获取指定键名的布尔值。
getjsonobject:获取指定键名的jsonobject对象。
getjsonarray:获取指定键名的jsonarray数组。注意jsonarray类型派生自清单list,意味着可以把它当作清单一样读写。
put:添加指定的键值对信息。
remove:移除指定键名的键值对。
clear:清空当前的jsonobject对象。
tojsonstring:把jsonobject对象转换为字符串。

针对前述的购物订单json串,为了有效地保存解析后的订单信息,有必要定义几个相应的实体类。比如要定义一个用户信息类,该类的定义代码如下所示:

//定义一个用户信息
public class userinfo {
	public string name; // 用户姓名
	public string address; // 收货地址
	public string phone; // 联系号码
}

 

再定义一个商品项信息类,该类的定义代码如下所示:

//定义一项商品信息
public class goodsitem {
	public string goods_name; // 商品名称
	public int goods_number; // 商品数量
	public double goods_price; // 商品价格
}

 

最后定义外层的购物订单信息类,该类的定义代码如下所示:

//定义一次购物订单信息
public class goodsorder {
	// 用户信息
	public userinfo user_info = new userinfo();
	// 购买的商品清单
	public list<goodsitem> goods_list = new arraylist<goodsitem>();
}

 

定义好了这些实体类,即可将jsonobject对象中的各个数据解析并填入购物订单对象,完整的json解析代码示例如下:

	// 把json字符串解析到对应的实体对象
	private static goodsorder testparserjson(string json) {
		// 创建一个购物订单对象
		goodsorder order = new goodsorder();
		// 根据json串获得jsonobject对象
		jsonobject object = jsonobject.parseobject(json);
		// 从jsonobject对象中获取键名为user_info的用户信息json对象
		jsonobject user_info = object.getjsonobject("user_info");
		// 从用户信息json对象中获取键名为name的字符串
		order.user_info.name = user_info.getstring("name");
		// 从用户信息json对象中获取键名为address的字符串
		order.user_info.address = user_info.getstring("address");
		// 从用户信息json对象中获取键名为phone的字符串
		order.user_info.phone = user_info.getstring("phone");
		system.out.println(string.format("用户信息如下:姓名=%s,地址=%s,手机号=%s", 
				order.user_info.name, order.user_info.address, order.user_info.phone));
		// 从jsonobject对象中获取键名为goods_list的商品信息json数组
		jsonarray goods_list = object.getjsonarray("goods_list");
		for (int i=0; i<goods_list.size(); i++) { // 遍历商品信息数组
			goodsitem item = new goodsitem(); // 创建一项商品对象
			// 从json数组获取下标为i的商品json对象
			jsonobject goods_item = (jsonobject) goods_list.get(i);
			// 从商品json对象中获取键名为goods_name的字符串
			item.goods_name = goods_item.getstring("goods_name");
			// 从商品json对象中获取键名为goods_number的整型数
			item.goods_number = goods_item.getintvalue("goods_number");
			// 从商品json对象中获取键名为goods_price的双精度数
			item.goods_price = goods_item.getdoublevalue("goods_price");
			system.out.println(string.format("第%d个商品:名称=%s,数量=%d,价格=%f", 
					i+1, item.goods_name, item.goods_number, item.goods_price));
			order.goods_list.add(item); // 往商品清单中添加指定商品对象
		}
		return order; // 返回解析后的购物订单对象
	}

 

运行上述的解析代码,观察到以下的购物订单日志,可见成功实现了json串到对象的解析操作:

用户信息如下:姓名=思无邪,地址=桃花岛水帘洞123号,手机号=15960238696
第1个商品:名称=mate30,数量=1,价格=8888.000000
第2个商品:名称=格力*空调,数量=1,价格=58000.000000
第3个商品:名称=红蜻蜓皮鞋,数量=3,价格=999.000000

注意到商品订单json串跟goodsorder定义的数据结构一一对应,不管是参数名称还是参数类型全部吻合,如此一来就能运用fastjson的自动转换绝技,整个自动转换只有两次代码调用:第一次调用jsonobject的parseobject方法,获得json串对应的jsonobject对象;第二次调用jsonobject的tojavaobject方法,依次填写上一步骤的jsonobject对象,以及待转换的实体类型如goodsorder.class。下面便是将json串自动转换成实体对象的代码例子:

		// 根据json串获得jsonobject对象
		jsonobject object = jsonobject.parseobject(json);
		// 把jsonobject对象中的信息一一转成购物订单信息
		goodsorder order = (goodsorder) jsonobject.tojavaobject(object, goodsorder.class);

 

哇噻,这个自动转换功能不要太好用哟,实乃开发者的一大福音。反过来,把某个实体对象转换成对应的json串,也只需短短一行代码就搞定了,调用jsonobject的tojsonstring方法即可,具体转换代码示例如下:

		// 把购物订单对象转换成json字符串
		string json = jsonobject.tojsonstring(order);

 

当然,有时候并不需要把整个实体对象都转换为json串,而是提取该对象的部分信息再封装成json串,这样的话,还是按照惯例逐步往json串添加键值对信息,也就是需要封装的数据才要put进jsonobject对象。下面是根据购物订单对象逐步生成json串的代码例子:

	// 根据购物订单对象逐步拼接生成json字符串
	private static string testgeneratejson(goodsorder order) {
		// 创建一个准备保存购物订单的jsonobject对象
		jsonobject object = new jsonobject();
		// 创建一个准备保存用户信息的jsonobject对象
		jsonobject user_info = new jsonobject();
		// 往用户信息json对象中添加键名为name的姓名信息
		user_info.put("name", order.user_info.name);
		// 往用户信息json对象中添加键名为address的地址信息
		user_info.put("address", order.user_info.address);
		// 往用户信息json对象中添加键名为phone的号码信息
		user_info.put("phone", order.user_info.phone);
		// 往购物订单json对象中添加键名为user_info的用户信息
		object.put("user_info", user_info);
		// 创建一个准备保存商品项的jsonarray数组
		jsonarray goods_list = new jsonarray();
		// 遍历购物订单里的各项商品
		for (goodsitem item : order.goods_list) {
			// 创建一个准备保存商品信息的jsonobject对象
			jsonobject goods_item = new jsonobject();
			// 往商品信息json对象中添加键名为goods_name的名称信息
			goods_item.put("goods_name", item.goods_name);
			// 往商品信息json对象中添加键名为goods_number的数量信息
			goods_item.put("goods_number", item.goods_number);
			// 往商品信息json对象中添加键名为goods_price的价格信息
			goods_item.put("goods_price", item.goods_price);
			goods_list.add(item); // 往json数组中添加jsonobject对象
		}
		// 往购物订单json对象中添加键名为goods_list的商品项信息
		object.put("goods_list", goods_list);
		return object.tojsonstring(); // 把jsonobject对象转换为json字符串
	}

 


更多java技术文章参见《java开发笔记(序)章节目录