本文采用简单的servlet作为后台处理数据的工具,前台使用freemarker的ftl模板作为输出工具,简单说明怎样将封装有实体类对象的List集合注入到ftl模板中并且成功的在遍历显示出来,之前在网上找了很多这方面的资料,但是都没有解决这个问题,所以自己就从头认真的研读的一番freemarker的API文档,阅读了相关的类和接口的功能说明,终于找到了突破口,在这里写出来供和我有相同经历的孩纸(初学者)使用:

首先看我写的domain实体类:News.java

public class News {
private Integer news_id;
private String news_title;
private String news_publish_date;
private String news_url;
public Integer getNews_id() {
return news_id;
}
public void setNews_id(Integer news_id) {
this.news_id = news_id;
}

.....以下的set和get方法都省略..

接着看我写的newsSql.xml文件中查询所有News对象的并返回List<News>或者Map<String,News>型数据的配置信息:

<typeAlias alias="news" type="cn.domain.News"/>
<resultMap class="news" id="getMap">
<result property="news_id" column="news_id"/>
<result property="news_title" column="news_title"/>
<result property="news_publish_date" column="news_publish_date"/>
<result property="news_url" column="news_url"/>
</resultMap>
<select id="queryAllNews" resultMap="getMap">
select *from news
</select>

下面是自己第一次写的NewsListServlet代码:

public class NewsListServlet extends HttpServlet {

private static final long serialVersionUID = 1L;
private NewsDao dao;
private Configuration cfg;

public void doGet(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
request.setCharacterEncoding("utf-8");
response.setContentType("text/html;charset=utf-8");
dao = new NewsDao();
List<News> newslist = dao.getAllNews();
Map<String,List<News>> map=new HashMap<String, List<News>>();
map.put("newslist",newslist);
cfg = new Configuration();
cfg.setServletContextForTemplateLoading(this.getServletContext(),"/ftl");
Template template = cfg.getTemplate("newsList.ftl");
try {
template.process(map,response.getWriter());
} catch (TemplateException e) {
e.printStackTrace();
}

}}

下面是newslist.ftl模板代码:

<html>
<div style="background-color:#AABBCD">
<table style="border:0px">
<tr style="border:0px" align="center">
<td colspan="4">以下是今天的主要新闻</td>
</tr>
<tr align="center">
<td>编号</td>
<td>标题</td>
<td>发布时间</td>
<td>操作</td>
</tr>
<#if newslist?exists >
<#list newslist as news>
<tr align="center">
<td>${news.news_id}</td>
<td align="left">${news.news_title}</td>
<td>${news.news_publish_date}</td>
<td><a href="${news.news_url}">查看详情</a></td>
</tr>
</#list></#if>
</table>
</div>
</html>

但是运行时会出现下面的异常信息,着实让人很头疼:

freemarker.template.TemplateModelException: Don't know how to present an object of this type to a template: cn.domain.News
at freemarker.template.SimpleObjectWrapper.handleUnknownType(SimpleObjectWrapper.java:139)
at freemarker.template.SimpleObjectWrapper.wrap(SimpleObjectWrapper.java:116)
at freemarker.template.WrappingTemplateModel.wrap(WrappingTemplateModel.java:131)
at freemarker.template.SimpleSequence.get(SimpleSequence.java:197)
at freemarker.template.IteratorBlock$Context.runLoop(IteratorBlock.java:163)
at freemarker.template.Environment.visit(Environment.java:316)
at freemarker.template.IteratorBlock.accept(IteratorBlock.java:94)
at freemarker.template.Environment.visit(Environment.java:180)
at freemarker.template.ConditionalBlock.accept(ConditionalBlock.java:78)
at freemarker.template.Environment.visit(Environment.java:180)
at freemarker.template.MixedContent.accept(MixedContent.java:91)
at freemarker.template.Environment.visit(Environment.java:180)
at freemarker.template.Environment.process(Environment.java:166)
at freemarker.template.Template.process(Template.java:238)

这里我声明一下,数据的封装和传递绝对没有问题,这个异常信息的关键是:

Don't know how to present an object of this type to a template: cn.domain.News

无法引述新闻类对象到模版,也就是说模板不认识list里面的数据是News对象,所以无法通过news.news_title来访问属性对象

到这里我想大家明白我说的是什么意思了吧,通过查询API文档,可以容易看到Template.process()函数有两种形式,一个是含有两个参数的,而另一个则含有三个参数,他们分别为:

void freemarker.template.Template.process(Object dataModel, Writer out) throws TemplateException, IOException
void freemarker.template.Template.process(Object dataModel, Writer out, ObjectWrapper wrapper) throws TemplateException, IOException
其实二者没什么大的区别,只是第二个方法比第一个多增加了一个ObjectWrapper wrapper参数而已,那个增加这个参数有什么作用呢?
答案是:第一个方法中默认了ObjectWrapper wrapper参数是ObjectWrapper.SIMPLE_WRAPPER型的,但是在我们的情况下需要另一种类型,也即:ObjectWrapper.BEANS_WRAPPER,观看英文单词也理解是什么意思了吧,再看看官方的文档说明:
An ObjectWrapper that exposes the object methods and JavaBeans properties as hash elements, and has custom handling for Java Map-s, ResourceBundle-s, etc. It doesn't treat org.w3c.dom.Node-s and Jython objects specially, however.
 Object wrapper that uses SimpleXXX wrappers only. It behaves like the DEFAULT_WRAPPER, but for objects that it does not know how to wrap as a SimpleXXX it throws an exception. It makes no use of reflection-based exposure of anything, which may makes it a good candidate for security-restricted applications. 
所以错误的修改就本简单了:

Map<String,List<News>> map=new HashMap<String, List<News>>();
map.put("newslist",newslist);
cfg = new Configuration();

cfg.setServletContextForTemplateLoading(this.getServletContext(),"/ftl");
Template template = cfg.getTemplate("newsList.ftl");
try {
template.process(map,response.getWriter(),ObjectWrapper.BEANS_WRAPPER);
} catch (TemplateException e) {
e.printStackTrace();
}

以下是改正后的运行效果:

以下是今天的主要新闻
编号 标题 发布时间 操作
1 MH-17航班又在乌克兰和俄罗斯边境出事了 2014-07-15 22:19:45.0 查看详情
2 中国和巴西签订了很多外贸上的关系文件 2014-07-17 21:23:45.0 查看详情
3 全国大学生软件大赛初赛成绩公布了,三人组合团队表现很出色 2014-07-14 15:18:22.0 查看详情
4 山东交通学院将来要成为一所名副其实的大学真的很困难 2012-06-11 13:18:49.0 查看详情

呵呵,自己的一点总结,大手们不要见笑。。。

关于在freemarker模板中遍历数据模型List<JavaBean>的经验的更多相关文章

  1. 在 Django 模板中遍历复杂数据结构的关键是句点字符

    在 Django 模板中遍历复杂数据结构的关键是句点字符 ( . ). 实例二 mysit/templates/myhtml2.html修改如下 <!DOCTYPE html> <h ...

  2. freemarker 模板中定义变量

    在模板中能够定义三种类型的变量: 简单变量:它能从模板中的不论什么位置来訪问,或者从使用 include 指令引入的模板訪问. 能够使用 assign 或 macro 指令来创建或替换这些变量. 局部 ...

  3. struts2中从数据库中读取数据,并在JSP页面中遍历保存有JavaBean对象的List对象

    0x1:前言 前面搭建struts就不说了,大家都能成功完毕. 0x2:Model 这里我们须要一个Model类来接收 <span style="font-size:10px;font ...

  4. JFinal配合Shiro权限控制在FreeMarker模板引擎中控制到按钮粒度的使用

    实现在FreeMarker模板中控制对应按钮的显示隐藏主要用到了Shiro中的hasRole, hasAnyRoles, hasPermission以及Authenticated等方法,我们可以实现T ...

  5. Spring MVC 学习总结(七)——FreeMarker模板引擎与动态页面静态化

    模板引擎可以让程序实现界面与数据分离,业务代码与逻辑代码的分离,这就提升了开发效率,良好的设计也使得代码复用变得更加容易.一般的模板引擎都包含一个模板解析器和一套标记语言,好的模板引擎有简洁的语法规则 ...

  6. FreeMarker模板语法

    四.FreeMarker模板语法 要编写复杂的模板需要熟悉FreeMarker语法规则,官网有详细说明,中文帮助也比较详细了,下面这些内容是从网上收罗来的,感谢网友的分享,经过整理与修改的内容如下.建 ...

  7. 161213、Maven资源替换和Freemarker模板

    先介绍一下本文的两位主角: Apache Maven - 正当红的项目管理工具 FreeMarker - 老牌的模板引擎 两者貌似互不相干,何来冲突呢? 原来Maven有一个内置的资源替换机制, 可以 ...

  8. Freemarker中遍历List以及内置函数使用

    在Freemarker应用中经常会遍历List获取需要的数据,并对需要的数据进行排序加工后呈现给用户. 那么在Freemarker中如何遍历List,并对List中数据进行适当的排序呢?一. Free ...

  9. springboot中Thymeleaf和Freemarker模板引擎的区别

    前言这两个都是属于模板引擎,但是各有各的好处,enn,在市面上比较多的也就是jsp.freemarker.velocity.thymeleaf等页面方案.Thymeleaf和Freemarker的区别 ...

随机推荐

  1. selenium2入门 用Yaml文件进行元素管理 (五)

    比如界面有一个按钮,id号是test.如果进行对象化的话,就是test.click就可以了.不用每次都要去创建test对象.如果id号变了,我们也只需要改一下test的名称就行了. 使用Yaml需要用 ...

  2. SQL点滴26—常见T-SQL面试解析

    原文:SQL点滴26-常见T-SQL面试解析 它山之石可以攻玉,这一篇是读别人的博客后写下的,不是原原本本的转载,加入了自己的分析过程和演练.sql语句可以解决很多的复杂业务,避免过多的项目代码,下面 ...

  3. MVC6 - 视图组建

    MVC6 - 视图组建 VS2015 PERVIEW中可以创建MVC6 项目. 我们可以 发现有几大亮点. 首先我们看目录结构: 当前项目包含两个主要的文件夹:Solution Items .src ...

  4. Java集合之LinkedHashSet源码分析

    1.简介 我们知道Set不允许包含相同的元素,如果试图把两个相同元素加入同一个集合中,add方法返回false.根据源码实现中的注释我们可以知道LinkedHashSet是具有可预知迭代顺序的Set接 ...

  5. 在SSIS中使用自定义的DLL文件

    原文:在SSIS中使用自定义的DLL文件 步骤1.开发dll(需要签名) using System;using System.Collections.Generic;using System.Text ...

  6. 使用Excel快速发送大量的电子邮件

    使用Excel快速发送大量的电子邮件.两个步骤: 1. 准备发送数据: a.) 打开Excel,新Book1.xlsx b.) 填写以下内容. 第一列:接受者,第二列:邮件标题,第三列:文,第四列:附 ...

  7. SuspendLayout()了解方法

     SuspendLayout()暂时挂起的布局逻辑控制(msdn),它ResumeLayout()在会同.我的理解是,使用SuspendLayout()让整个窗体站,等到所有的东西都设置齐全,然后Re ...

  8. .NET MVC4 实训记录之五(访问自定义资源文件)

    .Net平台下工作好几年了,资源文件么,大多数使用的是.resx文件.它是个好东西,很容易上手,工作效率高,性能稳定.使用.resx文件,会在编译期动态生成已文件名命名的静态类,因此它的访问速度当然是 ...

  9. WCF 采用net.tcp协议

    WCF 采用net.tcp协议实践   概述 与Socket相比,WCF真是爽得不得了,其基本指导思想为SOA——面向服务. 其基本配置在于ABC(Address,Binding,Contract), ...

  10. 网络地址到物理地址的映射(ARP)

    网络的互连首先要解决的问题就是网络地址到物理地址的映射,以太网接口分配的是一个48位的物理地址,而IP地址却只有32位,因此无法将它编码到IP地址中.有人建议可以构建一个中央数据库存储所有网络中的网络 ...