Reputation: 365
When iterating map
<#list map?keys as key>
${key}
</#list>
will return clone,1,getKey,5,etc
Anyone have solution instead of removing unwanted value one by one ?
Upvotes: 2
Views: 787
Reputation: 31152
You get both methods and keys mixed, if I understand well. This depends on the object_wrapper
configuration setting (Configuration.setObjectWrapper(ObjectWrapper)
). If you are using a BeansWrapper
as the object_wrapper
(as opposed to DefaultObjectWrapper
, which never had this problem), this can be prevented by yourBeansWrapper.setSimpleMapWrapper(true)
. However, it's maybe not accidental that in that project it's false
. There's a problem that FreeMarker language doesn't have a map type. It has something called hash, and that only supports string keys (sub-variables). So people may just use the Java API of java.util.Map
-s instead of hash operators like []
, ?keys
, etc., and for that setSimpleMapWrapper(false)
is needed, otherwise you don't see the Map
methods. Then you should write map.keySet()
.
Update: In 2.3.22 and later, nobody is forced to use mixed methods and keys anymore (which was a rather confusing workaround even back then), as the Java methods (and Java Bean properties) are accessible in a separate namespace through ?api
, like myMap?api.get(nonStringKey)
, myMap?api.keySet()
etc. So you can use an ObjectWrapper
that exposes the Map
keys only and supports the ?api
feature (preferably object_wrapper=DefaultObjectWrapper(2.3.22)
), enable ?api
(api_builtin_enabled=true
; by default it's disallowed for backward-security), then just use ?api
when you need something from the Java API namespace, and otherwise use []
, ?keys
, etc. if your Map
keys are String
-s.
Upvotes: 4
Reputation: 3679
Try with below syntax
<#assign keys = map?keys>
<#list keys as key>${key} = ${h[key]}; </#list>
EDIT -Extending @ddekany answer,
you would need to handle this in the code where you parse/invoke the FTL, some thing like below( just sample code). It could have been better ff you can add the FTL processing code here.
BeansWrapper ow = new BeansWrapper();
ow.setExposeFields(true);
// ow.setSimpleMapWrapper(true);
Template template = freeMarkerConfiguration.getTemplate(templateName, locale);
template.setObjectWrapper(ow);
template.process(root, writer);
Upvotes: 1