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