第一篇咱们主要学习了实体与json的相互转换的问题,但是咱们需要的是数据 你转换18遍我取不到数据也是扯淡,那么今天咱们就一起学习一下如何从使用Jackson从Json字符串中取值。废话不说直接上代码(注意第一篇里面的方法我都移到JsonProcessUtil里面了方便使用
)。
从Json字符串中取出指定节点的值
public static void getValue(TestVo vo) throws Exception {
// 准备工作 传入vo请参照第一篇里面的实体。此处不再重新贴上代码 浪费大家时间
ObjectMapper mapper = JsonProcessUtil.getMapperInstance(false);
String voJson = JsonProcessUtil.toJson(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 getValue(TestVo vo) throws Exception {
// 准备工作 传入vo请参照第一篇里面的实体。此处不再重新贴上代码 浪费大家时间
ObjectMapper mapper = JsonProcessUtil.getMapperInstance(false);
String voJson = JsonProcessUtil.toJson(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 = 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;
}
注意:JsonNode 提供了很多种取值的方法,但是为了通用我选择了toString()因为getTextValue(),getIntValue()……一些方法只能返回指定类型的值,这样不能达到通用。而且有一种情况如果我想要的是整个节点下面所有子节点的值呢?如果使用上面的方法就没办法了,只能使用toString()这时候它返回的是整个json字符串。注意:toString()方法如果只返回某一个属性的值 如:name 而不是一整个大节点如:name,age,gender,那么它会在返回的字符串上加双引号,用的时候注意去掉开始结束的双引号。
今天就学习到这,下篇文章我将与大家一起探讨一下为什么 我创建一个ObjectMapper对象要搞的那么复杂!不直接new。
分享到:
相关推荐
在Java中,将JSON字符串转换为Map或List是常见的操作,这在处理服务器返回的数据或者进行数据序列化时非常有用。 JSON字符串的结构主要包括对象(键值对的集合,用花括号{}包围)和数组(有序元素的集合,用方括号...
#### 三、从JSON字符串取值 在将对象转换成JSON字符串后,我们还需要能够从这个字符串中提取所需的信息。这可以通过遍历JSON字符串并解析其中的键值对来完成。 ##### 1. 实现方式 - 使用`JSON.parseObject`等工具...
要从这种格式的JSON字符串中提取值,我们可以使用Fastjson库。首先,我们需要导入Fastjson的相关类: ```java import com.alibaba.fastjson.JSON; import com.alibaba.fastjson.JSONArray; import ...
当JSON数据返回到前端,JavaScript代码会解析这个JSON字符串,将数据点插入到Highcharts的`series.data`数组中,最后调用`chart.redraw()`或`chart.update()`方法来更新图表,展示新的曲线报表。 这个例子展示了...
针对这个问题,本文将介绍两种方法,可以使得在使用Jackson进行序列化时,实体对象的属性值为null时,该属性不会被包含在生成的JSON字符串中。 首先,我们可以使用注解@JsonInclude来指定哪些属性需要被序列化。这...
在大多数编程语言中,都有现成的库或框架支持JSON序列化,例如在Java中我们可以使用Jackson或Gson库,在Python中可以使用json模块,将数据对象转换成JSON字符串。 例如,假设我们有一个用户表,包含id、name和email...
在这个例子中,Servlet会创建一个JSONArray对象,将获取到的一级选项数据填充进去,然后使用`response.getWriter().write()`将JSON字符串写入HTTP响应。这样,当Ajax请求返回时,JavaScript的`success`回调就能接收...
对于对象和集合类型参数值,则需要在后台先使用JSON工具(如Jackson或Fastjson)将它们转换为JSON字符串,再将其存入Model中,前端就可以通过EL表达式访问并解析这些JSON字符串了。 这样,当页面加载时,JSP页面会...
对于Boolean类型,我们需要注意Map中的值可能是"true"或"false"字符串,所以我们需要将其转换为Boolean对象: ```java Boolean boolValue = Boolean.valueOf((String) map.get("myBoolean")); method.invoke(target...