zoukankan      html  css  js  c++  java
  • JSON 解析 (二)—— Jackson的使用

    Jackson是基于Java语言的一种JSON和Java对象的数据处理工具。功能上简单易用,性能上根据目前主流转换工具比较,Jackson相对比较高效。

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

    Jackson包含三个jar:

           1、jackson-core

      2、jackson-annotations

      3、jackson-databind

    从Maven仓库中可知三者的依赖关系:1和2相互独立,3依赖1和2

    Jackson的JSON库提供了3种API:

    • Data Binding:最方便,也是最常用方式                    依赖jackson-databind
    • Tree Model:最灵活                                                   依赖jackson-databind
    • Streaming API:性能最好                                          只依赖jackson-core

    一、Data Binding

    1、序列化

     可使用ObjectMapper.writeValueAsString(Object obj)方法

    UserInfo userInfo1 = new UserInfo();
    userInfo1.setName("matt");
    userInfo1.setAge(21);
    
    UserInfo userInfo2 = new UserInfo();
    userInfo2.setName("kevin");
    userInfo2.setAge(15);
    
    List<UserInfo> list = new ArrayList<UserInfo>();
    list.add(userInfo1);
    list.add(userInfo2);
    
    Staff staff = new Staff();
    staff.setUsers(list);
    staff.setCount(list.size());
    
    ObjectMapper objectMapper = new ObjectMapper();
    String json = objectMapper.writeValueAsString(staff);
    System.out.println(json);
    // 输出:{"count":2,"users":[{"name":"matt","age":21},{"name":"kevin","age":15}]}

     可使用注解,实现序列化的细节控制,如  
        @JsonIgnore  忽略属性
     @JsonFormat  日期格式化
     @JsonProperty  属性重命名

    2、反序列化

     实体的反序列化

    Staff tmpStaff =  new ObjectMapper().readValue(json, Staff.class);  // 实体可包含泛型字段

     泛型的反序列化

    List<UserInfo> tmpList = new ObjectMapper().readValue(json, new TypeReference<List<UserInfo>>() {});

     方法参数的反序列化

    public class Company {
        public void printUsers(List<UserInfo> users) {
            for (UserInfo userInfo : users) {
                System.out.println(String.format("name:%s, age:%d", userInfo.getName(), userInfo.getAge()));
            }
        } 
    }
    String json = "[{"name":"matt","age":21},{"name":"kevin","age":15}]";
    Method method = Company.class.getDeclaredMethods()[0];
    Type type = method.getGenericParameterTypes()[0];
    method.invoke(new Company(), objectMapper.readValue(json, TypeFactory.defaultInstance().constructType(type)));
    // 输出:
    // name:matt, age:21
    // name:kevin, age:15

     注:使用Method.getGenericParameterTypes()返回Type,其中包含方法定义时参数的泛型信息,因而可正常反序列化

    二、Tree Model

    1、序列化

     JsonNodeFactory生成树节点,ObjectMapper.writeTree()和JsonGenerator负责输出json字符串

    StringWriter sw = new StringWriter();
    JsonFactory jsonFactory = new JsonFactory();
    JsonGenerator jsonGenerator = jsonFactory.createGenerator(sw);
    
    JsonNodeFactory jsonNodeFactory = new JsonNodeFactory(false);
    ObjectNode node1 = jsonNodeFactory.objectNode();
    node1.put("aa", 89);
    node1.put("bb", "abd");
    ObjectNode node2 = jsonNodeFactory.objectNode();
    node2.put("gr", 9);
    node2.set("subnode", node1);
    new ObjectMapper().writeTree(jsonGenerator, node2);
    System.out.println(sw.toString());
    // 输出:{"gr":9,"subnode":{"aa":89,"bb":"abd"}}

    2、反序列化

     ObjectMapper.readValue() 可把json字符串解析成JsonNode

    String json = "[{"name":"matt","age":21},{"name":"kevin","age":15}]";
    JsonNode node = new ObjectMapper().readValue(json, JsonNode.class);
    JsonNode subNode = node.get(0);
    System.out.println(subNode.get("name").asText());

    三、Streaming API

    1、序列化

     JsonGenerator提供序列化接口

    JsonFactory jsonFactory = new JsonFactory();
    // JsonFactory jsonFactory = new ObjectMapper().getFactory();
    JsonGenerator jsonGenerator = jsonFactory.createGenerator(System.out);
    
    jsonGenerator.writeStartObject();
    jsonGenerator.writeStringField("name", "matt");
    jsonGenerator.writeNumberField("age", 10);
    // jsonGenerator.writeObjectField("user", new UserInfo());    // 会抛异常
    jsonGenerator.writeEndObject();
    
    jsonGenerator.flush();
    jsonGenerator.close();
    // 输出: {"name":"matt","age":10}

      序列化实体对象时,会抛异常: java.lang.IllegalStateException: No ObjectCodec defined for the generator, can only serialize simple wrapper types

      解决该问题的方法:使用ObjectMapper.getFactory() 创建JsonFactory 对象

     2、反序列化

     JsonParser提供反序列化功能,其工作方式是:将JSON分成一个Token序列(如START_OBJECT、END_OBJECT、FIELD_NAME等),迭代Token序列进行解析

     JsonParser通过nextToken()获取Token,getCurrentName()获取当前Field Name,getText()或getValueAsString()等获取Value

    String json = "{ "brand" : "Mercedes", "doors" : 5 }";
    JsonFactory jsonFactory = new JsonFactory();
    JsonParser jsonParser = jsonFactory.createParser(json);
    jsonParser.nextToken();
    while (jsonParser.nextToken() != JsonToken.END_OBJECT) {
        String name = jsonParser.getCurrentName();
        jsonParser.nextToken();
        String value = jsonParser.getText();
        System.out.println(String.format("%s: %s", name, value));
    }
    // 输出:
    // brand: Mercedes
    // doors: 5

    参考:

    JSON之Jackson(一)

    JSON之Jackson(二)

    Jackson基础教程

  • 相关阅读:
    如何配置寄存器
    逻辑分析仪的使用
    CAN中如何计算波特率并配置波特率
    led不同颜色的驱动电压和驱动电流
    ULINK2配置
    电机加减速转动
    2N7002
    未添加时钟文件产生报错
    烟雾传感器
    Strategy 设计模式 策略模式 超靠谱原代码讲解
  • 原文地址:https://www.cnblogs.com/MattCheng/p/8629448.html
Copyright © 2011-2022 走看看