1. 程式人生 > 其它 >如何優雅解析多層巢狀的複雜JSON資料

如何優雅解析多層巢狀的複雜JSON資料

我們在平時開發中經常會涉及呼叫某個REST介面從而獲取對應資料的情況,在這個過程中,返回的資料往往都是JSON資料,一般情況下,我們都會針對這些JSON資料定義對應實體類,從而獲取我們需要的資料。這種方式對於結構簡單的JSON資料是OK的,但是如果遇到下面這種多級巢狀的資料就比較蛋疼了:

{
  "a1":{
    "b1":{
      "c1":{
        "d1":"d1"
      }
    }
  },
  "a2":{
    "b2":{
      "c2":{
        "d2":["i1","i2","i3"]
      }
    }
  }
}

那麼對於這種情況,有沒有比較優雅的處理方式呢?

一、什麼是OGNL表示式

OGNL全稱 “物件圖導航語言”,我們可以使用其提供的表示式語言獲取JAVA物件樹中的任意屬性或呼叫其方法。不僅如此,它還能自動實現必要的型別轉換,廢話不多說,我們來看看如何使用吧。

二、如何使用

1、首先引入所需的maven依賴,主要包括jackson和ognl:

<dependency>
  <groupId>com.fasterxml.jackson.core</groupId>
  <artifactId>jackson-core</artifactId>
  <version>2.11.4</version>
</dependency>
<dependency>
  <groupId>com.fasterxml.jackson.core</groupId>
  <artifactId>jackson-databind</artifactId>
  <version>2.11.4</version>
</dependency>
<dependency>
  <groupId>com.fasterxml.jackson.core</groupId>
  <artifactId>jackson-annotations</artifactId>
  <version>2.11.4</version>
</dependency>
        
<dependency>
  <groupId>ognl</groupId>
  <artifactId>ognl</artifactId>
  <version>3.1.26</version>
</dependency>

2、封裝JSON反序列化與資料提取的方法

我們封裝兩個方法:

  • parse:將JSON資料反序列化為Map物件

  • getValue:使用OGNL表示式從Map中提取資料

public class JsonUtils {
    private static Logger logger = Logger.getLogger("JsonUtils");

    private final static ObjectMapper objectMapper = new ObjectMapper();
    public static ObjectMapper getInstance() {
        
return objectMapper; } public static <T> T parse(String jsonStr, Class<T> clazz) throws Exception { return getInstance().readValue(jsonStr, clazz); } public static <T> T getValue(Map map, String path, Class<T> klass) throws Exception { OgnlContext ctx = new OgnlContext(); ctx.setRoot(map); T value = (T) Ognl.getValue(path, ctx, ctx.getRoot()); return value; } }

3、測試

public class Demo {

    public static void main(String[] args) throws Exception{
        String jsonData = "{\"a1\":{\"b1\":{\"c1\":{\"d1\":\"d1\"}}},\"a2\":{\"b2\":{\"c2\":{\"d2\":[\"i1\",\"i2\",\"i3\"]}}}}";

        Map<String, Object> map = JsonUtils.parse(jsonData, Map.class);

        String s = JsonUtils.getValue(map, "a1.b1.c1.d1", String.class);
        System.out.println(s);

        List<String> list = JsonUtils.getValue(map, "a2.b2.c2.d2", List.class);
        System.out.println(list);
    }
}

我們就以開篇展示的多層JSON資料為例進行演示,其中"a1.b1.c1.d1"將取到值為“d1”的字串資料,“a2.b2.c2.d2”將取到一個列表,執行程式碼,我們可得到如下結果:

d1
[i1, i2, i3]

三、小結

我們通過Demo可以看到,使用Ognl表示式可以使我們程式碼變得更加精煉,避免構造各種複雜實體類的尷尬,關於OGNL的更多用法,小夥伴們可以自行學習。