為什么采用freemarker?
1、模板技術,不依附於語言和框架,前端和后端解耦,便於分工協作,更好的協同。
2、頁面相應速度快
3、前端非常的靈活,采用自定義標簽可以在不更改后端的基礎上很容易的構造前端邏輯,可適應多變的網站。
為什么要自定義標簽?
答案在第一個問題的第三點,我們需要一個前端靈活的架構,在不更改后端邏輯的基礎上,很容易的改造前端邏輯。
在SSH的架構中,自定義標簽已經可以方便的實現(struts2的標簽也是基於freemarker的自定義標簽),但是用起來還是不夠爽,需要大量的配置,繁瑣的依賴注入等。用了jfinal以后,發現自定義freemarker標簽在該框架中用起來極爽,寥寥幾個類,幾行代碼就能將自定義標簽應用起來。廢話不多說了,上代碼吧。
第一步:實現標簽類
1 /** 2 * 分類標簽<br> 3 * 參數:{parent_id:上級主鍵} 4 * 返回值:{list:分類列表} 5 * 6 * @author yongtree 7 */ 8 public class CategoryListDirective implements TemplateDirectiveModel { 9 10 11 public void execute(Environment env, Map params, TemplateModel[] loopVars, 12 TemplateDirectiveBody body) throws TemplateException, IOException { 13 14 List<Category> list = new ArrayList<Category>(); 15 if (params.containsKey("parent_id") && params.get("parent_id") != null) { 16 list = Category.getCategoryList(params.get("parent_id").toString(), 17 Category.STATUS_ENABLED); 18 } else { 19 list = Category.getFirstCategoryList(Category.STATUS_ENABLED); 20 } 21 22 env.setVariable("list", DEFAULT_WRAPPER.wrap(list)); 23 body.render(env.getOut()); 24 } 25 26 }
第二步:action中引入
1 setAttr("_category_list", new CategoryListDirective());
第三步:頁面是使用
1 <@_category_list parent_id="2"> 2 <#list list as c> 3 <a href="/category/${c.id}">${c.name}</a> 4 </#list> 5 </@_category_list>
我們使用自定義標簽的目的是靈活,就是要將action中要做到事情,能直接通過標簽在頁面上使用。而上面的第二步,需要在action中set,使其action的邏輯不靈活。自定義標簽應該能脫離開具體的action,能在更多的模塊中用到,不受action的限制。所以第二步需要稍加改造,這是我們可以采用jfinal的全局攔截器,將這些標簽初始化內存中,在所有的action中都很容易的注入,當然你可以根據攔截器的相關配置和邏輯,將自定義標簽指定到相應的action中。上代碼吧
1 /** 2 * 自定義標簽攔截器 3 * @author yongtree 4 */ 5 public class DirectiveInterceptor implements Interceptor { 6 7 public static CategoryListDirective cld = new CategoryListDirective(); 8 9 public void intercept(ActionInvocation ai) { 10 Controller c = ai.getController(); 11 c.setAttr(LABEL_CATEGORY_LIST, cld); 12 ai.invoke(); 13 } 14 15 public static final String LABEL_CATEGORY_LIST = "_category_list"; 16 17 }
配置到Config中
1 /** 2 * 配置全局攔截器 3 */ 4 public void configInterceptor(Interceptors me) { 5 me.add(new AuthInterceptor()); 6 me.add(new DirectiveInterceptor()); 7 }
超爽吧,簡單幾步,就搞定了自定義標簽,這樣你就可以把主要的查詢和業務封裝到標簽里。在不改變業務邏輯和結構的基礎上,前端邏輯和展示需要調整,以后就只是前端開發人員或者網站美工的工作了,再輔以freemarker的macro宏定義,再前段封裝出更加方便使用的界面,那就更加的靈活和高校。所以在以內容為主的網站上,極力推薦采用這種方式來設計你的前端。
