Spring Expression Language使用map作为上下文

时间:2018-10-08 12:05:51

标签: 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);

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

3 个答案:

答案 0 :(得分:1)

正如@Marco所说,需要做一些修改。

  1. 在表达式中的文字字符串'john'周围使用单引号。
  2. 您需要将props变量作为上下文的根对象传递。
  3. 但是我们可以按照文档中所述使用SpEL直接访问地图

    // Officer's Dictionary
    
    Inventor pupin = parser.parseExpression("Officers['president']").getValue(
            societyContext, Inventor.class);
    
  4. 使用#this['name']Using #this

总是定义变量#this并引用当前变量 评估对象(针对哪些不合格的引用已解决)。

修改后,代码将如下所示:

    Map<String, Object> props= new HashMap<>();
    props.put("name", "john");
    ExpressionParser parser = new SpelExpressionParser();
    EvaluationContext context = new StandardEvaluationContext(props);
    Expression exp = parser.parseExpression("#this['name']=='john'");
    boolean s  = exp.getValue(props, Boolean.class);

答案 1 :(得分:0)

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

  PropertyAccessor accessor = new MyCustomPropertyAccessor();
  SimpleEvaluationContext evaluationContext = new SimpleEvaluationContext.Builder(accessor).
                        withRootObject(contextObject).build();
enter code here

您的自定义属性访问器将覆盖read方法:

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

    }
}

如果地图不适合您,请给DynaClass射击。

答案 2 :(得分:0)

您的代码中有两个错误。首先,您需要在表达式中的文字字符串'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);