INT-3585: JsonPropertyAccessor: skip failed parse

JIRA: https://jira.spring.io/browse/INT-3585

Even if this fix doesn't provide an order support,
it does cover an original premise of an issue
With this fix the order of accessors doesn't matter.

* Catch an `AccessException` in the `JsonPropertyAccessor.canRead()` and return `false`
to let the rest accessors to deal with the property requested
This commit is contained in:
Artem Bilan
2021-02-24 17:09:00 -05:00
committed by Gary Russell
parent eef31d4b34
commit 51b6ba8de8
3 changed files with 35 additions and 11 deletions

View File

@@ -70,7 +70,14 @@ public class JsonPropertyAccessor implements PropertyAccessor {
@Override
public boolean canRead(EvaluationContext context, Object target, String name) throws AccessException {
JsonNode node = asJson(target);
JsonNode node;
try {
node = asJson(target);
}
catch (AccessException e) {
// Cannot parse - treat as not a JSON
return false;
}
Integer index = maybeIndex(name);
if (node instanceof ArrayNode) {
return index != null;

View File

@@ -11,15 +11,22 @@
<object-to-json-transformer id="defaultTransformer" input-channel="defaultObjectMapperInput"/>
<object-to-json-transformer id="emptyContentTypeTransformer" input-channel="customObjectMapperInput" content-type=""/>
<object-to-json-transformer id="emptyContentTypeTransformer" input-channel="customObjectMapperInput"
content-type=""/>
<object-to-json-transformer id="overriddenContentTypeTransformer" input-channel="customObjectMapperInput" content-type="text/xml"/>
<object-to-json-transformer id="overriddenContentTypeTransformer" input-channel="customObjectMapperInput"
content-type="text/xml"/>
<object-to-json-transformer id="customJsonObjectMapperTransformer" input-channel="customJsonObjectMapperInput"
object-mapper="customJsonObjectMapper"/>
<object-to-json-transformer id="jsonNodeTransformer" input-channel="jsonNodeInput" result-type="NODE"/>
<beans:bean id="customJsonObjectMapper" class="org.springframework.integration.json.ObjectToJsonTransformerParserTests$CustomJsonObjectMapper"/>
<beans:bean id="customJsonObjectMapper"
class="org.springframework.integration.json.ObjectToJsonTransformerParserTests$CustomJsonObjectMapper"/>
<spel-property-accessors>
<beans:bean id="json" class="org.springframework.integration.json.JsonPropertyAccessor"/>
</spel-property-accessors>
</beans:beans>

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2002-2019 the original author or authors.
* Copyright 2002-2021 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -21,8 +21,7 @@ import static org.assertj.core.api.Assertions.assertThat;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.ApplicationContext;
@@ -38,8 +37,8 @@ import org.springframework.integration.test.util.TestUtils;
import org.springframework.messaging.Message;
import org.springframework.messaging.MessageChannel;
import org.springframework.messaging.MessageHeaders;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
import org.springframework.messaging.support.GenericMessage;
import org.springframework.test.context.junit.jupiter.SpringJUnitConfig;
import com.fasterxml.jackson.databind.JsonNode;
@@ -48,10 +47,10 @@ import com.fasterxml.jackson.databind.JsonNode;
* @author Oleg Zhurakousky
* @author Gary Russell
* @author Artem Bilan
*
* @since 2.0
*/
@ContextConfiguration
@RunWith(SpringJUnit4ClassRunner.class)
@SpringJUnitConfig
public class ObjectToJsonTransformerParserTests {
@Autowired
@@ -69,6 +68,9 @@ public class ObjectToJsonTransformerParserTests {
@Autowired
private DefaultMessageBuilderFactory defaultMessageBuilderFactory;
@Autowired
private StandardEvaluationContext evaluationContext;
@Test
public void testContentType() {
ObjectToJsonTransformer transformer =
@@ -174,6 +176,14 @@ public class ObjectToJsonTransformerParserTests {
assertThat(expression.getValue(evaluationContext, payload, Boolean.class)).isTrue();
}
@Test
public void testReflectionBeforeJsonString() {
Expression exp = new SpelExpressionParser().parseExpression("payload.class.name");
assertThat(exp.getValue(this.evaluationContext, new GenericMessage<>("foo"))).isEqualTo(String.class.getName());
exp = new SpelExpressionParser().parseExpression("payload.foo");
assertThat(exp.getValue(this.evaluationContext, new GenericMessage<>("{\"foo\" : \"bar\"}"))).isEqualTo("bar");
}
static class CustomJsonObjectMapper implements JsonObjectMapper<Object, Object> {
@Override