【json的处理】二、Jackson的处理

目前处理json的方法有很多,这里主要总结四种方法

1. Gson方式处理json 【json的处理】一、Gson处理

2. FastJson方式处理json 【json的处理】三、FastJson的处理

3. Jackson方式处理json 【json的处理】二、Jackson的处理

4. json-flattener方式处理json 【json的处理】四、json-flattener的处理

 

本文主要介绍Jackson的方式

前言

下面主要通过几个方面来介绍jackson:

1. jackson的一些常用方法

2. jackson的一些常用注解

3. JsonNode && ArrayNode && ObjectNode

4. jackson处理文件的导入导出

 

首先需要引入依赖

jackson-databind 依赖 jackson-core 和 jackson-annotations,当添加 jackson-databind 之后, jackson-core 和 jackson-annotations 也随之添加到 Java 项目工程中。在添加相关依赖包之后,就可以使用 Jackson。

<dependency>
    <groupId>com.fasterxml.jackson.core</groupId>
    <artifactId>jackson-databind</artifactId>
    <version>2.11.0</version>
</dependency>

 

一、jackson的一些常用方法

一些概念和方法的介绍:

ObjectMapper是JSON操作的核心,Jackson的所有JSON操作都是在ObjectMapper中实现。

ObjectMapper有多个JSON序列化的方法,可以把JSON字符串保存File、OutputStream等不同的介质中。

writeValue(File arg0, Object arg1)把arg1转成json序列,并保存到arg0文件中。

writeValue(OutputStream arg0, Object arg1)把arg1转成json序列,并保存到arg0输出流中。

writeValueAsBytes(Object arg0)把arg0转成json序列,并把结果输出成字节数组。

writeValueAsString(Object arg0)把arg0转成json序列,并把结果输出成字符串。

//实体类
@Data
@AllArgsConstructor
public class TestUser {
    private String name;
    private Integer age;
    private Integer sex;
    private Date date;
}

//测试类

//定义一个对象用于测试
TestUser testUser = new TestUser("1",11,1,new Date());
TestUser testUser2 = new TestUser("2",22,2,new Date());
ObjectMapper mapper = new ObjectMapper();
//【对象转String】
String str = mapper.writeValueAsString(testUser);
//结果:{"name":"1","age":11,"sex":1,"date":1600595735478}
System.out.println(str);
//【String转对象】这里要注意,版本号2.10.1以上readValue方法就会报错,2.9.5就可以
//报错信息:java.lang.ClassNotFoundException: com.fasterxml.jackson.core.exc.InputCoercionException
TestUser testUserTemp = mapper.readValue(str, TestUser.class);
//结果:TestUser(name=1, age=11, sex=1, date=Sun Sep 20 18:07:43 CST 2020)
System.out.println(testUserTemp);
//list转json-string
List<TestUser> testUserList = new ArrayList<>();
testUserList.add(testUser);
testUserList.add(testUser2);
String json = mapper.writeValueAsString(testUserList);
//结果:[{"name":"1","age":11,"sex":1,"date":1600910383747},{"name":"2","age":22,"sex":2,"date":1600910383747}]
System.out.println(json);

 

二、jackson的一些常用注解

@JsonIgnore

此注解用于属性上,作用是进行JSON操作时忽略该属性。

@JsonIgnoreProperties

此注解用于类上,作用是忽略多个属性,如:@JsonIgnoreProperties({"userName", "userAge"})

@JsonFormat

此注解用于属性上,作用是把Date类型直接转化为想要的格式,如@JsonFormat(pattern = "yyyy-MM-dd HH-mm-ss")。

@JsonProperty

此注解用于属性上,作用是把该属性的名称序列化为另外一个名称,如把trueName属性序列化为name, @JsonProperty("name")。

@JsonInclude

此注解可用于属性和类上,作用是排除值为null的属性,如:

@JsonInclude(JsonInclude.Include.NON_NULL)-->属性为null不参与序列化。

@JsonInclude(JsonInclude.Include.NON_EMPTY)-->属性为空或者null都不参与序列化。

@JsonUnwrapped

此注解用于属性上,作用:

1. 是去掉外包装
2. 把成员对象中的属性提升到其容器类,并添加给定的前缀,如:@JsonUnwrapped(prefix = "user_")

@JsonAppend

此注解用于类上,为json添加虚拟属性,如:@JsonAppend(attrs = {@JsonAppend.Attr(value = "version")})

@JsonNaming

此注解用于类上,作用是将驼峰式改成下划线,如:

@JsonNaming(PropertyNamingStrategy.SnakeCaseStrategy.class)

此外还有:

  • KEBAB_CASE: 属性名单词用短线分隔连接, 比如hello-world

  • LOWER_CASE: 属性名用小写字母而且没有分隔符, 比如helloworld

  • SNAKE_CASE: 属性名用小写字母而且用下划线做分隔符, 比如hello_world

  • UPPER_CAMEL_CASE: 属性名所有单词用大写开头而且没有分隔符, 比如HelloWorld

MapperFeature.USE_ANNOTATIONS

禁用所有jackson注解的功能

@JsonPropertyOrder

此注解用于类上,作用是给序列化之后的json排序,如:

@JsonPropertyOrder(value = {"userSex","userAge","userName"})

 

1. JsonIgnore && JsonIgnoreProperties

@Data
@AllArgsConstructor
public class TestUser {
    @JsonIgnore
    private String name;
    private Integer age;
    private Integer sex;
    private Date date;
}

//定义一个对象用于测试
TestUser testUser = new TestUser("1",11,1,new Date());
ObjectMapper mapper = new ObjectMapper();
//【对象转String】
String str = mapper.writeValueAsString(testUser);
//加上注解前:{"name":"1","age":11,"sex":1,"date":1600913752059}
//加上注解后:{"age":11,"sex":1,"date":1600913711465}
System.out.println(str);

--------------------------------------------------------------------------------------------

@Data
@AllArgsConstructor
@JsonIgnoreProperties({"userName", "userAge"})
public class TestUser {
    private String userName;
    private Integer userAge;
    private Integer userSex;
}

//定义一个对象用于测试
TestUser testUser = new TestUser("111",11,1);
ObjectMapper mapper = new ObjectMapper();
//【对象转String】
String str = mapper.writeValueAsString(testUser);
//加上注解前:{"userName":"111","userAge":11,"userSex":1}
//加上注解后:{"userSex":1}
System.out.println(str);

2. JsonFormat

@Data
@AllArgsConstructor
public class TestUser {
    private String name;
    private Integer age;
    private Integer sex;
    @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
    private Date date;
}

//定义一个对象用于测试
TestUser testUser = new TestUser("1",11,1,new Date());
ObjectMapper mapper = new ObjectMapper();
//【对象转String】
String str = mapper.writeValueAsString(testUser);
//加上注解前:{"name":"1","age":11,"sex":1,"date":1600913893613}
//加上注解后:{"name":"1","age":11,"sex":1,"date":"2020-09-24 02:17:56"}
System.out.println(str);

3. JsonProperty

@Data
@AllArgsConstructor
public class TestUser {
    @JsonProperty("t_name")
    private String name;
    private Integer age;
    private Integer sex;
    private Date date;
}

//定义一个对象用于测试
TestUser testUser = new TestUser("1",11,1,new Date());
ObjectMapper mapper = new ObjectMapper();
//【对象转String】
String str = mapper.writeValueAsString(testUser);
//加上注解前:{"name":"1","age":11,"sex":1,"date":1600913893613}
//加上注解后:{"t_name":"1","age":11,"sex":1,"date":1600913990057}
System.out.println(str);

4. JsonInclued

@Data
@AllArgsConstructor
public class TestUser {
    @JsonInclude(JsonInclude.Include.NON_NULL)
    private String name;
    private Integer age;
    private Integer sex;
    private Date date;
}

@Data
@AllArgsConstructor
@JsonInclude(JsonInclude.Include.NON_NULL)
public class TestUser {
    private String name;
    private Integer age;
    private Integer sex;
    private Date date;
}

//定义一个对象用于测试
TestUser testUser = new TestUser(null,11,1,new Date());
ObjectMapper mapper = new ObjectMapper();
//【对象转String】
String str = mapper.writeValueAsString(testUser);
//加上注解前:{"name":null,"age":11,"sex":1,"date":1600914468252}
//加上注解后:{"age":11,"sex":1,"date":1600914452682}
System.out.println(str);

5. JsonUnwrapped

@Data
@AllArgsConstructor
public class TestUser {
    private String name;
    private Integer age;
    private Integer sex;
    @JsonUnwrapped
    private Teacher teacher;
}

@Data
@AllArgsConstructor
public class Teacher {
    private String tel;
    private String email;
}

//定义一个对象用于测试
TestUser testUser = new TestUser("111",11,1,new Teacher("13718999090","12345@qq.com"));
ObjectMapper mapper = new ObjectMapper();
//【对象转String】
String str = mapper.writeValueAsString(testUser);
//加上注解前:{"name":"111","age":11,"sex":1,"teacher":{"tel":"13718999090","email":"12345@qq.com"}}
//加上注解后:{"name":"111","age":11,"sex":1,"tel":"13718999090","email":"12345@qq.com"}
System.out.println(str);

----------------------------------------------------------------------------------------------
    
@Data
@AllArgsConstructor
public class TestUser {
    private String userName;
    private Integer userAge;
    private Integer userSex;
    @JsonUnwrapped(prefix = "user_")
    private Teacher teacher;
}

//定义一个对象用于测试
TestUser testUser = new TestUser("111",11,1,new Teacher("11111","11111@qq.com"));
ObjectMapper mapper = new ObjectMapper();
//【对象转String】
String str = mapper.writeValueAsString(testUser);
//加上注解前:{"userName":"111","userAge":11,"userSex":1,"teacher":{"tel":"11111","email":"11111@qq.com"}}
//加上注解后:{"userName":"111","userAge":11,"userSex":1,"user_tel":"11111","user_email":"11111@qq.com"}
System.out.println(str);

6. JsonAppend

@Data
@AllArgsConstructor
@JsonAppend(attrs = {@JsonAppend.Attr(value = "version")})
public class TestUser {
    private String name;
    private Integer age;
    private Integer sex;
}

//定义一个对象用于测试
TestUser testUser = new TestUser("111",11,1);
ObjectMapper mapper = new ObjectMapper();
//为虚拟属性添加值
ObjectWriter writer = mapper.writerFor(TestUser.class).withAttribute("version", "1.0");
//【对象转String】
String str = writer.writeValueAsString(testUser);
//加上注解前:{"name":"111","age":11,"sex":1}
//加上注解后:{"name":"111","age":11,"sex":1,"version":"1.0"}
System.out.println(str);

7. JsonNaming

@Data
@AllArgsConstructor
@JsonNaming(PropertyNamingStrategy.SnakeCaseStrategy.class)
public class TestUser {
    private String userName;
    private Integer userAge;
    private Integer userSex;
}

//定义一个对象用于测试
TestUser testUser = new TestUser("111",11,1);
ObjectMapper mapper = new ObjectMapper();
//【对象转String】
String str = mapper.writeValueAsString(testUser);
//加上注解前:{"userName":"111","userAge":11,"userSex":1}
//加上注解后:{"user_name":"111","user_age":11,"user_sex":1}
System.out.println(str);

8. MapperFeature.USE_ANNOTATIONS

@Data
@AllArgsConstructor
@JsonNaming(PropertyNamingStrategy.SnakeCaseStrategy.class)
public class TestUser {
    private String userName;
    private Integer userAge;
    private Integer userSex;
}

//定义一个对象用于测试
TestUser testUser = new TestUser("111",11,1);
ObjectMapper mapper = new ObjectMapper();
//禁用jackson注解
mapper.disable(MapperFeature.USE_ANNOTATIONS);
//【对象转String】
String str = mapper.writeValueAsString(testUser);
//加上注解前:{"userName":"111","userAge":11,"userSex":1}
//加上注解后:{"userName":"111","userAge":11,"userSex":1}
System.out.println(str);

9. JsonPropertyOrder

@Data
@AllArgsConstructor
@JsonPropertyOrder(value = {"userSex","userAge","userName"})
public class TestUser {
    private String userName;
    private Integer userAge;
    private Integer userSex;
}

//定义一个对象用于测试
TestUser testUser = new TestUser("111",11,1);
ObjectMapper mapper = new ObjectMapper();
//【对象转String】
String str = mapper.writeValueAsString(testUser);
//加上注解前:{"userName":"111","userAge":11,"userSex":1}
//加上注解后:{"userSex":1,"userAge":11,"userName":"111"}
System.out.println(str);

 

 

三、JsonNode && ArrayNode && ObjectNode

ObjectNode

是对象结点,可以存入对象属性。如 { "name":"Lilei", "age":"18", "school":"HNU" }

ArrayNode

是数组结点,用于存放JsonNode数据。如[ "Lilei", "XiaoHong", {"nm1": "Jay", "nm2": "Kong"} ]

JsonNode

是ObjectNode和ArrayNode的父接口。想要生成JsonNode对象都要先生成ObjectMapper类对象,它是产生Json结点的工厂。

 

1. JsonNode

String jsonStr = "{\"userName\":\"111\",\"userAge\":11,\"userSex\":1}";
ObjectMapper mapper = new ObjectMapper();
//【JsonNode】
JsonNode jsonNode = mapper.readTree(jsonStr);
//结果:{"userName":"111","userAge":11,"userSex":1}
System.out.println(jsonNode);
//【判断值类型】
String nodeType = jsonNode.get("userName").getNodeType().toString()+"***"+jsonNode.get("userAge").getNodeType().toString();
//结果:STRING***NUMBER
System.out.println(nodeType);
//【遍历key】
Iterator<String> fieldNames = jsonNode.fieldNames();
while (fieldNames.hasNext()) {
    //结果:userName  userAge  userSex
    System.out.println(fieldNames.next());
}
//【遍历value】
Iterator<JsonNode> elements = jsonNode.elements();
while (elements.hasNext()) {
    //结果:"111"  11  1
    System.out.println(elements.next());
}
//【单独获取某个key的值】
JsonNode path = jsonNode.get("userName");
//结果:"111"
System.out.println(path);
//结果:true
System.out.println(jsonNode instanceof ObjectNode);

获取属性、子节点有以下两个方法:

  1. path:

    路径访问安全,当访问的结点不存在时返回“MissingNode”,我将其理解为没有任何属性值的结点,也可以通过asText()转换为String类型,值为空字串;当访问的属性无效时同样返回空字串""。

    优势是不知道多层子节点的值是否一定存在时可以连续使用path,若不存在一律返回"";但不能判断结点是否存在。

  2. get:

    路径访问不安全,其访问结点路径或属性无效时返回null,故使用连续使用get访问时,若路径不存在会出现空指针异常

    优势是可以用是否为null判断结点是否存在。

  3. 访问技巧:

    不知道节点路径上是否所有节点都存在,可以使用

    JsonNode temp = xxxNode.path("prop1").path("prop2").....get("propN");

    if (null != temp) { do something... } 这样的方式安全得到不一定存在的节点

String jsonStr = "{\"userName\":\"111\",\"userAge\":11,\"userSex\":1}";
ObjectMapper mapper = new ObjectMapper();
//【JsonNode】
JsonNode jsonNode = mapper.readTree(jsonStr);
//【path】
JsonNode path = jsonNode.path("userName");
//结果:"111"
System.out.println(path);
JsonNode kkk = jsonNode.path("kkk");
//结果:空
System.out.println(kkk);
//【连续path】
JsonNode paths = jsonNode.path("a").path("b").path("c");
//结果:空
System.out.println(paths);
//【get】
JsonNode get1 = jsonNode.get("userName");
//结果:"111"
System.out.println(get1);
//结果:null
JsonNode get2 = jsonNode.get("kkk");
System.out.println(get2);
//【连续get】
JsonNode get3 = jsonNode.get("userName").get("kkk");
//结果:null
System.out.println(get3);
//【连续get-->如果get的结果为null之后继续get就会报错】
JsonNode get4 = jsonNode.get("userName").get("kkk").get("kkk");
//结果:java.lang.NullPointerException
System.out.println(get4);
//【asText && asInt】
String userName_userAgeText_userAgeInt = jsonNode.path("userName").asText()+"_"+jsonNode.path("userAge").asText()+"_"+jsonNode.path("userSex").asInt();
//结果:111_11_1
System.out.println(userName_userAgeText_userAgeInt);

2. ObjectNode

ObjectMapper mapper = new ObjectMapper();
//生成对象结点
ObjectNode objNode = mapper.createObjectNode();
//【put方法--在jdk1.8中,简单值用put设置】
objNode.put("name","111");
objNode.put("age",11);
//结果:{"name":"111","age":11}
System.out.println(objNode);
//【set方法--在jdk1.8中,子节点用set设置】
ObjectNode objectNode = mapper.createObjectNode();
objectNode.put("innername", "222");
objectNode.put("innerage", 22);
objNode.set("inner", objectNode);
//结果:{"name":"111","age":11,"inner":{"innername":"222","innerage":22}}
System.out.println(objNode);

3. ArrayNode

ObjectMapper mapper = new ObjectMapper();
//【生成数组结点】-->注意:数组结点添加元素不做简单值和结点类的区分
ArrayNode arrNode = mapper.createArrayNode();
arrNode.add("111");
//结果:["111"]
System.out.println(arrNode);
//生成对象结点
ObjectNode objNode = mapper.createObjectNode();
objNode.put("name","111");
objNode.put("age",11);
ArrayNode addObj = arrNode.add(objNode);
//结果:["111",{"name":"111","age":11}]
System.out.println(addObj);

 

四、Jackson处理文件的导入导出

1. txt文件的导出

ObjectMapper mapper = new ObjectMapper();
//生成对象结点
ObjectNode objNode = mapper.createObjectNode();
objNode.put("name","111");
objNode.put("age",11);
//【写入txt文件】
OutputStream outputStream= new FileOutputStream(new File("d:/11.txt"));
mapper.writeValue(outputStream, objNode);

效果:

2. txt文件的导入

ObjectMapper mapper = new ObjectMapper();
//【导入txt文件数据】
JsonNode jsonNode = mapper.readTree(new File("d:/11.txt"));
//结果:{"name":"111","age":11}
System.out.println(jsonNode);

3. 导入导出案例

要求:

根据实体类对象的类型生成相应的json并导出

导入json数据

映射到对象

@Data
@AllArgsConstructor
public class TestUser {
    private String userName;
    private Integer userAge;
    private Integer userSex;
    private Integer[] test;
}

ObjectMapper mapper = new ObjectMapper();
//生成数组节点
ArrayNode arrayNode = mapper.createArrayNode();
arrayNode.add(1);
arrayNode.add(2);
arrayNode.add(3);
//生成对象结点
ObjectNode objNode = mapper.createObjectNode();
objNode.put("userName","111");
objNode.put("userAge",11);
objNode.put("userSex",1);
objNode.put("test",arrayNode);
//【导出】
OutputStream outputStream= new FileOutputStream(new File("d:/test.txt"));
mapper.writeValue(outputStream, objNode);
//【导入】
JsonNode jsonNode = mapper.readTree(new File("d:/test.txt"));
TestUser testUser = mapper.treeToValue(jsonNode, TestUser.class);
//结果:TestUser(userName=111, userAge=11, userSex=1, test=[1, 2, 3])
System.out.println(testUser);

效果:

 

 

 

参考:

1. https://www.cnblogs.com/jpfss/p/9055747.html

2. https://blog.csdn.net/wang_snake/article/details/93719178

3. https://blog.csdn.net/blwinner/article/details/98532847?depth_1-utm_source=distribute.pc_relevant.none-task&utm_source=distribute.pc_relevant.none-task

 

持续更新!!!

posted @ 2021-04-09 14:29  夏夜凉凉  阅读(1763)  评论(0编辑  收藏  举报