• 关于在freemarker模板中遍历数据模型List<JavaBean>的经验


           本文采用简单的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 查看详情

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

  • 相关阅读:
    mxnet笔记
    8.1.18示例:使用forName()的扩展
    8.1.17使用1.2版本的用户自定义类装载器
    8.1.16 使用1.1版本的用户自定义类装载器
    8.1.13 _quick 指令
    8.1.12直接引用
    8.1.11编译时常量解析
    8.1.10装载约束
    8.1.8 解析CONSTANT_String_info入口
    8.1.7 解析CONSTANT_interfaceMethodref_info入口
  • 原文地址:https://www.cnblogs.com/ljhoracle/p/3859976.html
Copyright © 2020-2023  润新知