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