• 【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

    持续更新!!!

  • 相关阅读:
    错误处理和调试 C++快速入门30
    错误处理和调试 C++快速入门30
    虚继承 C++快速入门29
    多继承 C++快速入门28
    界面设计01 零基础入门学习Delphi42
    鱼C记事本 Delphi经典案例讲解
    界面设计01 零基础入门学习Delphi42
    虚继承 C++快速入门29
    linux系统中iptables防火墙管理工具
    linux系统中逻辑卷快照
  • 原文地址:https://www.cnblogs.com/flyinghome/p/14636993.html
Copyright © 2020-2023  润新知