Spring表达式语言(SpEL),用于通过列表访问json

Spring表达式语言(SpEL),用于通过列表访问json,spring,spring-el,Spring,Spring El,我在试着理解为什么这不起作用 context.addPropertyAccessor(new JsonPropertyAccessor()); Object j = mapper.readTree( "{\"foo\": {\"bar\": [ { \"fizz\": 5, \"buzz\": 6, \"doo\": 9 }, {\"fizz\": 7}, {\"fizz\": 8} ] } })"); System.out.println(evaluate(j, "foo.bar.

我在试着理解为什么这不起作用

  context.addPropertyAccessor(new JsonPropertyAccessor());

  Object j = mapper.readTree(
"{\"foo\": {\"bar\": [ { \"fizz\": 5, \"buzz\": 6, \"doo\": 9 }, {\"fizz\": 7}, {\"fizz\": 8} ] } })");

System.out.println(evaluate(j, "foo.bar.![doo == 9]"));
它总是打印:

[false, false, false]

我需要检查doo是否包含9。

如果您不需要使用SPEL,您可以轻松地使用它

包括依赖项:

<dependency>
    <groupId>com.jayway.jsonpath</groupId>
    <artifactId>json-path</artifactId>
    <version>2.4.0</version>
</dependency>
通过上面提到的链接,您可以找到关于JsonPath查询的更多详细信息


如果仍然需要将JsonPath与SPEL集成,则可以将解析函数添加到计算上下文中。幸运的是,您已经使用了spring集成,它具有
JsonPathUtils
类和
evaluate(String,String)
方法

StandardEvaluationContext evaluationContext = new StandardEvaluationContext();
Method method = BeanUtils.resolveSignature("evaluate", JsonPathUtils.class);
evaluationContext.registerFunction("jsonPath", method);

String json = "{\"foo\": {\"bar\": [ { \"fizz\": 5, \"buzz\": 6, \"doo\": 9 }, " +
            "{\"fizz\": 7}, {\"fizz\": 8, \"doo\": 7} ] } })";
evaluationContext.setVariable("foo", json);    

ExpressionParser parser = new SpelExpressionParser();
Expression expression = parser.parseExpression("#jsonPath(#foo, 'foo.bar[?(@.doo>6)]')");
Object result = expression.getValue(evaluationContext);
//now result contains still the same JSONArray


最后我找到了你问题的原因。首先:猜猜是什么返回表达式
foo.bar.doo
?它不是字符串或整数值。它返回一个
ToStringFriendlyJsonNode
的实例。所以
doo==9
总是会给你
false
,因为它们不能相等。此外,您不能使用
评估
的方法是什么?
foo.bar[?(@.doo==9)]
提供具有
doo==9的所有
bar
。如果只需要true或false,那么
foo.bar[?(@.doo)].doo==9
private static Object evaluate(Object target,String expression){return parser.parseExpression(expression).getValue(context,target);}上面的表达式给了我一个异常。线程“main”中的异常org.springframework.expression.spel.SpelParseException:表达式[foo.bar[?(@.doo==9)]]@10:EL1059E:@or&后面只能跟一个标识符或一个带引号的名称我以为你在使用jsonPath。对我来说,使用jsonPath是一个不太可行的选择,我想是因为我想在表达式中使用一些内置java方法和Springbeans中的一些函数。因此,SpEL比注册大量自定义函数更容易。仍然想知道为什么我的原始表达式在SpEL+JsonPropertyAccessor中不起作用。@user1189332我从未使用Jackson API(位于
JsonPropertyAccessor
下)进行查询。我甚至不知道它可以处理查询。但为了以防万一,我更新了我的答案,并展示了如何将JsonPath与SPEL集成。希望它能有所帮助。@user1189332我更新了答案。抱歉,在找到解决方案之前无法停止)
StandardEvaluationContext evaluationContext = new StandardEvaluationContext();
Method method = BeanUtils.resolveSignature("evaluate", JsonPathUtils.class);
evaluationContext.registerFunction("jsonPath", method);

String json = "{\"foo\": {\"bar\": [ { \"fizz\": 5, \"buzz\": 6, \"doo\": 9 }, " +
            "{\"fizz\": 7}, {\"fizz\": 8, \"doo\": 7} ] } })";
evaluationContext.setVariable("foo", json);    

ExpressionParser parser = new SpelExpressionParser();
Expression expression = parser.parseExpression("#jsonPath(#foo, 'foo.bar[?(@.doo>6)]')");
Object result = expression.getValue(evaluationContext);
//now result contains still the same JSONArray
 expression.getValue("foo.bar.![doo!=null and new Integer(doo.toString()) == 9]");