Java中OGNL表達(dá)式語言的使用詳解
OGNL 介紹
OGNL(Object Graph Navigation Language)表達(dá)式語言是一種用于Java語言的表達(dá)式語言,專門用于在對象圖中進(jìn)行導(dǎo)航和操作。
在Java中,OGNL可以讓開發(fā)人員以簡潔的方式訪問和操作Java對象的屬性、調(diào)用對象的方法,執(zhí)行算術(shù)和邏輯運(yùn)算,以及處理集合和數(shù)組等操作。
OGNL的語法簡潔明了,可以方便地用于在Java開發(fā)中進(jìn)行動(dòng)態(tài)屬性存取、列表和Map操作、函數(shù)和方法調(diào)用等,為開發(fā)人員提供了便利的數(shù)據(jù)操作手段。
OGNL 使用場景
常見使用場景:
- ognl
- Fastjson
- ognl
使用ognl包需要引入依賴
maven依賴:
<dependency> <groupId>ognl</groupId> <artifactId>ognl</artifactId> <version>3.3.4</version> </dependency>
- 主要功能
訪問對象屬性:
使用點(diǎn)號(.)來訪問對象的屬性(也可設(shè)置對象的屬性)。例如:person.name 表示訪問 person 對象的 name 屬性。
調(diào)用對象方法
使用at符號(@)來調(diào)用對象的方法。例如:@java.lang.Math@random() 表示調(diào)用 Math 類的 random 方法。
訪問集合和數(shù)組:
使用方括號([])來訪問集合或數(shù)組中的元素。例如:myList[0] 表示訪問 myList 集合中的第一個(gè)元素。
賦值和表達(dá)式計(jì)算:
支持變量賦值和基本的算術(shù)、邏輯運(yùn)算符。例如:age > 18 && age < 60 表示對 age 變量進(jìn)行邏輯判斷。
條件表達(dá)式:
支持條件運(yùn)算符,如三元運(yùn)算符 condition ? true : false。
對象引用:
使用(#)符號來引用對象。例如:#person.name 表示引用 person 對象的 name 屬性。
內(nèi)置對象:
OGNL中有一些內(nèi)置對象,如 #context(上下文對象)、#root(根對象)、#this(當(dāng)前對象)等,可以方便地用于表達(dá)式中的引用和操作。
- 注意事項(xiàng)
- 當(dāng)表達(dá)式expression中的屬性不存在時(shí),獲取或設(shè)置值會(huì)報(bào)錯(cuò)
- Ognl類的主要方法
applyExpressionMaxLength
:設(shè)置Ognl 表達(dá)式的最大允許長度限制
void applyExpressionMaxLength(Integer expressionMaxLength)
- expressionMaxLength:表達(dá)式的最大允許長度
freezeExpressionMaxLength
:凍結(jié) Ognl 表達(dá)式的最大允許長度的限制
- void freezeExpressionMaxLength()
thawExpressionMaxLength
:解除 Ognl 表達(dá)式的最大允許長度的限制
- void thawExpressionMaxLength()
createDefaultContext
:創(chuàng)建一個(gè)默認(rèn)的 Ognl 上下文對象
Map createDefaultContext(Object root)
root
:根對象
Map createDefaultContext(Object root, ClassResolver classResolver)
root
:根對象classResolver
:類解析器
Map createDefaultContext(Object root, ClassResolver classResolver, TypeConverter converter)
root
:根對象classResolver
:類解析器converter
:類型轉(zhuǎn)換器
Map createDefaultContext(Object root, MemberAccess memberAccess)
root
:根對象memberAccess
:成員訪問對象
Map createDefaultContext(Object root, MemberAccess memberAccess, ClassResolver classResolver, TypeConverter converter)
root
:根對象memberAccess
:成員訪問對象classResolver
:類解析器converter
:類型轉(zhuǎn)換器
addDefaultContext
:向默認(rèn) Ognl 上下文中添加一個(gè)自定義的上下文對象
Map addDefaultContext(Object root, Map context)
root
:根對象context
:上下文對象
Map addDefaultContext(Object root, ClassResolver classResolver, Map context)
root
:根對象classResolver
:類解析器context
:上下文對象
Map addDefaultContext(Object root, ClassResolver classResolver, TypeConverter converter, Map context)
root
:根對象classResolver
:類解析器converter
:類型轉(zhuǎn)換器context
:上下文對象
Map addDefaultContext(Object root, MemberAccess memberAccess, ClassResolver classResolver, TypeConverter converter, Map context)
root
:根對象memberAccess
:成員訪問對象classResolver
:類解析器converter
:類型轉(zhuǎn)換器context
:上下文對象
compileExpression
:將字符串表達(dá)式編譯為 Ognl 表達(dá)式對象
Node compileExpression(OgnlContext context, Object root, String expression)
context
:上下文對象expression
:字符串表達(dá)式
parseExpression
:將字符串表達(dá)式解析為 Ognl 表達(dá)式對象
Object parseExpression(String expression)
expression:字符串表達(dá)式
getLastEvaluation
:從上下文中獲取最后一個(gè)評估(Evaluation)對象
Evaluation getLastEvaluation(Map context)
- context:上下文對象
setRoot
:設(shè)置 Ognl 表達(dá)式的根對象
void setRoot(Map context, Object root)
context
:上下文對象root
:根對象
getRoot
:獲取 Ognl 表達(dá)式的根對象
Object getRoot(Map context)
context
:上下文對象
isConstant
:判斷給定的表達(dá)式是否是常量
isConstant(Object tree)
tree
:Ognl 表達(dá)式對象
isConstant(Object tree, Map context)
tree
:Ognl 表達(dá)式對象context
:上下文對象
isConstant(String expression)
expression
:字符串表達(dá)式
isConstant(String expression, Map context)
expression
:字符串表達(dá)式context
:上下文對象
isSimpleProperty
:判斷給定的表達(dá)式是否是簡單的屬性
isSimpleProperty(String expression)
expression
:字符串表達(dá)式
isSimpleProperty(String expression, Map context)
expression
:字符串表達(dá)式context
:上下文對象
isSimpleProperty(Object tree)
tree
:Ognl 表達(dá)式對象
isSimpleProperty(Object tree, Map context)
tree
:Ognl 表達(dá)式對象context
:上下文對象
isSimpleNavigationChain
:判斷給定的表達(dá)式是否是簡單的導(dǎo)航鏈
isSimpleNavigationChain(String expression)
expression
:字符串表達(dá)式
isSimpleNavigationChain(String expression, Map context)
expression
:字符串表達(dá)式context
:上下文對象
isSimpleNavigationChain(Object tree)
tree
:Ognl 表達(dá)式對象
isSimpleNavigationChain(Object tree, Map context)
tree
:Ognl 表達(dá)式對象context
:上下文對象
setValue
:將給定的值設(shè)置到根對象的屬性中
void setValue(String expression, Object root, Object value)
根據(jù)表達(dá)式定位到根對象的屬性,并將給定的值設(shè)置為該屬性的值
expression
:字符串表達(dá)式root
:根對象value
:要設(shè)置的值
void setValue(String expression, Map context, Object root, Object value)
使用給定的上下文對象和根對象,根據(jù)表達(dá)式定位到根對象的屬性,并將給定的值設(shè)置為該屬性的值
expression
:字符串表達(dá)式context
:上下文對象root
:根對象value
:要設(shè)置的值
void setValue(Object tree, Object root, Object value)
使用表達(dá)式對象定位到根對象的屬性,并將給定的值設(shè)置為該屬性的值
tree
:Ognl 表達(dá)式對象root
:根對象value
:要設(shè)置的值
void setValue(Object tree, Map context, Object root, Object value)
使用給定的上下文對象和根對象,根據(jù)表達(dá)式對象定位到根對象的屬性,并將給定的值設(shè)置為該屬性的值
tree
:Ognl 表達(dá)式對象context
:上下文對象root
:根對象value
:要設(shè)置的值
void setValue(ExpressionAccessor expression, OgnlContext context, Object root, Object value)
使用給定的表達(dá)式訪問器、上下文對象和根對象,定位到根對象的屬性,并將給定的值設(shè)置為該屬性的值
expression
:Ognl 表達(dá)式訪問器context
:Ognl 表達(dá)式訪問器root
:根對象value
:要設(shè)置的值
getValue
:通過給定的表達(dá)式從根對象中獲取屬性值
Object getValue(String expression, Object root)
根據(jù)表達(dá)式定位到根對象的屬性,并返回該屬性的值
expression
:字符串表達(dá)式root
:根對象
Object getValue(String expression, Object root, Class resultType)
根據(jù)表達(dá)式定位到根對象的屬性,并將返回的值轉(zhuǎn)換為指定的結(jié)果類型
expression
:字符串表達(dá)式root
:根對象resultType
:結(jié)果類型
Object getValue(String expression, Map context, Object root)
使用給定的上下文對象和根對象,根據(jù)表達(dá)式定位到根對象的屬性,并返回該屬性的值
expression
:字符串表達(dá)式context
:上下文對象root
:根對象
Object getValue(String expression, Map context, Object root, Class resultType)
使用給定的上下文對象和根對象,根據(jù)表達(dá)式定位到根對象的屬性,并將返回的值轉(zhuǎn)換為指定的結(jié)果類型
expression
:字符串表達(dá)式context
:上下文對象root
:根對象resultType
:結(jié)果類型
Object getValue(Object tree, Object root)
使用表達(dá)式對象定位到根對象的屬性,并返回該屬性的值
tree
:Ognl 表達(dá)式對象root
:根對象
Object getValue(Object tree, Object root, Class resultType)
使用表達(dá)式對象定位到根對象的屬性,并將返回的值轉(zhuǎn)換為指定的結(jié)果類型
tree
:Ognl 表達(dá)式對象root
:根對象resultType
:結(jié)果類型
Object getValue(Object tree, Map context, Object root)
使用給定的上下文對象和根對象,根據(jù)表達(dá)式對象定位到根對象的屬性,并返回該屬性的值
tree
:Ognl 表達(dá)式對象context
:上下文對象root
:根對象
Object getValue(Object tree, Map context, Object root, Class resultType)
使用給定的上下文對象和根對象,根據(jù)表達(dá)式對象定位到根對象的屬性,并將返回的值轉(zhuǎn)換為指定的結(jié)果類型
tree
:Ognl 表達(dá)式對象context
:上下文對象root
:根對象resultType
:結(jié)果類型
Object getValue(ExpressionAccessor expression, OgnlContext context, Object root)
使用給定的表達(dá)式訪問器、上下文對象和根對象,定位到根對象的屬性,并返回該屬性的值
expression
:Ognl 表達(dá)式訪問器context
:Ognl 上下文對象root
:根對象
Object getValue(ExpressionAccessor expression, OgnlContext context, Object root, Class resultType)
使用給定的表達(dá)式訪問器、上下文對象和根對象,定位到根對象的屬性,并將返回的值轉(zhuǎn)換為指定的結(jié)果類型
expression
:Ognl 表達(dá)式訪問器context
:Ognl 上下文對象root
:根對象resultType
:結(jié)果類型
- 設(shè)置值
1.使用字符串表達(dá)式方式設(shè)置值
public static void main(String[] args) throws Exception { // 創(chuàng)建一個(gè)根對象 Person person = new Person("John", 25); // 創(chuàng)建一個(gè) Ognl 上下文 OgnlContext context = new OgnlContext(); context.setRoot(person); // 使用字符串表達(dá)式方式設(shè)置值 Ognl.setValue("name", context, person, "Alice"); Ognl.setValue("age", context, person, 30); // 輸出更新后的屬性值 System.out.println(person.getName()); // 輸出:Alice System.out.println(person.getAge()); // 輸出:30 }
2.使用 Ognl 表達(dá)式對象方式設(shè)置值
public static void main(String[] args) throws Exception { // 創(chuàng)建一個(gè)根對象 Person person = new Person("John", 25); // 創(chuàng)建一個(gè) Ognl 表達(dá)式對象 Object tree = Ognl.parseExpression("name"); // 使用表達(dá)式對象方式設(shè)置值 Ognl.setValue(tree, person, "Alice"); // 輸出更新后的屬性值 System.out.println(person.getName()); // 輸出:Alice }
3.使用 Ognl 表達(dá)式訪問器和 Ognl 上下文對象方式設(shè)置根值
public static void main(String[] args) throws OgnlException { // 創(chuàng)建一個(gè)根對象 Person person = new Person("John", 25); // 創(chuàng)建一個(gè) Ognl 上下文 OgnlContext context = new OgnlContext(); context.setRoot(person); // 創(chuàng)建一個(gè) Ognl 表達(dá)式訪問器 ExpressionAccessor expression = OgnlRuntime.getPropertyAccessor(Person.class); // 使用表達(dá)式訪問器和上下文對象設(shè)置值 Object tree = Ognl.parseExpression("age"); Ognl.setValue(expression, context, person, tree, 30); // 輸出更新后的屬性值 System.out.println(person.getAge()); // 輸出:30 }
- 獲取值
使用字符串表達(dá)式方式獲取值
public static void main(String[] args) throws OgnlException { // 創(chuàng)建一個(gè)根對象 Person person = new Person("Alice", 30); // 使用字符串表達(dá)式方式獲取值 Object nameValue = Ognl.getValue("name", person); System.out.println(nameValue); // 輸出:Alice // 使用字符串表達(dá)式方式獲取值 Object ageValue = Ognl.getValue("age", person); System.out.println(ageValue); // 輸出:30 }
使用字符串表達(dá)式及Ognl 上下文對象方式獲取值
public static void main(String[] args) throws OgnlException { // 創(chuàng)建一個(gè)根對象 Person person = new Person("Alice", 30); // 創(chuàng)建一個(gè) Ognl 上下文 OgnlContext context = new OgnlContext(); context.setRoot(person); // 使用帶上下文參數(shù)的字符串表達(dá)式方式獲取值 Object nameValue = Ognl.getValue("name", context, person); System.out.println(nameValue); // 輸出:Alice // 使用帶上下文參數(shù)的字符串表達(dá)式方式獲取值 Object ageValue = Ognl.getValue("age", context, person); System.out.println(ageValue); // 輸出:30 }
使用 Ognl 表達(dá)式對象方式獲取值
public static void main(String[] args) throws OgnlException { // 創(chuàng)建一個(gè)根對象 Person person = new Person("Alice", 30); // 創(chuàng)建一個(gè) Ognl 表達(dá)式對象 Object nameTree = Ognl.parseExpression("name"); // 使用表達(dá)式對象方式獲取值 Object nameValue = Ognl.getValue(nameTree, person); System.out.println(nameValue); // 輸出:Alice }
使用 Ognl 表達(dá)式對象及Ognl 上下文對象方式獲取值
public static void main(String[] args) throws OgnlException { // 創(chuàng)建一個(gè)根對象 Person person = new Person("Alice", 30); // 創(chuàng)建一個(gè) Ognl 上下文 OgnlContext context = new OgnlContext(); context.setRoot(person); // 創(chuàng)建一個(gè) Ognl 表達(dá)式對象 Object nameTree = Ognl.parseExpression("name"); // 使用表達(dá)式對象方式獲取值 Object nameValue = Ognl.getValue(nameTree, context, person); System.out.println(nameValue); // 輸出:Alice }
使用自定義的表達(dá)式訪問器和上下文對象方式獲取值
public static void main(String[] args) throws OgnlException { // 創(chuàng)建一個(gè)根對象 Person person = new Person("Alice", 30); // 創(chuàng)建一個(gè) Ognl 上下文 OgnlContext context = new OgnlContext(); context.setRoot(person); // 創(chuàng)建一個(gè)自定義的表達(dá)式訪問器 ExpressionAccessor expression = OgnlRuntime.getPropertyAccessor(Person.class); // 使用自定義的表達(dá)式訪問器和上下文對象獲取值 Object ageValue = Ognl.getValue(expression, context, person, "age"); System.out.println(ageValue); // 輸出:30 }
- 使用示例
maven依賴
<dependency> <groupId>ognl</groupId> <artifactId>ognl</artifactId> <version>3.3.4</version> </dependency>
實(shí)現(xiàn)源碼
public class OGNLTest { @Data @NoArgsConstructor @AllArgsConstructor public static class User { public Integer userId; public String userName; public Sex sex; } @Data @NoArgsConstructor @AllArgsConstructor public static class Sex { public Integer sexCode; public String sexName; } public static void main(String[] args) throws OgnlException { // 訪問對象屬性 User user = new User(111111, "哈哈", new Sex(1, "男")); Integer userId = (Integer) Ognl.getValue("userId", user); System.out.println(userId);// 111111 Integer sexCode = (Integer) Ognl.getValue("sex.sexCode", user); System.out.println(sexCode);// 1 // 調(diào)用對象方法 Double random = (Double) Ognl.getValue("@java.lang.Math@random()", null); System.out.println(random);// 0.9562367273068916 // 訪問集合和數(shù)組 List<User> list = Stream.of(user).collect(Collectors.toList()); String sexName = (String) Ognl.getValue("[0].sex.sexName", list); System.out.println(sexName);// 男 // 賦值和表達(dá)式計(jì)算 boolean isMan = (Boolean) Ognl.getValue("sex.sexCode == 1", user); System.out.println(isMan);// true // 條件表達(dá)式 String sex = (String) Ognl.getValue("sex.sexCode == 1 ? \"男\(zhòng)" : \"女\"", user); System.out.println(sex);// 男 // 對象引用 Map<String,Object> context = new HashMap<>(); context.put("aaa", new Sex(2, "女")); Integer sexCode1 = (Integer) Ognl.getValue("#aaa.sexCode", context, user); System.out.println(sexCode1);// 2 // 內(nèi)置對象 Integer sexCode2 = (Integer) Ognl.getValue("#root.sex.sexCode", user); System.out.println(sexCode2);// 1 Integer sexCode3 = (Integer) Ognl.getValue("#this.sex.sexCode", user); System.out.println(sexCode3);// 1 } }
- Mybatis
MyBatis 早期版本確實(shí)使用過 OGNL 作為表達(dá)式語言,特別是在動(dòng)態(tài) SQL 處理中。在 MyBatis 的 XML 配置文件中,OGNL 被用來處理一些復(fù)雜的表達(dá)式,例如在 、 等標(biāo)簽中進(jìn)行條件判斷。
然而,由于 OGNL 存在一些性能和安全問題,MyBatis 在后續(xù)版本中逐步淘汰了 OGNL,轉(zhuǎn)而使用更為簡潔和安全的 OGNL 變種 或 Java 原生表達(dá)式。目前,OGNL 仍然可以通過自定義插件使用,但它已不再是 MyBatis 的核心功能。
Java原生表達(dá)式更簡單、更安全,并且能夠直接利用 Java 語言的語法和功能進(jìn)行條件判斷、循環(huán)等操作。
Java原生表達(dá)式的使用
在 MyBatis 中,Java原生表達(dá)式主要用于動(dòng)態(tài) SQL 的編寫,特別是在 、、 等標(biāo)簽中,用于控制 SQL 的生成邏輯。
基本語法:
在 MyBatis 中,Java原生表達(dá)式通常出現(xiàn)在如下標(biāo)簽的屬性中:
- :用于條件判斷
- :類似于 switch-case 的控制結(jié)構(gòu)
- :用于循環(huán)生成 SQL 部分
- :用于動(dòng)態(tài) SQL 中的空白字符去除
常用的Java 原生表達(dá)式:
- 條件表達(dá)式
- 三元運(yùn)算符
- 邏輯運(yùn)算符
- 邏輯運(yùn)算(&&, ||, !)
- 數(shù)學(xué)運(yùn)算(+, -, *, /)
- 類型轉(zhuǎn)換(通過 (type) 強(qiáng)制轉(zhuǎn)換)
- 方法調(diào)用(如 string.equals())
使用示例:
(1) 標(biāo)簽中的 Java 原生表達(dá)式:
標(biāo)簽用于根據(jù)某個(gè)條件動(dòng)態(tài)地生成 SQL 片段。我們可以在 標(biāo)簽中直接使用 Java 表達(dá)式進(jìn)行條件判斷。
<select id="selectUser" resultType="User"> SELECT * FROM users <where> <if test="username != null"> AND username = #{username} </if> <if test="age != null"> AND age = #{age} </if> </where> </select>
- test=“username != null” 中的 username != null 就是一個(gè) Java 原生表達(dá)式。
- 在這里,test 屬性值就是 Java 表達(dá)式的條件判斷語句,如果表達(dá)式結(jié)果為 true,那么 中的 SQL 片段才會(huì)被加入到最終生成的 SQL 中。
(2) 標(biāo)簽中的 Java 原生表達(dá)式:
標(biāo)簽類似于 Java 中的 switch-case 語法,用于根據(jù)多個(gè)條件選擇生成不同的 SQL 片段。
<select id="selectUser" resultType="User"> SELECT * FROM users <where> <choose> <when test="age != null"> AND age = #{age} </when> <when test="username != null"> AND username = #{username} </when> <otherwise> AND status = 'active' </otherwise> </choose> </where> </select>
- 允許在多個(gè) 中根據(jù)不同條件選擇合適的 SQL 片段。
- 每個(gè) 中的 test 屬性也可以使用 Java 表達(dá)式。
(3) 標(biāo)簽中的 Java 原生表達(dá)式:
標(biāo)簽用于循環(huán)生成 SQL 片段,通常用于處理數(shù)組、集合或列表類型的參數(shù)。
<select id="selectUsersByIds" resultType="User"> SELECT * FROM users <where> <foreach collection="ids" item="id" open="AND id IN (" separator="," close=")"> #{id} </foreach> </where> </select>
- collection=“ids”:表示傳入的參數(shù)集合或數(shù)組。
- 在 標(biāo)簽中,我們可以使用 Java 表達(dá)式來處理循環(huán)邏輯和參數(shù)拼接。
(4) 使用 Java 原生三元運(yùn)算符:
在 MyBatis 中,Java原生表達(dá)式也支持使用 Java 的三元運(yùn)算符來簡化條件判斷。
<select id="selectUser" resultType="User"> SELECT * FROM users WHERE status = <if test="status != null"> #{status} </if> <if test="status == null"> 'active' </if> </select>
使用三元運(yùn)算符來替代多重條件判斷,改為:
<select id="selectUser" resultType="User"> SELECT * FROM users WHERE status = #{status != null ? status : 'active'} </select>
(5) 標(biāo)簽中的 Java 原生表達(dá)式:
標(biāo)簽用于對生成的 SQL 語句進(jìn)行前后字符的去除(如去掉 AND 或 OR 等)。
<select id="selectUser" resultType="User"> SELECT * FROM users <trim prefix="WHERE" prefixOverrides="AND |OR "> <if test="status != null">AND status = #{status}</if> <if test="age != null">AND age = #{age}</if> </trim> </select>
- Fastjson
- JSONPath類的主要方法
Object
eval
(String json, String path)
通過給定的 JSON 數(shù)據(jù)和 JSONPath 表達(dá)式,返回匹配該表達(dá)式的結(jié)果對象JSONArray
extract
(Object json, String path)
根據(jù)指定的 JSONPath 表達(dá)式,從 JSON 對象中提取匹配的 JSON 數(shù)組。返回一個(gè) JSONArray 對象boolean
contains
(Object json, String path)
判斷 JSON 數(shù)據(jù)中是否包含匹配指定 JSONPath 表達(dá)式的內(nèi)容boolean
containsValue
(Object json, String path, Object value)
判斷 JSON 對象中匹配 JSONPath 表達(dá)式的內(nèi)容是否包含指定的值int
size
(Object json, String path)
計(jì)算 JSONPath 表達(dá)式匹配的內(nèi)容的大小,并返回匹配結(jié)果的個(gè)數(shù)Set<?>
keySet
(Object json, String path)
返回 JSONPath 表達(dá)式匹配的所有鍵值的 Set 集合void
arrayAdd
(Object rootObject, String path, Object… values)
在 JSON 對象中的指定位置添加一個(gè)或多個(gè)元素void
remove
(Object json, String path)
根據(jù)指定的 JSONPath 表達(dá)式,從 JSON 對象中移除匹配路徑的內(nèi)容void
set
(Object json, String path, Object value)
根據(jù)指定的 JSONPath 表達(dá)式,在 JSON 對象中設(shè)置匹配路徑的值為指定的 valueJSONPath
compile
(String path)
編譯 JSONPath 表達(dá)式,返回一個(gè)對應(yīng)的 JSONPath 對象這個(gè)方法可以提高后續(xù)對同一個(gè) JSONPath 表達(dá)式的操作性能。
Object
read
(String json, String path)
讀取 JSON 數(shù)據(jù)中指定 JSONPath 表達(dá)式的值List
paths
(Object json, String path)
獲取 JSON 對象中匹配指定 JSONPath 表達(dá)式的所有路徑,并返回一個(gè) JSONPath 列表void
setArrayItem
(Object json, String path, Object value)
根據(jù)指定的 JSONPath 表達(dá)式,在 JSON 數(shù)組中設(shè)置匹配路徑的元素為指定的 valuevoid
removeArrayItem
(Object json, String path, int index)
根據(jù)指定的 JSONPath 表達(dá)式,從 JSON 數(shù)組中移除指定索引位置的元素
- 主要功能
- 設(shè)置JSON對象中的屬性值
- 獲取JSON對象中的屬性值
- JSONPath的優(yōu)勢
- 設(shè)置JSON對象中的屬性值時(shí),如果屬性不存在,也會(huì)自動(dòng)創(chuàng)建
- 獲取JSON對象中的屬性值是,如果屬性不存在,不會(huì)報(bào)錯(cuò)空指針,會(huì)返回null
- 使用示例
public class OGNLTest { public static void main(String[] args) { // 設(shè)置JSON對象中的屬性值 JSONObject jsonObject = new JSONObject(); JSONPath.set(jsonObject, "$.role.roleName", "管理員"); JSONPath.set(jsonObject, "$.user.userName", "Joker"); System.out.println(JSON.toJSONString(jsonObject));// {"role":{"roleName":"管理員"},"user":{"userName":"Joker"}} JSONObject jsonObject1 = JSON.parseObject("{\"role\":{\"roleName\":\"管理員\"},\"user\":{\"userName\":\"Joker\"}}"); JSONPath.set(jsonObject1, "$.user.userId", 18); System.out.println(JSON.toJSONString(jsonObject1));// {"role":{"roleName":"管理員"},"user":{"userName":"Joker","userId":18}} // 獲取JSON對象中的屬性值 System.out.println(JSONPath.eval(jsonObject, "$.role.roleName"));// 管理員 System.out.println(JSONPath.eval(jsonObject, "$.user.userName"));// Joker System.out.println(JSONPath.eval(jsonObject, "$.user.age"));// null System.out.println(JSONPath.eval(jsonObject, "$.user.sex.setName"));// null } }
Spring不選擇OGNL的原因
Spring 官方推薦的表達(dá)式語言是Spring Expression Language (SpEL) ,它提供了更強(qiáng)大的功能和更多的特性。
為什么Spring使用SpEL替代了OGNL了呢:
OGNL 在早期版本中被發(fā)現(xiàn)存在一些安全漏洞,尤其是當(dāng)其用于動(dòng)態(tài)求值時(shí),可能會(huì)導(dǎo)致惡意代碼執(zhí)行。因此,在使用 OGNL 時(shí)要特別小心,盡量避免在不信任的輸入中執(zhí)行 OGNL 表達(dá)式,或使用一些安全措施來過濾不安全的表達(dá)式。
總結(jié)
以上為個(gè)人經(jīng)驗(yàn),希望能給大家一個(gè)參考,也希望大家多多支持腳本之家。
相關(guān)文章
mybatis 運(yùn)行時(shí)加載自定義mapper文件方式
這篇文章主要介紹了mybatis 運(yùn)行時(shí)加載自定義mapper文件方式,具有很好的參考價(jià)值,希望對大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2021-07-07Java開發(fā)之普通web項(xiàng)目轉(zhuǎn)為Maven項(xiàng)目的方法
這篇文章主要給大家介紹了關(guān)于Java開發(fā)之普通web項(xiàng)目轉(zhuǎn)為Maven項(xiàng)目的相關(guān)資料,文中通過圖文將轉(zhuǎn)換的方法步驟介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧。2017-12-12Zuul 實(shí)現(xiàn)網(wǎng)關(guān)轉(zhuǎn)發(fā)的五種方式小結(jié)
這篇文章主要介紹了Zuul 實(shí)現(xiàn)網(wǎng)關(guān)轉(zhuǎn)發(fā)的五種方式小結(jié),具有很好的參考價(jià)值,希望對大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2021-07-07Springboot配置security basic path無效解決方案
這篇文章主要介紹了Springboot配置security basic path無效解決方案,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下2020-09-09詳談StringUtils3之StringUtils.isEmpty()和StringUtils.isB的區(qū)別
這篇文章主要介紹了詳談StringUtils3之StringUtils.isEmpty()和StringUtils.isB的區(qū)別,具有很好的參考價(jià)值,希望對大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2022-07-07Java設(shè)計(jì)模式之命令模式(Command模式)介紹
這篇文章主要介紹了Java設(shè)計(jì)模式之命令模式(Command模式)介紹,本文講解了Command模式的定義、如何使用命令模式等內(nèi)容,需要的朋友可以參考下2015-03-03Java數(shù)據(jù)結(jié)構(gòu)之優(yōu)先級隊(duì)列(堆)圖文詳解
優(yōu)先級隊(duì)列是比棧和隊(duì)列更專用的結(jié)構(gòu),在多數(shù)情況下都非常有用,下面這篇文章主要給大家介紹了關(guān)于Java數(shù)據(jù)結(jié)構(gòu)之優(yōu)先級隊(duì)列(堆)的相關(guān)資料,需要的朋友可以參考下2022-03-03