使用ObjectMapper转换JSON


ObjectMapper 是一个使用 Swift 编写的用于 model 对象(类和结构体)和 JSON 之间转换的框架。它提供一些功能将转换成Java对象匹配JSON结构,反之亦然。它使用JsonParser和JsonGenerator的实例实现JSON实际的读/写。

记录一些在工作中经常使用的方法。

maven 依赖

需要添加以下依赖:

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

<!-- https://mvnrepository.com/artifact/com.fasterxml.jackson.core/jackson-core -->
<dependency>
    <groupId>com.fasterxml.jackson.core</groupId>
    <artifactId>jackson-core</artifactId>
    <version>2.9.5</version>
</dependency>

<!-- https://mvnrepository.com/artifact/com.fasterxml.jackson.core/jackson-annotations -->
<dependency>
    <groupId>com.fasterxml.jackson.core</groupId>
    <artifactId>jackson-annotations</artifactId>
    <version>2.9.5</version>
</dependency>

使用场景

  1. Java对象转换为JSON对象
  2. JSON对象转为Java对象
  3. Java数组对象和JSON数组对象转换
  4. 抽取json中的部分数据进行转换
    当我们请求别人的http接口时,有时候我们只需要返回的json的部分数据,可能嵌套的数据比较多,层级比较复杂,可以使用readTree(json);来获取你需要的数据。

测试model类

package com.qunar.pf.flink.server.model;

/** @Description: @Author: renxin.tang @Date: 2019/11/21 21:48 */
public class YarnAppModel {
  private String id;
  private String user;
  private String name;
  private String state;
  /* 
	getter and setter and toString
 	*/
}

使用场景实例

1、Java对象转换为JSON对象

代码:

 @Test
  public void javaObjectToJson() throws JsonProcessingException {
    YarnAppModel yarnAppModel = new YarnAppModel();
    yarnAppModel.setId("application_1574306678989_4374");
    yarnAppModel.setName("pf_flink_server");
    yarnAppModel.setUser("datadev");
    yarnAppModel.setState("RUNNING");
    ObjectMapper mapper = new ObjectMapper();
    String json = mapper.writeValueAsString(yarnAppModel);
    System.out.println(json);
  }

运行结果:


{"id":"application_1574306678989_4374","user":"datadev","name":"pf_flink_server","state":"RUNNING"}

2、JSON对象转换为Java对象

代码:

 @Test
  public void jsonToJavaObject() throws IOException {
    String json = "{\"id\":\"application_1574306678989_4374\",\"user\":\"datadev\",\"name\":\"pf_flink_server\",\"state\":\"RUNNING\"}";
    ObjectMapper mapper = new ObjectMapper();
    YarnAppModel yarnAppModel = mapper.readValue(json, YarnAppModel.class);
    System.out.println(yarnAppModel.toString());
  }

运行结果:


YarnAppModel{id='application_1574306678989_4374', user='datadev', name='pf_flink_server', state='RUNNING'}

3、Java数组对象和JSON数组对象转换

代码:

  @Test
  public void jsonCollectorAndJavaColletor() throws IOException {
    ObjectMapper mapper = new ObjectMapper();
    YarnAppModel yarnAppModel = new YarnAppModel("application_1574306678989_4374","datadev","pfflink","RUNNING");
    YarnAppModel yarnAppModel2 = new YarnAppModel("application_1574306678989_4374_2","datadev2","pfflink2","RUNNING");
    List<YarnAppModel> lists = new ArrayList<>();
    lists.add(yarnAppModel);
    lists.add(yarnAppModel2);
    // Java数组-->JSON数组
    String json1 = mapper.writeValueAsString(lists);
    System.out.println("数组转JSON:\n"+json1);
    System.out.println("-----------------------------------");
   //  JSON数组-->Java数组
    List<YarnAppModel> lists2 = mapper.readValue(json1, new TypeReference<List<YarnAppModel>>(){});
    System.out.println("JSON转数组:\n"+lists2.toString());
  }

运行结果:

数组转JSON:
[{"id":"application_1574306678989_4374","user":"datadev","name":"pfflink","state":"RUNNING"},{"id":"application_1574306678989_4374_2","user":"datadev2","name":"pfflink2","state":"RUNNING"}]
-----------------------------------
JSON转数组:
[YarnAppModel{id='application_1574306678989_4374', user='datadev', name='pfflink', state='RUNNING'}, YarnAppModel{id='application_1574306678989_4374_2', user='datadev2', name='pfflink2', state='RUNNING'}]

4、抽取json中的部分数据进行转换

当我们请求别人的http接口时,有时候我们只需要返回的json的部分数据,可能嵌套的数据比较多,层级比较复杂,可以使用readTree(json);来获取你需要的数据。
此时我们的model类里面的字段应该是少于请求到的json数据的,并且数据层级比较复杂需要进一步提取,
如请求http后得到的返回值:

{"apps":
    {"app":[
        {"id":"application_1574306678989_4623","user":"datadev","name":"wordcount","state":"RUN","time":15432523535255},
        {"id":"application_1574306678989_4543","user":"datadev2","name":"wordcount","state":"RUN","time":15432523535255}
        ]
    }
  }

我们需要的只是"app"下的数据并且不需要time字段的值,我们应该怎么提取呢?
在提取之前我们需要做一些配置,不然会报一些异常(这些配置也不是全要配,配置项也不仅仅是这些):

ObjectMapper objectMapper = new ObjectMapper();  
        //序列化的时候序列对象的所有属性  
        objectMapper.setSerializationInclusion(Include.ALWAYS);  

        //反序列化的时候如果多了其他属性,不抛出异常  
        objectMapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);  

        //如果是空对象的时候,不抛异常  
        objectMapper.configure(SerializationFeature.FAIL_ON_EMPTY_BEANS, false);  

        //取消时间的转化格式,默认是时间戳,可以取消,同时需要设置要表现的时间格式  
        objectMapper.configure(SerializationFeature.WRITE_DATES_AS_TIMESTAMPS, false);  
        objectMapper.setDateFormat(new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"))  

代码:

  @Test
  public void getYarnApps() throws IOException {
    String path ="http://xxxxxxx:8088/ws/v1/cluster/apps";
    String json = HttpUtil.doGet(path,null);
    System.out.println("HTTP返回json数据:\n"+json);
    ObjectMapper mapper = new ObjectMapper();
    // 转换为格式化的json
    mapper.enable(SerializationFeature.INDENT_OUTPUT);
    // 如果json中有新增的字段并且是实体类类中不存在的,不报错
    mapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);
    // ObjectMapper读取json文件
    JsonNode root = mapper.readTree(json);
    JsonNode apps = root.get("apps");
    JsonNode app = apps.get("app");
    List<YarnAppModel> resoult = mapper.readValue(app.toString(), new TypeReference<List<YarnAppModel>>(){});
    System.out.println("提取结果:");
    for (YarnAppModel yarnAppModel : resoult) {
      System.out.println(yarnAppModel.getId()+"\t"+yarnAppModel.getName()+"\t"+yarnAppModel.getState());
    }
  }

运行结果:

HTTP返回json数据:
{"apps":{"app":[{"id":"application_1574306678989_4623","user":"datadev","name":"wordcount","state":"RUNNING","time":15432523535255},{"id":"application_1574306678989_4543","user":"datadev2","name":"wordcount","state":"RUNNING","time":15432523535255}]}}
提取结果:
application_1574306678989_4623	wordcount	RUNNING
application_1574306678989_4543	wordcount	RUNNING
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章