Merge pull request #17 from weihubeats/add-spring-boot-nebula-all

update ExpressionUtil
This commit is contained in:
weihubeats 2024-09-14 10:02:49 +08:00 committed by GitHub
commit cdfe36f9b4
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
2 changed files with 218 additions and 25 deletions

View File

@ -14,14 +14,14 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.nebula.web.common.utils;
import com.nebula.base.utils.DataUtils;
import java.lang.reflect.Method;
import java.util.Objects;
import org.apache.commons.lang3.StringUtils;
import java.util.Map;
import org.springframework.core.LocalVariableTableParameterNameDiscoverer;
import org.springframework.expression.EvaluationContext;
import org.springframework.expression.Expression;
import org.springframework.expression.ExpressionParser;
import org.springframework.expression.spel.standard.SpelExpressionParser;
import org.springframework.expression.spel.support.StandardEvaluationContext;
@ -32,36 +32,127 @@ import org.springframework.expression.spel.support.StandardEvaluationContext;
* @description:
*/
public class ExpressionUtil {
private static final ExpressionParser parser = new SpelExpressionParser();
private static final LocalVariableTableParameterNameDiscoverer discoverer = new LocalVariableTableParameterNameDiscoverer();
/**
* el表达式解析
* 解析EL表达式
*
* @param expressionString 解析值
* @param expressionString 表达式字符串
* @param method 方法
* @param args 参数
* @return
* @return 解析结果
*/
public static Object parse(String expressionString, Method method, Object[] args) {
if (DataUtils.isEmpty(expressionString)) {
if (isEmpty(expressionString)) {
return null;
}
// 获取被拦截方法参数名列表
LocalVariableTableParameterNameDiscoverer discoverer = new LocalVariableTableParameterNameDiscoverer();
// SPEL解析
String[] paramNames = discoverer.getParameterNames(method);
if (paramNames == null || args == null || paramNames.length != args.length) {
throw new IllegalArgumentException("Method parameter names and argument values do not match.");
}
// SPEL解析
ExpressionParser parser = new SpelExpressionParser();
StandardEvaluationContext context = new StandardEvaluationContext();
for (int i = 0; i < Objects.requireNonNull(paramNames).length; i++) {
context.setVariable(paramNames[i], args[i]);
}
return parser.parseExpression(expressionString).getValue(context);
EvaluationContext context = createEvaluationContext(method, args);
return parseExpression(expressionString, context);
}
/**
* 解析EL表达式
*
* @param expressionString 表达式字符串
* @param rootObject 根对象
* @return 解析结果
*/
public static Object parse(String expressionString, Object rootObject) {
if (isEmpty(expressionString)) {
return null;
}
return parseExpression(expressionString, rootObject);
}
/**
* 解析EL表达式
*
* @param expressionString 表达式字符串
* @param variables 变量Map
* @return 解析结果
*/
public static Object parse(String expressionString, Map<String, Object> variables) {
if (isEmpty(expressionString)) {
return null;
}
EvaluationContext context = createEvaluationContext(variables);
return parseExpression(expressionString, context);
}
/**
* 判断是否为EL表达式
*
* @param param 待判断的字符串
* @return 是否为EL表达式
*/
public static boolean isEl(String param) {
return !StringUtils.isEmpty(param) && param.startsWith("#");
return !isEmpty(param) && param.startsWith("#");
}
/**
* 创建EvaluationContext
*
* @param method 方法
* @param args 参数
* @return EvaluationContext
*/
private static EvaluationContext createEvaluationContext(Method method, Object[] args) {
String[] paramNames = discoverer.getParameterNames(method);
EvaluationContext context = new StandardEvaluationContext();
if (paramNames != null) {
for (int i = 0; i < paramNames.length; i++) {
context.setVariable(paramNames[i], args[i]);
}
}
return context;
}
/**
* 创建EvaluationContext
*
* @param variables 变量Map
* @return EvaluationContext
*/
private static EvaluationContext createEvaluationContext(Map<String, Object> variables) {
EvaluationContext context = new StandardEvaluationContext();
variables.forEach(context::setVariable);
return context;
}
/**
* 解析表达式
*
* @param expressionString 表达式字符串
* @param context EvaluationContext
* @return 解析结果
*/
private static Object parseExpression(String expressionString, EvaluationContext context) {
Expression expression = parser.parseExpression(expressionString);
return expression.getValue(context);
}
/**
* 解析表达式
*
* @param expressionString 表达式字符串
* @param rootObject 根对象
* @return 解析结果
*/
private static Object parseExpression(String expressionString, Object rootObject) {
Expression expression = parser.parseExpression(expressionString);
return expression.getValue(rootObject);
}
/**
* 判断字符串是否为空
*
* @param str 待判断的字符串
* @return 是否为空
*/
private static boolean isEmpty(String str) {
return str == null || str.trim().isEmpty();
}
}

View File

@ -0,0 +1,102 @@
package com.nebula.web.common.utils;
import java.lang.reflect.Method;
import java.util.HashMap;
import java.util.Map;
import org.junit.jupiter.api.Test;
import org.springframework.expression.spel.SpelParseException;
import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertFalse;
import static org.junit.jupiter.api.Assertions.assertNull;
import static org.junit.jupiter.api.Assertions.assertThrows;
import static org.junit.jupiter.api.Assertions.assertTrue;
/**
* @author : wh
* @date : 2024/9/13 16:19
* @description:
*/
public class ExpressionUtilTest {
@Test
void testParseWithMethodAndArgs() throws NoSuchMethodException {
Method method = TestClass.class.getDeclaredMethod("testMethod", String.class, int.class);
Object[] args = {"Hello", 5};
assertEquals("Hello", ExpressionUtil.parse("#param1", method, args));
assertEquals(5, ExpressionUtil.parse("#param2", method, args));
assertEquals("Hello5", ExpressionUtil.parse("#param1 + #param2", method, args));
}
@Test
void testParseWithRootObject() {
TestClass testObj = new TestClass("World", 10);
assertEquals("World", ExpressionUtil.parse("name", testObj));
assertEquals(10, ExpressionUtil.parse("age", testObj));
assertEquals("World is 10 years old", ExpressionUtil.parse("name + ' is ' + age + ' years old'", testObj));
}
@Test
void testParseWithVariables() {
Map<String, Object> variables = new HashMap<>();
variables.put("x", 10);
variables.put("y", 20);
assertEquals(30, ExpressionUtil.parse("#x + #y", variables));
assertEquals(200, ExpressionUtil.parse("#x * #y", variables));
}
@Test
void testIsEl() {
assertTrue(ExpressionUtil.isEl("#expression"));
assertFalse(ExpressionUtil.isEl("normalString"));
assertFalse(ExpressionUtil.isEl(""));
assertFalse(ExpressionUtil.isEl(null));
}
@Test
void testParseWithInvalidExpression() {
assertThrows(SpelParseException.class, () -> ExpressionUtil.parse("invalid#expression", new Object()));
}
@Test
void testParseWithEmptyExpression() {
assertNull(ExpressionUtil.parse("", new Object()));
assertNull(ExpressionUtil.parse(null, new Object()));
}
// 用于测试的内部类
private static class TestClass {
private String name;
private int age;
public TestClass(String name, int age) {
this.name = name;
this.age = age;
}
public void testMethod(String param1, int param2) {
// 方法体为空仅用于测试
}
// Getters and setters
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
}
}