Spring 表达式语言使用映射作为上下文

Joh*_*agu 9 java spring

我正在使用 spring 表达式语言来解析一些表达式。我遇到这样一种情况:运行表达式的上下文是 BeanUtils 创建的映射或动态 bean

Map<String, Object> props= new HashMap<>();
props.put("name", "john");
ExpressionParser parser = new SpelExpressionParser();
EvaluationContext context = new StandardEvaluationContext();
Expression exp = parser.parseExpression("name==john");
boolean s  = exp.getValue(context, Boolean.class);
Run Code Online (Sandbox Code Playgroud)

这会爆炸,因为名称不是上下文中定义的公共属性。关于如何使用 spring 表达式语言来实现此类功能的任何想法

Mar*_*rco 10

您的代码中有两个错误。首先,您需要'john'在表达式中的文字字符串周围使用单引号。其次,您需要将变量props作为上下文的根对象传递。修复这些问题后,您需要使用MapAcessor属性访问器来直接访问地图属性:

    Map<String, Object> props = new HashMap<>();
    props.put("name", "john");
    ExpressionParser parser = new SpelExpressionParser();
    StandardEvaluationContext context = new StandardEvaluationContext(props);
    context.addPropertyAccessor(new MapAccessor());
    Expression exp = parser.parseExpression("name=='john'");
    boolean s  = exp.getValue(context, Boolean.class);
Run Code Online (Sandbox Code Playgroud)


小智 0

@John Kiragu,您可以通过创建与地图一起使用的自定义属性访问器来实现这一点。然后使用 SimpleEvaluationContext。请参阅下面的示例:

  PropertyAccessor accessor = new MyCustomPropertyAccessor();
  SimpleEvaluationContext evaluationContext = new SimpleEvaluationContext.Builder(accessor).
                        withRootObject(contextObject).build();
enter code here
Run Code Online (Sandbox Code Playgroud)

然后,您的自定义属性访问器将覆盖读取方法:

public class MyCustomPropertyAccessor implements PropertyAccessor {

    @Override
    public boolean canRead(EvaluationContext context, Object target, String name) throws AccessException {
      // your custom code

    }
    @Override
    public TypedValue read(EvaluationContext context, Object target, String name) throws AccessException {
    // your custom code

    }
}
Run Code Online (Sandbox Code Playgroud)

另外,如果地图不适合您,请尝试一下DynaClass