用于列表访问json的Spring Expression Language(SpEL)

问题描述 投票:1回答:1

我试图理解为什么这不起作用?

  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。

spring spring-el
1个回答
1
投票

如果您不需要使用SPEL,则可以使用Jayway JsonPath轻松完成它>

包含依赖项:

<dependency>
    <groupId>com.jayway.jsonpath</groupId>
    <artifactId>json-path</artifactId>
    <version>2.4.0</version>
</dependency>

然后使用JsonPath并查询:

Srgin json = "{\"foo\": {\"bar\": [ { \"fizz\": 5, \"buzz\": 6, \"doo\": 9 },
    {\"fizz\": 7}, {\"fizz\": 8, \"doo\": 6} ] } })";

JSONArray array = JsonPath.read(json, "foo.bar[?(@.doo==9)]");

// now array is a List of size 1, since second "doo" is not equal 9
// using array.get(0) you can get first object as a HashMap<String, Object>

通过上面提到的链接,您可以找到有关JsonPath查询的更多详细信息。


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

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的是什么?它不是String或Integer值。它返回ToStringFriendlyJsonNode的实例。因此doo==9总是会给您false,因为它们不能相等。此外,您不能使用><,因为不允许比较ObjectInteger。因此,在比较之前,您需要转换为合适的类型。

 expression.getValue("foo.bar.![doo!=null and new Integer(doo.toString()) == 9]");

此外,我们需要检查doo是否存在,因此我们需要检查nullToStringFriendlyJsonNode只能提供字符串值。这就是为什么我们必须使用ToString()。如您所见,本机SPEL不方便且过于冗长,因为不应将其用于复杂的Json查询。

© www.soinside.com 2019 - 2024. All rights reserved.