Handle MapAccessor exception when attribute does not exist and render blank
See original GitHub issueWith version 2.1.3.RELEASE, when trying to output a map attribute that does not exist via the MapAccessor
implementation, Thymeleaf currently throws an exception and the rendering fails. It would be nice if it could instead handle the exception and render the attribute value as an empty string / blank.
After all, when calling Map.get("keyThatDoesNotExist")
the map does not throw an exception. It simply returns null
. And I think it makes sense that null
should be interpreted by Thymeleaf to be rendered blank. At least it seems that’s what is done in other places.
Following is a simple example of the issue and the current workaround I’m using.
I have the following user map:
{
firstName: "John",
lastName: "Doe"
}
Now, in my template, I would like to do the following:
<div th:text="${user.firstName}"></div>
<div th:text="${user.lastName}"></div>
<div th:text="${user.gender}"></div>
This, however, will fail with an exception such as:
org.springframework.expression.spel.SpelEvaluationException: EL1008E:(pos 5): Property or field 'gender' cannot be found on object of type 'java.util.LinkedHashMap' - maybe not public?
Now, if I change the expression to ${user['gender']}
, it doesn’t throw an exception and simply renders the attribute as empty (because it doesn’t use the MapAccessor implementation I believe), which is what I would like to happen. So the below in my template works nicely.
<div th:text="${user['gender']}"></div>
I would, however, much rather use the dot-syntax and don’t quite understand why the two different formats should behave differently. It seems like an unnecessary detail to be aware of and the dot-syntax is probably far more popular than the brackets.
I realize that Thymeleaf might not be able to prevent the exception from being thrown if a Spring implementation is used behind the scenes, but it should be able to catch and ignore the exception when appropriate.
Issue Analytics
- State:
- Created 9 years ago
- Comments:6 (3 by maintainers)
Top GitHub Comments
I understand the difference in behaviour can be distracting, but it is consistent with the two different access methods being used.
In the case of
${user['gender']}
we are accessing the bean as aMap
, and when a map is accessed a key that is not contained, the result isnull
.However,
${user.gender}
is the syntactic equivalent to Java code’suser.getGender()
, which is impossible if thegetGender()
method does not exist. Something like that wouldn’t really raise an exception, because it wouldn’t even compile 😃The different context-related structures (
VariablesMap
, etc.) will be heavily refactored in Thymeleaf 3 (see #128 and #193), so this will be queued for later evaluation for the new version. Work in v3 has started already, but we haven’t reached the context layer yet 😉After evaluation, we won’t be adding any
try...catch
for catching this kind of SpringEL exceptions in Thymeleaf 3.0.This is the way Spring’s
MapAccessor
works, and doing such thing would break the compatibility between the way maps are accessed using SpringEL in thymeleaf pages and elsewhere. It could be something to think about for very specific scenarios… but catching map access exceptions in general is too big a modification of behaviour.Besides, Thymeleaf 3.0 has made an effort for reducing the amount of times a custom
PropertyAccessor
needs to be used in SpringEL expressions, so applying a customPropertyAccessor
here is not an option either. This effort has been done in order to increase the chances that the new SpringEL compiler (since Spring 4.1) is able to compile SpringEL expressions used in Thymeleaf pages to bytecode in the near future (the SpEL compiler cannot compile expressions that use custom property accessors).Closing this therefore as declined.