void

Struts2下使用FreeMarker

当今的页面展示技术主要分为两种:基于JSP和EL表达式、采用模板引擎(FreeMarker、Velocity等)。 FreeMarker是一个用java语言编写的模板引擎,它基于模板生成文本输出。它强制将展示层和业务逻辑层分开,使开发人员不能像JSP页面那样在页面中添加业务逻辑。

FreeMarker采用${…}的语法形式在模块中充当占位符,运行时,由模板引擎解析模板,并用动态数据替换${…}部分的内容。FreeMarker不仅可以用作表现层的实现技术,还可以生成XMLJspJava文件等。

FreeMarker模板主要由四部分组成 :

◆普通文本

◆注释 <#--注释内容-->

插值:${..}和#{..} 

◆FTL标签。FTL标签的名字以#开始,如:<#if user=“admin”>…</#if>;自定义标签使用@代替#。

 

一、使用FreeMarker作为Struts2表现层的示例

  1. package com.action.convention;  
  2.   
  3. import java.util.ArrayList;  
  4. import java.util.List;  
  5. import org.apache.struts2.convention.annotation.Action;  
  6. import org.apache.struts2.convention.annotation.Result;  
  7. import com.opensymphony.xwork2.ActionSupport;  
  8.   
  9. @Result(name = "success", location = "/freemarker.ftl")  
  10. public class HelloAction extends ActionSupport {  
  11.   
  12.     public String execute() {  
  13.         System.out.println("execute");  
  14.         return SUCCESS;  
  15.     }  
  16.   
  17.     public List<String> getList() {  
  18.         List<String> list = new ArrayList<String>();  
  19.         list.add("aaa");  
  20.         list.add("bbb");  
  21.         list.add("ccc");  
  22.         list.add("ddd");  
  23.         return list;  
  24.     }  
  25. }  

 

freemarker.ftl

  1. <html>  
  2. <head>  
  3. <meta http-equiv="Content-Type" content="text/html; charset=utf-8">  
  4. <title>Insert title here</title>  
  5. </head>  
  6. <body>  
  7. This is my first freemarker page!  
  8. <br/>  
  9. <#--循环list里的内容-->  
  10. <#list list as item>  
  11. ${item}  
  12. </#list>  
  13. </body>  
  14. </html>  

 

生成的页面如下:

 

二、使用FreeMarker模板生成Action示例

 

为了使用FreeMarker来将数据模型中的值合并到模板文件中,可按如下步骤进行:

1,创建Configuration实例,该实例负责管理FreeMarker的模板加载路径,负责生成模板实例

2,使用Configuration实例来生成Template实例,同进需要指定使用的模板文件

3,填充数据模型,数据模型就是一个Map对象

4,调用Template实例的process方法完成合并

  1. private static void createAction() throws Exception {  
  2.     // 第一步:创建freemarker.template.Configuration实例  
  3.     Configuration cfg = new Configuration();  
  4.     File directory = new File("src/resources/template");  
  5.     // 指定.ftl模板路径  
  6.     cfg.setDirectoryForTemplateLoading(directory);  
  7.   
  8.     // 第二步:使用Configuration实例来生成Template实例,同进需要指定使用的模板文件  
  9.     String tempFile = "action.ftl";  
  10.     Template template = cfg.getTemplate(tempFile);  
  11.   
  12.     // 第三步:填充数据模型,数据模型就是一个Map对象  
  13.     LoginUser user1 = new LoginUser();  
  14.     user1.setUsername("Cui");  
  15.     user1.setPassword("1212");  
  16.     Map<String, Object> map = new HashMap<String, Object>();  
  17.     map.put("user", user1);  
  18.   
  19.     // 第四步:调用Template实例的process方法完成合并  
  20.     Writer writer = new FileWriter("./bin/createAction.java");  
  21.     template.process(map, writer);  
  22. }  

 

action.ftl模板内容如下:

  1. import com.opensymphony.xwork2.ActionSupport;  
  2.   
  3. public class ${user.username}Action extents ActionSupport{  
  4. public String execute() {  
  5.         System.out.println("${user.password}");  
  6.         return SUCCESS;  
  7.     }  
  8. }  

 

运行测试方法createAction()在指定路径下生成createAction.java文件,文件内容如下:

import com.opensymphony.xwork2.ActionSupport;

public class CuiAction extents ActionSupport{
public String execute() {
        System.out.println("1212");
        return SUCCESS;
    }
}

可见,用user对象的值填充了freemarker文件中的占位符。

PS:在上面的示例完成后又在工程下做了一些其他的示例,这两天学习FreeMarker重新运行第一个示例时FreeMarker却报错了,提示无法获取list变量,错误信息如下:

   把list放入Session中可以正常显示,但是手动把变量放入Session中不仅麻烦session也会越来越大,这样肯定不能解决问题。重新创建了一个strut2工程,取消了struts-convention插件支持,测试成功,这让我怀疑是struts-convention插件对FreeMarker的支持有问题,但写这篇博客时做的示例就好好的。后来换到LoginAction下进行测试,但是又发现一个问题:登录form中的username和password无法通过属性驱动传递到LoginAction的username和password属性中,提取参数并将参数传递给Action属性的工作是由param拦截器实现的,难不成param拦截器出问题了?应该也不会,上网搜了一下发现http://topic.csdn.net/u/20110213/14/59b09329-b292-4164-a0fa-e2e6d7fa20d8.html?65640中遇到的问题和我的一样,他提到去掉AOP支持就可以正常传值,这才想到自己前几天做了一个Spring AOP的示例,把applicationContext.xml中关于AOP的配置去掉,页面到Action的传值成功,Action中的属性传值给FreeMarker模板也成功了。关于Spring AOP造成传值失败需要再查找一下。

分享到: 
  • 上一篇:JQuery日期插件datepicker的使用
  • 下一篇:SSH下Action中无法注入业务bean的解决方法
  • 查看评论
    1楼 zrzking 2012-05-28 13:47发表 [回复]
    我也遇到类似问题,很是困扰,最后是如何解决的?
    Re: cuisea 2012-06-01 13:58发表 [回复]
    回复zrzking:你也用到AOP了吗?我的报错是因为自定义了一个AOP拦截器:
    1. @Aspect  
    2. public class SecurityHandler {  
    3.     // 在执行指定方法前执行  
    4.     @Before("execution(* add*(..))")  
    5.     private void checkSecurity() {  
    6.         System.out.println("添加前检查通过");  
    7.     }  
    8.   
    9.     // 在执行指定方法后执行  
    10.     @After("execution(* add*(..))")  
    11.     private void checkResult() {  
    12.         System.out.println("添加后检查通过");  
    13.     }  
    14. }  

    这个示例测试操作add方法,可能对其他拦截器产生影响了,把add改成其他“ff”之类,即拦截其他方法这样黄页问题就没有了。当然你也可以在工程中去掉自定义AOP。



    转自 http://blog.csdn.net/cuihaiyang/article/details/6227409

    posted on 2013-06-19 08:49 void 阅读(1030) 评论(1)  编辑  收藏

    Feedback

    # re: Struts2下使用FreeMarker 2016-02-29 09:30 延伸

    什么嘛  回复  更多评论   


    只有注册用户登录后才能发表评论。


    网站导航: