json - JsonPropertyAccessor 的选择器访问问题
问题描述
在使用 org.springframework.expression.spel.standard.SpelExpressionParser 将 JsonNode 访问到 Spring Boot 2.2.4 服务时,我遇到了一个问题。我可以用下面的例子来描述这个问题:
给定 Json 作为 StandardEvaluationContext 中的根对象:
{"property":[{"name":"value1"},{"name":"value2"}]}
下面带有选择器的 spring 表达式语言值返回value1
没有问题:
property.^[name != null].name
但是下面的这个选择器返回null
而不是value1
:
property.^[name == 'value1'].name
任何想法 ?
编辑:
这是一个主要的方法类示例:
import java.util.List;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.JsonMappingException;
import com.fasterxml.jackson.databind.ObjectMapper;
import org.springframework.expression.spel.standard.SpelExpressionParser;
import org.springframework.expression.spel.support.StandardEvaluationContext;
import org.springframework.integration.json.JsonPropertyAccessor;
public class TestJsonAccessor {
public static void main(String[] args) throws JsonMappingException, JsonProcessingException {
StandardEvaluationContext context = new StandardEvaluationContext();
context.setPropertyAccessors(List.of(new JsonPropertyAccessor()));
context.setRootObject(new ObjectMapper().readTree("{\"property\":[{\"name\":\"value1\"},{\"name\":\"value2\"}]}"));
SpelExpressionParser parser = new SpelExpressionParser();
System.out.println(parser.parseExpression("property.^[name != null].name").getValue(context));
System.out.println(parser.parseExpression("property.^[name == 'value1'].name").getValue(context));
}
}
在打印的控制台中:
value1
Exception in thread "main" org.springframework.expression.spel.SpelEvaluationException: EL1007E: Property or field 'name' cannot be found on null
at org.springframework.expression.spel.ast.PropertyOrFieldReference.readProperty(PropertyOrFieldReference.java:213)
at org.springframework.expression.spel.ast.PropertyOrFieldReference.getValueInternal(PropertyOrFieldReference.java:104)
at org.springframework.expression.spel.ast.PropertyOrFieldReference.access$000(PropertyOrFieldReference.java:51)
at org.springframework.expression.spel.ast.PropertyOrFieldReference$AccessorLValue.getValue(PropertyOrFieldReference.java:406)
at org.springframework.expression.spel.ast.CompoundExpression.getValueInternal(CompoundExpression.java:92)
at org.springframework.expression.spel.ast.SpelNodeImpl.getValue(SpelNodeImpl.java:112)
at org.springframework.expression.spel.standard.SpelExpression.getValue(SpelExpression.java:272)
at TestJsonAccessor.main(TestJsonAccessor.java:20)
解决方案
问题出在这里:name == 'value1'
。这name
不是要比较的纯文本 - 它是一个ToStringFriendlyJsonNode
并且要使其与该equal
运算符一起工作,您需要将其作为字符串。因此像这样:
property.^[name.toString() == 'value1'].name
实现目标还有另一种更长的方法:
property.^[name.getTarget().asText() == 'value1'].name
它的JsonPropertyAccessor
目的是使最终结果对最终用户友好。在中间它仍然是我们需要处理的一些 JSON 对象。
推荐阅读
- angular - 如何在不使用 ngx-Admin Starter Kit 的情况下使用 ngx-Admin 组件?
- c#-4.0 - SMTP 服务器需要安全连接或客户端未通过身份验证。服务器响应为:5.7.57 客户端未通过身份验证发送
- data-structures - 在不使用任何额外空间的情况下反转队列
- angular - Wifiwizard 已添加到我的配置和 package.json 文件中,但我在 module.ts 文件中找不到导入
- javascript - 使用 JavaScript 和 Chart.js 根据请求创建多个图表
- pandas - 如何将多列分组为逗号分隔的输出
- java - 无法使用 servlet 和 JavaMail 发送电子邮件
- java - Java 抛出“PersistenceException:SQLGrammarException:无法提取结果集”
- c# - 使用 rest 更新 azure cdn 中的 blob 内容类型
- security - 如何删除网站 url 名称中的反射跨站点脚本