Проблема доступа к селектору с помощью JsonPropertyAccessor - PullRequest
1 голос
/ 31 марта 2020

Я допускаю проблему при доступе к JsonNode с помощью org.springframework.expression.spel.standard.SpelExpressionParser в сервис Spring Boot 2.2.4. Я могу описать проблему следующим примером:

Учитывая Json как root объект в StandardEvaluationContext:

{"property":[{"name":"value1"},{"name":"value2"}]}

значение языка выражения весны с селектором ниже возвращает 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)

1 Ответ

0 голосов
/ 01 апреля 2020

Проблема здесь: name == 'value1'. То, что name - это не простой текст для сравнения - это ToStringFriendlyJsonNode, и для того, чтобы он работал ожидаемым с этим оператором equal, вам нужно сделать его в виде строки. Поэтому вот так:

property.^[name.toString() == 'value1'].name

Существует еще один гораздо более длинный способ достижения цели:

property.^[name.getTarget().asText() == 'value1'].name

Смысл JsonPropertyAccessor в том, чтобы сделать конечный результат удобным для конечного пользователя , В середине это все еще какой-то JSON объект, с которым нам нужно иметь дело.

...