在《 Jackson使用简介》中介绍了Jackson的基本用法:字符串与JsonNode间转换。
JsonNode
JsonNode为抽象类,这意味着不能直接构建JsonNode实例的对象图,但可以通过创建其子类ObjectNode的实例对象进行相关操作。
ObjectNode
ObjectNode是JsonNode的子类,用于修改:
- Iterator elements():accessing all value nodes of this Node, iff this node is a JSON Array or Object node;
- Iterator fieldNames()
- Iterator<Map.Entry<String,JsonNode>> fields(): accessing all fields (with both names and values) of this JSON Object;
- JsonNode findValue(String fieldName):finding a JSON Object field with specified name in this node or its child nodes, and returning value it has;
- get:根据节点名称获取当前节点下子节点,没有返回null;
- path:根据节点名称获取当前节点下子节点,没有返回MissingNode;
- remove:根据节点名移除节点;
- removeall:移除所有节点;
- put:设定可设定任意类型的值;
- set:只能设定JsonNode类型的值;
节点修改
JsonNode本身不能修改,但其子类ObjectNode可以修改。当JsonNode是非叶子节点时,通过OjectMapper获得的JsonNode本身就是ObjectNode。
String strJson = "{\"cap\":\"test\",\"count\":123,\"result\":true,\"names\":[\"first\",\"second\"],\"values\":[1,2]}";
JsonNode nodeRoot = objectMapper.readTree(strJson);
// nodeRoot为非叶子节点,本身即为ObjectNode类型
ObjectNode objRoot = (ObjectNode)nodeRoot;
// 增加新节点
objRoot.put("add", "new node");
// 修改节点
objRoot.put("count", 10);
String result = objectMapper.writeValueAsString(nodeRoot);
System.out.println(result);
at与path方法
通过get、path都可以获取node下当前子节点;但at方法可以访问任何级别子节点(参数为‘根到要访问节点的路径’,类似Linux下路径访问/first/second
):
- get:参数为节点名称;节点不存在时,返回null;
- path:参数为节点名称;节点不存在时,返回MissingNode;
- at:参数为节点路径;节点不存在(路径错误)时,返回MissingNode;
JsonNode atNone = nodeRoot.at("/root/none");
if(atNone.isMissingNode()){
System.out.println("Not found");
}
JsonNode rootNode = nodeRoot.path("root");
if(atNone.isMissingNode()){
System.out.println("Not found");
}
Json转类
通过objectMapper.readValue(Json, ClassT),把Json字符串可以方便地转换为对应的类。对于复杂的类型则需要使用TypeReference。
String strJson = "{\"birthday\":\"2010-03-05\",\"Name\":\"mike\",\"cur\":\"2020-09-12 22:31:04\"}";
// 生成类
Person p2 = objectMapper.readValue(strJson, Person.class);
// 生成字典
Map<String, Object> m1 = objectMapper.readValue(strJson, new com.fasterxml.jackson.core.type.TypeReference<Map<String, Object>>() {});
示例
在前一节基础上添加从文件中读、写Json以及格式化输出JSON;
public class JsonConvert {
private static final Logger _logger = LoggerFactory.getLogger(JasonConvert.class);
private final static ObjectMapper objectMapper = new ObjectMapper();
static {
// 设置序列化时忽略null值
// objectMapper.setSerializationInclusion(JsonInclude.Include.NON_NULL);
// 反序列化时忽略不存在的字段
// objectMapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES,false);
objectMapper.disable(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES);
// 强制JSON 空字符串("")转换为null
objectMapper.enable(DeserializationFeature.ACCEPT_EMPTY_STRING_AS_NULL_OBJECT);
objectMapper.setDateFormat(new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"));
objectMapper.registerModule(new JavaTimeModule())
// .registerModule(new ParameterNamesModule())
.registerModule(new Jdk8Module());
}
public static <T> T fromJson(String strJson, Class<T> clsT) {
try {
return objectMapper.readValue(strJson, clsT);
} catch (IOException e) {
_logger.error("Deserialize fail: {}", e);
}
return null;
}
public static String toJson(Object obj) {
try {
return objectMapper.writeValueAsString(obj);
} catch (JsonProcessingException e) {
_logger.error("Serialize fail: {}", e);
}
return null;
}
public static String toPrettyJson(Object obj) {
try {
return objectMapper.writerWithDefaultPrettyPrinter().writeValueAsString(obj);
} catch (JsonProcessingException e) {
_logger.error("Serialize fail: {}", e);
}
return null;
}
public static void toFile(String strFile, Object obj){
try {
objectMapper.writeValue(new File(strFile), obj);
} catch (IOException e) {
_logger.error("Serialize fail: {}", e);
}
}
public static <T> T fromFile(String strFile, Class<T> clsT) {
try {
return objectMapper.readValue(new File(strFile), clsT);
} catch (IOException e) {
_logger.error("Deserialize fail: {}", e);
}
return null;
}
public static JsonNode asTree(String strJson) {
try {
return objectMapper.readTree(strJson);
} catch (IOException e) {
_logger.error("Deserialize fail: {}", e);
}
return null;
}
}