強大的ognl

AidenTer發表於2024-06-26

OGNL

OGNL (Object-Graph Navigation Language),是一種功能強大的表示式語言,透過它簡單一致的表示式語法,可以存取物件的任意屬性,呼叫物件的方法,遍歷整個物件的結構圖,實現欄位型別轉化等功能。它使用相同的表示式去存取物件的屬性。這樣可以更好的取得資料。

背景

隨著各個系統互動的增加,各式各樣複雜層次結構較深的JSON處理逐漸頻繁,對JSON解析也變得越來越棘手;在此基礎上希望有更好用的JSON解析工具,本次介紹OGNL希望對大家有所幫助。下面透過研究OGNL的原生API來看看如何使用OGNL來進行物件的存取操作。

說明

ONGL使用起來非常簡單,且支援很多複雜操作(lambda表示式,map等操作),但通常我們不用擔心那些複雜操作,在原始碼中,我們主要關注如下三個引數

引數名稱

說明

tree(Expression)

表示式是整個 OGNL 的核心內容,所有的 OGNL 操作都是針對表示式解析後進行的。透過表示式來告訴 OGNL 操作到底要幹些什麼。OGNL支援大量的表示式,如 “鏈式訪問物件”、表示式計算、甚至還支援 Lambda 表示式。

context

上下文物件,所有OGNL表示式都在當前物件的上下文中進行計算

root

需要操作的物件

/**
 * Evaluates the given OGNL expression tree to extract a value from the given root object. The
 * default context is set for the given context and root via <CODE>addDefaultContext()</CODE>.
 *
 * @param tree       the OGNL expression tree to evaluate, as returned by parseExpression()
 * @param context    the naming context for the evaluation
 * @param root       the root object for the OGNL expression
 * @param resultType the converted type of the resultant object, using the context's type converter
 * @return the result of evaluating the expression
 * @throws MethodFailedException            if the expression called a method which failed
 * @throws NoSuchPropertyException          if the expression referred to a nonexistent property
 * @throws InappropriateExpressionException if the expression can't be used in this context
 * @throws OgnlException                    if there is a pathological environmental problem
 */
public static Object getValue(Object tree, OgnlContext context, Object root, Class<?> resultType) throws OgnlException {
   ...
}

快速開始

本節僅說明讀取JSON欄位,讀取、注入、修改等操作仍希望使用JavaAPI操作

<dependency>
    <groupId>ognl</groupId>
    <artifactId>ognl</artifactId>
    <version>3.4.2</version>
</dependency>

我們以下面這個JSON為例

{
    "id": "2951asd12ca",
    "platformUid": "paidaxin",
    "nickName": "一隻派大星",
    "groupEntity": [
        {
            "id": "gid1",
            "name": "第一個群",
            "tagList": [
                {
                    "id": "tag1",
                    "tagName": "tagName1"
                },
                {
                    "id": "tag2",
                    "tagName": "tagName2"
                }
            ]
        },
        {
            "id": "gid2",
            "name": "第二個群",
            "tagList": [
                {
                    "id": "tag1",
                    "tagName": "tagName1"
                }
            ]
        }
    ]
}
//省略資料拼裝,JSON已被反序列化為ProfileEntity 
ProfileEntity profileEntity = initProfile();

//如果獲取本身屬性可以直接this.屬性,如果獲取的屬性為一個List則使用this.{屬性}
Ognl.getValue("#this.nickName", profileEntity);
Ognl.getValue("#this.{groupEntity}", profileEntity);
Ognl.getValue("#this.{groupEntity.{tagList}}", profileEntity);
//相比較於Stream.map().flatmap().map()...更為方便

除了獲取JSON中的欄位外還有什麼功能呢?

OGNL - Apache Commons OGNL - Language Guide

OGNL | Arthas


強大的ognl

相關文章