Jackson第二篇【从JSON字符串中取值】

来源:http://blog.csdn.net/songyongfeng/article/details/6932674

第一篇咱们主要学习了实体与json的相互转换的问题,但是咱们需要的是数据 你转换18遍我取不到数据也是扯淡,那么今天咱们就一起学习一下如何从使用Jackson从Json字符串中取值。废话不说直接上代码。

从Json字符串中取出指定节点的值

	public static void getValue(TestVo vo) throws Exception {   
	    // 准备工作 传入vo请参照第一篇里面的实体。此处不再重新贴上代码 浪费大家时间   
	    ObjectMapper mapper = CommonUtil.getMapperInstance(false);   
	    String voJson = CommonUtil.beanToJson(vo);   
	    JsonNode node = mapper.readTree(voJson);// 这里的JsonNode和XML里面的Node很像   
	    System.out.println("readValueFromJson>>>" + node.get("voName").toString());// 获取voName   
	    // 输出结果:readValueFromJson>>>一个容器而已   
	} 
怎么样简单吧,但是这个作用不是很大啊!我想获取TestVo下面的Person的name的值 该怎么办呢?别着急,咱们走起


	public static void getValue2(TestVo vo) throws Exception {   
	    // 准备工作 传入vo请参照第一篇里面的实体。此处不再重新贴上代码 浪费大家时间   
	    ObjectMapper mapper = CommonUtil.getMapperInstance(false);   
	    String voJson = CommonUtil.beanToJson(vo);   
	    JsonNode node = mapper.readTree(voJson);// 这里的JsonNode和XML里面的Node很像   
	    node = node.get("pers");   
	    System.out.println("node是不是个集合:" + node.isArray());// 这个方法咱们后面会用到先让它给大家照个面   
	    for (int i = 0; i < node.size(); i++) {   
	        JsonNode childNode = node.get(i);   
	        System.out.println("readValueFromJson>>>" + childNode.get("name").toString());// 获取name   
	    }   
	    /*  
	     * 输出结果   
	     * node是不是个集合:true  
	     * readValueFromJson>>>张三   
	     * readValueFromJson>>>李四  
	     * readValueFromJson>>>王二麻子  
	     */  
	}

怎么样功能还行吧?如果这样你就满意了,那你也太容易满足了。现在我在项目中需要像xpath那样来查找某节点的值(不太了解xpath的童鞋别着急我以后会和大家一起学习下)。/a/b/c/d 这样找到某个节点的值。为了增加复杂度,我又给Person类里面增加 一个List<Person> childs;表示这个人的孩子那么咱们一往下需找的节点就多了……

  首先看下我准备的数据

{"voName":"一个容器而已","pers":[{"name":"张三","age":46,"childs":[{"name":"小张三1","age":20,"childs":null},{"name":"小张三2","age":17,"childs":null}]},{"name":"李四","age":29,"childs":[{"name":"小李四1","age":20,"childs":null}]},{"name":"王二麻子","age":23,"childs":null}]}

张三:有两个孩子 李四:有一个孩子 王二麻子:没有孩子

我现在要做的就是把所有的孩子找出来。

废话不多说直接看代码

	public static void main(String[] args) throws Exception {  
	    // 准备数据  
	    List<Person> pers = new ArrayList<Person>();  
	    List<Person> childs = new ArrayList<Person>();  
	    Person p = new Person("张三", 46);  
	    childs.add(new Person("小张三1", 20));  
	    childs.add(new Person("小张三2", 17));  
	    p.setChilds(childs);  
	    pers.add(p);  
	    p = new Person("李四", 29);  
	    childs = new ArrayList<Person>();  
	    childs.add(new Person("小李四1", 20));  
	    p.setChilds(childs);  
	    pers.add(p);  
	    p = new Person("王二麻子", 23);  
	    pers.add(p);  
	    TestVo vo = new TestVo("一个容器而已", pers);  
	    // 实体转JSON字符串  
	    String json = CommonUtil.beanToJson(vo);  
	    Object[] obj = readValueFromJson(json, "pers:childs:name").toArray();  
	    System.out.println( Arrays.toString(obj) );  
	    // 输出结果:[小张三1, 小张三2, 小李四1]  
	} 

好玩吧,接下来咱们就一起看下我这个readValueFormJson是如何实现的呢?

	/**
	 * 从json中读取tagPath处的值 tagPath用 :分隔
	 * 
	 * @param json
	 * @param tagPath
	 * @return
	 * @throws Exception
	 */
	public static List<String> readValueFromJson(String json, String tagPath) throws Exception {
		// 返回值
		List<String> value = new ArrayList<String>();
		if (CommonUtil.isEmpty(json) || (CommonUtil.isEmpty(tagPath))) {
			return value;
		}
		ObjectMapper mapper = CommonUtil.getMapperInstance(false);
		String[] path = tagPath.split(":");
		JsonNode node = mapper.readTree(json);
		getJsonValue(node, path, value, 1);
		return value;
	}

	public static void getJsonValue(JsonNode node, String[] path, List<String> values, int nextIndex) {
		if (CommonUtil.isEmpty(node)) {
			return;
		}
		// 是路径的最后就直接取值
		if (nextIndex == path.length) {
			if (node.isArray()) {
				for (int i = 0; i < node.size(); i++) {
					JsonNode child = node.get(i).get(path[nextIndex - 1]);
					if (CommonUtil.isEmpty(child)) {
						continue;
					}
					values.add(child.toString());
				}
			} else {
				JsonNode child = node.get(path[nextIndex - 1]);
				if (!CommonUtil.isEmpty(child)) {
					values.add( child.toString() );
				}
			}
			return;
		}
		// 判断是Node下是集合还是一个节点
		node = node.get(path[nextIndex - 1]);
		if (node.isArray()) {
			for (int i = 0; i < node.size(); i++) {
				getJsonValue(node.get(i), path, values, nextIndex + 1);
			}
		} else {
			getJsonValue(node, path, values, nextIndex + 1);
		}
	}

挺好吧,功能虽然实现了。但是童鞋们可能会对这个产生疑问,你他X的不是脱裤子放屁吗?先把Bean转换成Json再从Json中取值。效率低不说,而且还复杂。我直接通过get方法多好……如果你这样想了说明你是一个思考者!但是有种情况(本人在开发中遇到的)如果这个bean非常大 不同情况你需要的字段是不一样的 那你怎办? 根据情况判断if else if else if?如果有一百种情况呢?那不就累死了。所以在数据库里面配置不同业务情况从不同字段取值比较好,这样就会用到这种功能。另外附上:CommonUtil.isEmpty()方法


    /**
	 * 判断对象是否为空
	 * 
	 * @param obj
	 * @return
	 */
	public static boolean isEmpty(Object obj) {
		boolean result = true;
		if (obj == null) {
			return true;
		}
		if (obj instanceof String) {
			result = (obj.toString().trim().length() == 0) || obj.toString().trim().equals("null");
		} else if (obj instanceof Collection) {
			result = ((Collection) obj).size() == 0;
		} else {
			result = ((obj == null) || (obj.toString().trim().length() < 1)) ? true : false;
		}
		return result;
	}


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值