Jackson用于解析json数据,现有解决的几个问题:
例:json数据---HBASE的JMX数据
{
"beans": [{
"name": "Hadoop:service=HBase,name=Master,sub=AssignmentManger",
"modelerType": "Master,sub=AssignmentManger",
"tag.Context": "master",
"tag.Hostname": "hadoop-warehouse-master-02",
"ritOldestAge": 0,
"ritCountOverThreshold": 0,
"BulkAssign_num_ops": 751817,
"BulkAssign_min": 0,
"BulkAssign_max": 504831,
"BulkAssign_mean": 74.20337129913264,
"BulkAssign_median": 0.0,
"BulkAssign_75th_percentile": 48.0,
"BulkAssign_95th_percentile": 80.0,
"BulkAssign_99th_percentile": 326.1299999999994,
"ritCount": 0,
"Assign_num_ops": 36716,
"Assign_min": 3,
"Assign_max": 180029,
"Assign_mean": 122.99449831136289,
"Assign_median": 26.0,
"Assign_75th_percentile": 37.0,
"Assign_95th_percentile": 120.29999999999995,
"Assign_99th_percentile": 497.46000000000254
}]
}
//获取方法:
Document document = Jsoup
.connect("http://1.1.1.1/jmx?qry=Hadoop:service=HBase,name=Master,sub=AssignmentManger")
.ignoreContentType(true)
//.header("Content-Type", "application/json;charset=UTF-8")
.timeout(10000)
.get();
System.out.println(document.body().text());
1.忽略多余不关心得字段
jackson解析json字符串,需要一个对象来进行映射。默认情况下jackson 映射得类,需要每个json字段对应一个类属性。由于json过长,真正需要的json字段可能就一两个,在写映射的对象,不想将所有的字段都列一个属性来解析。忽略没有类属性的json字段。
解决方案一:
在对应的类上加注解:@JsonIgnoreProperties(ignoreUnknown = true)
解决方案二:
ObjectMapper mapper = new ObjectMapper(); mapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);
//main
ObjectMapper mapper = new ObjectMapper();
//第二种方法
mapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);
JmxObjectItem jmxObjectItem = mapper.readValue(document.body().text(),JmxObjectItem.class);
//-----------------映射 类--------------------
import java.util.List;
public class JmxObjectItem {
private List<HbaseMasterAssignmentManger> beans;
//getter setter
}
import com.fasterxml.jackson.annotation.JsonProperty;
@JsonIgnoreProperties(ignoreUnknown = true) //第一种方法
public class HbaseMasterAssignmentManger {
private String name;
//@JsonAlias({"name","user"})
@JsonProperty("tag.Hostname")
private String tagHostname;
private int ritOldestAge;
private int ritCount;
//getter setter
}
2.类属性的别名
从上面json字符串可以看到有 字段名称含有点(.) 符号【"tag.Hostname"】,而java属性名称不可以有点。这就需要属性别名来解决了。
在相应的属性上增加注解:@JsonProperty("tag.Hostname")
有两种注解可以达到效果
@JsonProperty
这个注解提供了序列化和反序列化过程中该java属性所对应的名称
@JsonAlias
这个注解只在反序列化时起作用,指定该java属性可以接受的更多名称
3.直接获取某个字段值,不需要映射类
在解析一些json串时,只需要某些字段值,不值当的写一个映射类,可以根据字段名称来直接获取。使用 mapper.readTree("json");
ObjectMapper mapper = new ObjectMapper();
JsonNode jsonNode = mapper.readTree(document.body().text());
System.out.println(jsonNode.get("beans").get(0));
System.out.println(jsonNode.get("beans").get(0).get("tag.Hostname"));//结果含有双引号(类型为JsonNode) "hadoop-warehouse-master-02"
System.out.println(jsonNode.get("beans").get(0).get("tag.Hostname").asText()); //没有引号 hadoop-warehouse-master-02
System.out.println(jsonNode.get("beans").isArray()); //判断是否为数组
// -----------------------结果------------------------
{ "beans" : [ { "name" : "Hadoop:service=HBase,name=Master,sub=AssignmentManger", "modelerType" : "Master,sub=AssignmentManger", "tag.Context" : "master", "tag.Hostname" : "hadoop-warehouse-master-02", ... } ] }
{"name":"Hadoop:service=HBase,name=Master,sub=AssignmentManger","modelerType":"Master,sub=AssignmentManger","tag.Context":"master","tag.Hostname":"hadoop-warehouse-master-02"...}
"hadoop-warehouse-master-02"
hadoop-warehouse-master-02
true
4.简单构建 JSON 字符串
String strJSON="{\"fuid\":57859184,\"dt\":\"2021-12-29 15:16:30\",\"key\":\"txyX\",\"val\":\"&Tnrf\",\"num\":572.2190381530534,\"info\":\"a7fc6b18-881a-4a27-9790-82a023d8c809\"}";
ObjectMapper mapper = new ObjectMapper();
JsonNode res = mapper.readTree(strJSON); // 解析 JSON 字符串
System.out.println(res.get("fuid"));
ObjectNode objectNode = mapper.createObjectNode(); //简单 构建 JSON 字符串
objectNode.put("a",1);
objectNode.put("b",10.9999);
objectNode.put("c","xxxx");
System.out.println(objectNode.toString());