使用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
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章