Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Handle MapAccessor exception when attribute does not exist and render blank #315

Closed
jkuhs opened this issue Sep 13, 2014 · 6 comments
Closed

Comments

@jkuhs
Copy link

jkuhs commented Sep 13, 2014

With 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.

@jkuhs
Copy link
Author

jkuhs commented Oct 2, 2014

Any chance to get some feedback on this issue @danielfernandez ?

@danielfernandez
Copy link
Member

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 a Map, and when a map is accessed a key that is not contained, the result is null.

However, ${user.gender} is the syntactic equivalent to Java code's user.getGender(), which is impossible if the getGender() 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 ;-)

@jkuhs
Copy link
Author

jkuhs commented Oct 2, 2014

Thanks for the reply! In my example, user is actually a map and MapAccessor is being used. That's why I don't understand why it would behave any different than when accessing a map via VariablesMap.

I agree that if user was not a map but a bean, there should be an exception - at compile time as you mentioned.

@danielfernandez
Copy link
Member

Ah, good. Sorry I didn't notice user was a map. In such case, I would tend to agree with you... returning null looks much better. OK, let's see what we can do with this in v3. Thanks!

@jkuhs
Copy link
Author

jkuhs commented Oct 2, 2014

Great, thanks!

danielfernandez referenced this issue Sep 29, 2015
…quest param or servletContext attribute from SpringEL. Related to #85
@danielfernandez danielfernandez self-assigned this Sep 29, 2015
@danielfernandez
Copy link
Member

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 custom PropertyAccessor 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.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

2 participants