JsonPropertyAccessor 的选择器访问问题
Problem of selector access with the JsonPropertyAccessor
我在使用 org.springframework.expression.spel.standard.SpelExpressionParser 访问 Json 节点到 Spring Boot 2.2.4 服务时遇到问题。
我可以用下面的例子来描述这个问题:
给定 Json 作为 StandardEvaluationContext 中的根对象:
{"property":[{"name":"value1"},{"name":"value2"}]}
spring 表达式语言值与下面的选择器 returns value1
没有问题:
property.^[name != null].name
但是下面这个选择器 returns null
而不是 value1
:
property.^[name == 'value1'].name
有什么想法吗?
编辑:
这是一个主要方法class示例:
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[=11=]0(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我们需要处理的对象
我在使用 org.springframework.expression.spel.standard.SpelExpressionParser 访问 Json 节点到 Spring Boot 2.2.4 服务时遇到问题。 我可以用下面的例子来描述这个问题:
给定 Json 作为 StandardEvaluationContext 中的根对象:
{"property":[{"name":"value1"},{"name":"value2"}]}
spring 表达式语言值与下面的选择器 returns value1
没有问题:
property.^[name != null].name
但是下面这个选择器 returns null
而不是 value1
:
property.^[name == 'value1'].name
有什么想法吗?
编辑:
这是一个主要方法class示例:
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[=11=]0(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我们需要处理的对象