Closed psmf22 closed 11 months ago
SpEL evaluation context responsible for evaluating expressions on JSON objects is configured at JsonHelper::createSpelEvaluationContext
. This evaluation context uses JsonPropertyAccessor
(standard Spring integration class, but we have our own copy in the fcli-common
project) for accessing JSON properties.
It looks like JsonPropertyAccessor::canRead
always returns true if the target is JsonNode
(with one additional condition in case of an ArrayNode
, which is not applicable for this issue). Also, the JsonPropertyAccessor::read
method simply returns node.get(name)
(without calling node.has(name)
to check whether the property actually exists), which returns null
if either the property doesn't exist, or if it does exist but has a null
value.
To resolve this issue, we'd likely need to modify either one or both of the JsonPropertyAccessor
methods mentioned above to return false or throw an exception if the property doesn't exist, based on the return value of node.has(name)
.
Some considerations:
canRead
return false
if the property doesn't exist is more in line with property accessors for standard Java objects (see ReflectivePropertyAccessor::canRead
). However, this may not always be appropriate for JSON objects given their dynamic nature. For example, server responses may potentially simply leave properties out instead of explicitly assigning a null
value, thereby causing unexpected exceptions if we change this behavior. In such cases, an easy work-around is available though by explicitly calling get(name)
from within an expression, instead of referencing the plain property name.JsonPropertyAccessor
is currently an exact copy of the original Spring class, so modifying this class may cause maintenance issues and maybe copyright issues (not sure whether copying the source code into our own source tree may already be a copyright issue?). As an alternative, maybe we should have our own JsonPropertyAccessorDecorator
class that delegates all method calls to an original JsonPropertyAccessor
instance, but adds custom behavior in the canRead
method (and maybe also read
method).
When trying to filter on non-existing fields there should be an error or at least a warning. Especially when the comparison is part of a multi-condition filter this can easily lead to confusion.
Example: Single Condition (not too bad):
Multiple Conditions:
In my case I was trying to filter on "booleanValue" using "boolValue" and it took us a while to figure out. Having an error message would be useful.