【参考:http://blog.csdn.net/fangzhangsc2006/article/details/8687371】

在采用FreeMarker做前台视图模板的情况下,我们可以通过<#include>标签和自定义宏来解决很多重复性工作。

一个简单的FreeMarker宏:

  1. <#macro sayHello name="">
  2. hello ${name}
  3. </#macro>

然后通过如下的形式调用:

  1. <@sayHello name="shannon" />

不过这种在模板页中定义的宏能力有限。【1】假设,我们很多页面都要输出一个热门排行框,而排行数据需要从controller层动态获取,我们可以用这种宏来完成所有的展示工作,但前提是相应的controller和接口中层需要预先将这些排行数据放到model中去,因此对于后端来说这也是一个重复性的工作。那么有没有一种方式可以让后端也脱离这种重复工作呢?答案是肯定的,这也是写这篇博客的目的。

在一个偶然的机会发现jeecms项目中用到了这种方式,于是借鉴了一番。

FreeMarker不仅可以在前端的模板页中定义宏,还可以通过扩展其接口在后端实现宏,这有什么好处呢?这种方式就好比让你的模板页具备了从前端再次回到后端的能力。这样我们就能很好的解决【1】处的假设,我们无需在各个controller的各个接口中去重复的向model中添加所需的排行数据,而是当FreeMarker渲染模板页时遇到相应的宏它可以回到后端去调用相应的方法取到所需的数据。例子如下:

  1. import freemarker.core.Environment;
  2. import freemarker.template.ObjectWrapper;
  3. import freemarker.template.TemplateDirectiveModel;
  4. /**
  5. * FreeMarker自定义宏
  6. * 获取App下载排行列表
  7. * 参数包括 length(列表长度) mtypeCode(主类型代码) typeCode(小类型代码) rankMode(排行模式1、2、3)
  8. * @author shannon
  9. *
  10. */
  11. public class FMAppRankDirective implements TemplateDirectiveModel {
  12. @Resource(name = "appRankService")
  13. private AppRankService appRankService;
  14. @SuppressWarnings("unchecked")
  15. @Override
  16. public void execute(Environment env, Map params, TemplateModel[] loopVars,
  17. TemplateDirectiveBody body) throws TemplateException, IOException {
  18. //DirectiveUtils是借用jeecms项目中的工具类,主要是因为它集成了一些异常处理功能,
  19. //其实完全可以不用它,params是个Map,自己通过key取值就可以了,做一下空值判断
  20. Integer length = DirectiveUtils.getInt("length", params);
  21. Integer mtypeCode = DirectiveUtils.getInt("mtypeCode", params);
  22. Integer typeCode = DirectiveUtils.getInt("typeCode", params);
  23. Integer rankMode = DirectiveUtils.getInt("rankMode", params);
  24. ArrayList<App> rankList = appRankService.getRankList(length, mtypeCode, typeCode, rankMode);
  25. env.setVariable("appRankList", ObjectWrapper.DEFAULT_WRAPPER.wrap(rankList));
  26. if (body != null) {
  27. body.render(env.getOut());
  28. }
  29. }
  30. }

通过实现FreeMarker的TemplateDirectiveModel就在后端实现了一个自定义的宏,这个宏的功能很简单,只是根据给定的参数将排行数据“appRankList”放到model中去,然后模板页中就可以使用这个变量了。

FreeMarker的配置参数中需要将这个宏加入进去。

  1. <bean id="appRankDirective" class="com.shannon.example.rank.util.FMAppRankDirective" />
  2. <bean id="freemarkerConfigurer" class="org.springframework.web.servlet.view.freemarker.FreeMarkerConfigurer">
  3. ……其他配置略……
  4. <property name="freemarkerVariables">
  5. <map>
  6. ……其他配置略……
  7. <entry key="appRankDirective" value-ref="appRankDirective"/>
  8. </map>
  9. </property>
  10. </bean>

在模板页中使用:

  1. <#-- 应用下载排行框,title为该框的标题,length为排行列表长度,mtypeCode为主类型代码,typeCode为小类型代码,rankMode为排行方式
  2. 1为总下载量,2为月下载量,3为昨日增长下载量
  3. -->
  4. <#macro appRankBox title="" length=10 mtypeCode=1 typeCode=-1 rankMode=1>
  5. <@appRankDirective length=length mtypeCode=mtypeCode typeCode=typeCode rankMode=rankMode />
  6. <h3 class="box-title">${title}</h3>
  7. <div class="box">
  8. <ul class="row-list">
  9. <#list appRankList as item>
  10. ……详细输出内容略……
  11. </#list>
  12. </ul>
  13. </div>
  14. </#macro>

这里我在模板页中又定义了一个宏,负责内容及样式的输出,因为模板页中的宏比较直观,让后端的宏只负责拿数据。其他页面直接使用“appRankBox”就可以了,然后由它来调用后端的“appRankDirective”宏来拿数据。

这样,controller就从重复工作中脱身了。

FreeMarker自定义TemplateDirectiveModel的更多相关文章

  1. 关于FreeMarker自定义TemplateDirectiveModel

    [转载来源:http://zwllxs.iteye.com/blog/2036826] java代码如下: import freemarker.core.Environment; import fre ...

  2. FreeMarker 自定义 TemplateDirectiveModel(二)

    FreeMarker 是一个用 Java 语言编写的模板引擎,它基于模板来生成文本输出.FreeMarker 与 Web 容器无关,即在 Web 运行时,它并不知道 Servlet 或 HTTP.它不 ...

  3. FreeMarker 自定义 TemplateDirectiveModel(一)

    FreeMarker 是一个用 Java 语言编写的模板引擎,它基于模板来生成文本输出.FreeMarker 与 Web 容器无关,即在 Web 运行时,它并不知道 Servlet 或 HTTP.它不 ...

  4. 基于SSM3框架FreeMarker自定义指令(标签)实现

    通过之前的Spring MVC 3.0.5+Spring 3.0.5+MyBatis3.0.4全注解实例详解系列文章,我们已经成功的整合到了一起,这次大象将在此基础上对框架中的FreeMarker模板 ...

  5. freemarker自定义标签(与java合用)

    自定义类继承FreemarkerManager类,重写protected Configuration createConfiguration(ServletContext servletContext ...

  6. OneBlog开源博客-详细介绍如何实现freemarker自定义标签

    前言 OneBlog中使用到了springboot + freemarker的技术,同时项目里多个controller中都需要查询一个公有的数据集合,一般做法是直接在每个controller的方法中通 ...

  7. freemarker 自定义标签

    1.编写标签类 package com.pccw.business.fnd.common.filegen; import java.io.IOException; import java.io.Wri ...

  8. freemarker自定义标签报错(六)

    freemarker自定义标签 1.错误描述 freemarker.core.ParseException: Encountered "\"\u4f60\u597d\uff01\& ...

  9. freemarker自定义标签报错(五)

    freemarker自定义标签 1.错误描述 六月 05, 2014 11:40:49 下午 freemarker.log.JDK14LoggerFactory$JDK14Logger error 严 ...

随机推荐

  1. 转载:poj题目分类(侵删)

    转载:from: POJ:http://blog.csdn.net/qq_28236309/article/details/47818407 按照ac的代码长度分类(主要参考最短代码和自己写的代码)  ...

  2. CSS元素隐藏的11种方法

    { display: none; /* 不占据空间,无法点击 */ } { visibility: hidden; /* 占据空间,无法点击 */ } { position: absolute; cl ...

  3. form表单提交数据的数据格式

    form表单提交的数据格式默认是 enctype="application/x-www-form-urlencoded"这样将input框的数据与input框的name属性以键值对 ...

  4. JAVA之Map使用

    参考: http://blog.csdn.net/laixiaobailing/article/details/41644327

  5. pip 使用总结

    pip的安装: Windows Python2.7 以上的版本均自带pip,安装的时候记得勾选对应的选项即可. 安装easy_install, 通过easy_install pip 下载[easy_s ...

  6. .pth 文件扩展python环境路径

    有时候我们不希望把一个库放到 site-packages 下面,而是更愿意把它保留在原始的工程目录中,方便管理和维护. 通常的做法是在程序启动的时候,往sys.path里面增加这个目录,但是这样做非常 ...

  7. Falsy Bouncer

    真假美猴王! 删除数组中的所有假值. 在JavaScript中,假值有false.null.0."".undefined 和 NaN. 这是一些对你有帮助的资源: Boolean ...

  8. 在js中做数字字符串补0

    转自(http://blog.csdn.net/aimingoo/article/details/4492592) 通常遇到的一个问题是日期的“1976-02-03 HH:mm:ss”这种格式 ,我的 ...

  9. eureka -2 - 重要配置

    Server 端配置 eureka.client.registerWithEureka :是否将自己注册到Eureka Server,默认是true,如果是单节点部署,切是server端,则设置成fa ...

  10. sed用法详解

    转载自: SED单行脚本快速参考(Unix 流编辑器) 如侵犯您的版权,请联系:Windeal12@qq.com ------------------------------------------- ...