我們在開發的時候,往往對一些數據字典形式的數據,想將它封裝成通用的模塊以便于使用,如果使用JSP做展示層,可以創建自定義標簽來實現,現在換成FreeMarker視圖,我們一樣可以達到想要的目的。
實現FreeMarker指令其實很簡單,只要實現TemplateDirectiveModel接口,覆蓋里面的方法即可。
public void execute(Environment env, Map params, TemplateModel[] loopVars, TemplateDirectiveBody body) throws TemplateException, IOException
大象以select下拉框及顯示數據字典文本兩個自定義指令為例來進行說明。
在ssm3工程中按下圖創建freemarker package

本例只為了說明如何實現,簡便起見,所以用了DictContext這個模擬數據字典類。

我模擬了性別和學歷的數據,實際開發中,這些都是從數據庫取得,原理都差不多,這里主要是為了演示。xb01、xl01這個標識大家可以隨意定義只要保證唯一性就可以了,該類中還有兩個取數據的方法,請直接看源碼,這里就不再說明了。
接下來我們就可以來創建DictSelectDirective這個類。

上面這些參數,都是從模板頁的自定義指令中獲取的,根據我們想創建的這個select FreeMarker指令,可以定義任何我們想要的東西。因為最終生成的就是一段select html代碼。
通過params.get()獲得的參數有類型要求,不同的值需要對其轉型到相應類型。所以你不能將select的name類型轉為SimpleNumber。另外還有一點要注意,FreeMarker對值的類型很敏感,什么意思呢?比如params.get("value");這是獲得數據庫中對應的字典值,對于這個值請一定要統一定義數據類型,比如都為整型或是字符串型,否則就會轉換失敗。所以大象在這里為了演示用到了TemplateModel接口,它是所有模板數據類型的超類。雖然這樣做可以避免類型轉換的錯誤,但同時會增加類型解析的代碼量,所以完全沒有必要,因為只要前期規劃設計好,這類問題完全可以避免。
DictSelectDirective里面其它代碼就是拼裝select,這個請直接看源碼,另外代碼中用到了一個第三方開源工具commons-lang,所以pom中需要加入這個依賴。

注意紅色框部分的代碼,我在之前就說過,如果類型不確定,使用TemplateModel,就需要做類型解析的分析。而DictContext.getInstance().getDict(type.getAsString())是獲得對應類型的數據字典,for循環將數據拼裝到option中,如果是編輯表單,value有值,則會將對應的option選中。
DictDisplayDirective實現更簡單,方法DictSelectDirective一樣,這里就不再贅述。
想讓FreeMarker的指令發揮作用,我們還有一些工作要做。下面這些源碼中都有,可以直接查看代碼。
1、在servlet-context.xml里面加入紅色方框中的內容

2、在數據庫的role表中,增加sex和edu兩個字段
3、在Role.java中添加sex與edu屬性及getter,setter方法
4、修改RoleMapper.xml中insert和update語句,增加sex和edu的保存與更新。<sql id="base_column">也要增加sex和edu字段。
5、修改role_edit.html,增加性別與學歷的FreeMarker指令。

6、修改role_list.html,增加性別與學歷顯示。

7、role_view.html也作相應修改,略。
整個FreeMarker自定義指令(標簽)的實現就這些,非常簡單,大家還可以自行擴展,比如根據自身的業務需要,創建checkbox、radio等指令,或者是多個value值的文本顯示,這些原理都是一樣的。
源碼下載:ssm3_freemarker
本文為菠蘿大象原創,如要轉載請注明出處。http://www.aygfsteel.com/bolo