天天看點

OFBiz進階--OFBiz問答之[ftl]檔案中{?keys}和{map.keySet()}顯示異常分析

一個問題引發的思考   來看場景 1   我有一個 java 的 Map 變量, 希望在 ftl 檔案中被 list 循環疊代顯示到頁面, 示例如下 java代碼片段 1 Map<String, String> javaMap = new HashMap<String, String>(); javaMap.put(“a”, “A”); javaMap.put(“b”, “B”);   ftl代碼片段 1 <#list javaMap.keySet() as ke>     <p>${ke}=${javaMap[ke]}</p> </#list>   渲染出的ftl代碼 <p>a=A</p> <p>b=B</p>   ftl代碼片段 2 <#list javaMap?keys as ke>     <p>${ke}=${javaMap[ke]}</p> </#list>   渲染出的ftl代碼 模闆渲染錯誤, 在${javaMap[ke]}地方渲染發生錯誤   ftl代碼片段 3 <#list javaMap?keys as ke>     ${ke}; </#list>   渲染出的ftl代碼 hashCode;keyOne;getClass;get;values;toString;keyTwo;clone;keySet;containsValue;notifyAll;clear;size;empty;entrySet;isEmpty;class;put;putAll;remove;containsKey;equals;wait;notify;   在看場景 2  java代碼片段 2 String javaString = “{'a':'A','b':'B'}”;   ftl代碼片段 4 <#assign ftlBeanObj = javaString?eval> 驗證 , 對象會是Map特性的對象嗎 <#list ftlBeanObj.keySet() as ke>     <p>${ke}=${ftlBeanObj[ke]}</p> </#list>   驗證 -結果如下,渲染出的html代碼 模闆渲染錯誤, 在 ftlBeanObj.keySet() 地方渲染發生錯誤, 沒找到這個方法 ftl代碼片段 5 <#assign ftlBeanObj = javaString?eval> 驗證 , 對象會是JSON特性的對象嗎 <#list ftlBeanObj?keys as ke>        <p>${ke}=${ftlBeanObj[ke]}</p> </#list>   驗證 -結果如下,渲染出的html代碼 <p>a=A</p> <p>b=B</p>   分析, 在前文環境中 javaMap是一個java的對象,      若想正确的周遊其記憶體儲的鍵值對, 需要使用對象自身方法 Map.keySet() 方法來周遊     若使用ftl專屬文法 ?keys, 将會把 javaMap 對象這個HashMap類自身的java.method當作對象的屬性, 在這裡被周遊出來   javaString?eval 這個ftl專屬文法将建構一個ftl專屬的 DefaultObjectWrapper 對象,      此時需要使用 ?keys 文法,才能正确的周遊出其内部的實際鍵值對     這裡建構出來的對象不具有Map性質

    思考 有文章提到 javaMap 的這種周遊現象是因為 ftl 将 java Object 轉為 BeansWrapper 對象了, 而不是轉為 DefaultObjectWrapper 對象 原文如下 However, some really old FreeMarker integrations use a strange configuration, where the public Map methods (like getClass) appear as keys. That happens as they are using a pure BeansWrapper (instead of DefaultObjectWrapper) whose simpleMapWrapper property was left on false. You should avoid such a setup, as it mixes the methods with real Map entries.   要想使用 javaMap.keySet() 方式周遊鍵值對, 需要調整 ftl 的初始配置(ps: 本人還未嘗試,不确定配置改動是否能正常得到後文提到的結果 在配置檔案中加入如下配置: <prop key="object_wrapper">freemarker.ext.beans.BeansWrapper</prop>   在 OFBiz 中這個配置的初始化如下, 這裡是 BeansWrapper 對象 // import freemarker.ext.beans. BeansWrapper; // import freemarker.ext.beans. BeansWrapperBuilder; // import freemarker. template. Configuration; // import freemarker. template. Version; Version version = Configuration. VERSION_2_3_24; Configuration newConfig = new Configuration(version); BeansWrapper wrapper = new BeansWrapperBuilder(version).build(); newConfig.setObjectWrapper(wrapper);   若如 OFBiz 中這種配置, 确實會如前文 javaMap.keySet() 周遊正常;  javaMap?keys 周遊出錯; <!--?xml version="1.0" encoding="UTF-8" standalone="no"?-->     在 Moqui 中這個配置的初始化如下, 這裡是 BeansWrapper 對象 [org.moqui.impl.context.renderer.FtlTemplateRenderer#makeFtlConfiguration] // Version FTL_VERSION = Configuration.VERSION_2_3_25; Configuration newConfig = new MoquiConfiguration ( FTL_VERSION, ecfi ); BeansWrapper defaultWrapper = new BeansWrapperBuilder ( FTL_VERSION ). build (); newConfig. setObjectWrapper (defaultWrapper );   若如 Moqui 中這種配置, 也會如前文 javaMap.keySet() 周遊正常;  javaMap?keys 周遊出錯;      參考連結 [ https://www.eertime.com/archives/255.html]

<!--?xml version="1.0" encoding="UTF-8" standalone="no"?-->

[ https://stackoverflow.com/questions/1497777/freemarker-iterating-over-hashmap-keys] 

繼續閱讀