和所有的介绍一样,我们以Hello World开始,在以后所有的例子中,我们采用webwork/xwork作为Controller.

None.gif package  cn.martin.freemarker.quickstart.action;
None.gif
None.gif
import  com.opensymphony.xwork.ActionSupport;
None.gif
ExpandedBlockStart.gifContractedBlock.gif
/**
InBlock.gif * 
@author martin
ExpandedBlockEnd.gif 
*/

ExpandedBlockStart.gifContractedBlock.gif
public   class  HelloAction  extends  ActionSupport  dot.gif {
InBlock.gif    
private String message;
InBlock.gif
ExpandedSubBlockStart.gifContractedSubBlock.gif    
public String getMessage() dot.gif{
InBlock.gif        
return message;
ExpandedSubBlockEnd.gif    }

InBlock.gif
ExpandedSubBlockStart.gifContractedSubBlock.gif    
public String execute() throws Exception dot.gif{
InBlock.gif        
this.message ="Hello World!";
InBlock.gif        
return SUCCESS;
ExpandedSubBlockEnd.gif    }

ExpandedBlockEnd.gif}

我们的页面很简单,只是显示message
None.gif < html >
None.gif
< head >
None.gif    
< title > FreeMarker Quick Start </ title >
None.gif
</ head >
None.gif
None.gif
< body >
None.gif
None.gif${message}
None.gif
None.gif
</ body >
None.gif
</ html >
  • ${message}:称为interpolations,FreeMarker会在输出时用实际值进行替代,它会按以下的顺序查找message变量
    • The value stack
    • The action context
    • Request scope
    • Session scope
    • Application scope
    • Built-in variables

如果没有该变量,会抛出异常。

其他还有

  • FTL标记(FreeMarker模板语言标记):以<#开头,我们会在下面用到
  • 注释:包含在<#-->之间

配置xwork.xml

None.gif <! DOCTYPE xwork PUBLIC "-//OpenSymphony Group//XWork 1.0//EN"
None.gif        "http://www.opensymphony.com/xwork/xwork-1.0.dtd"
>
None.gif
None.gif
< xwork >
None.gif    
< include  file ="webwork-default.xml" />
None.gif
None.gif    
< package  name ="default"  extends ="webwork-default" >
None.gif        
< action  name ="demo"
None.gif                class
="cn.martin.freemarker.quickstart.action.HelloAction" >
None.gif            
< result  name ="success"  type ="freemarker" > /templates/demo.ftl </ result >
None.gif        
</ action >
None.gif    
</ package >
None.gif
</ xwork >

webwork.properties
None.gif #  extension for actions
None.gif
webwork.action.extension =
None.gif
None.gif
#  spring integration
None.gif#
webwork.objectFactory=spring
None.gif#
webwork.objectFactory.spring.autoWire=type
None.gif

None.gif
# ## Configuration reloading
None.gif#
 This will cause the configuration to reload xwork.xml when it is changed
None.gif
webwork.configuration.xml.reload = true
None.gif
None.gif
# ## Load custom default resource bundles
None.gif
webwork.custom.i18n.resources = default
None.gif
None.gif
# ## character encoding
None.gif
webwork.i18n.encoding = UTF - 8
  1. 暂时我们用不到spring,没有必要引人
  2. 至于后缀,个人爱好,我不喜欢那么多的东西,没有任何后缀.

工程整体结构如下:
freemarker-quickstart01.gif

web.xml

None.gif <? xml version="1.0" encoding="UTF-8" ?>
None.gif
None.gif
<! DOCTYPE web-app PUBLIC "-//Sun Microsystems, Inc.//DTD Web Application 2.3//EN"
None.gif        "http://java.sun.com/dtd/web-app_2_3.dtd"
>
None.gif
< web-app >
None.gif    
< filter >
None.gif        
< filter-name > webwork </ filter-name >
None.gif        
< filter-class > com.opensymphony.webwork.dispatcher.FilterDispatcher </ filter-class >
None.gif    
</ filter >
None.gif
None.gif    
< filter-mapping >
None.gif        
< filter-name > webwork </ filter-name >
None.gif        
< url-pattern > /* </ url-pattern >
None.gif    
</ filter-mapping >
None.gif
None.gif    
< welcome-file-list >
None.gif        
< welcome-file > index.html </ welcome-file >
None.gif        
< welcome-file > demo.action </ welcome-file >
None.gif    
</ welcome-file-list >
None.gif    
< taglib >
None.gif        
< taglib-uri > webwork </ taglib-uri >
None.gif        
< taglib-location > /WEB-INF/lib/webwork.jar </ taglib-location >
None.gif    
</ taglib >
None.gif
</ web-app >

OK!deploy到server看一下结果:
freemarker-quickstart02.gif

Next:继续前进

我们来将页面做的更友好一些,用户输入姓名,显示Hello + 用户名

None.gif<html>
None.gif
<head>
None.gif    
<title>FreeMarker Quick Start</title>
None.gif
</head>
None.gif
None.gif
<body>
None.gif
None.gif
<#if userName?exists&&userName?has_content>
None.gif       Hello ${userName}!
None.gif
</#if>
None.gif
None.gif
None.gif
<form action="demo" method="post">
None.gif    Input your name:
<input type="text" size="8" name="userName"/>
None.gif    
<input type="submit" value="Get Words"/>
None.gif
</form>
None.gif
None.gif
</body>
None.gif
</html>

在该页面中,我们见到一些奇怪的表达式
None.gif<#if userName?exists&&userName?has_content>
ExpandedBlockStart.gifContractedBlock.gif       Hello $
dot.gif{userName}!
None.gif
</#if>

这是FreeMarker的表达式,暂时不管它,先了解一下即可,以后会有专门的介绍.

userName?exists 判断该变量是否存在 userName?has_content 判断该变量是否不为null并且不为empty

修改Action

None.gifpackage cn.martin.freemarker.quickstart.action;
None.gif
None.gif
import com.opensymphony.xwork.ActionSupport;
None.gif
//**
InBlock.gif * 
@author martin
ExpandedBlockEnd.gif 
*/
ExpandedBlockStart.gifContractedBlock.gif
public class HelloAction extends ActionSupport dot.gif{
InBlock.gif    
private String userName;
InBlock.gif
ExpandedSubBlockStart.gifContractedSubBlock.gif    
public void setUserName(String userName) dot.gif{
InBlock.gif        
this.userName = userName;
ExpandedSubBlockEnd.gif    }

InBlock.gif
ExpandedSubBlockStart.gifContractedSubBlock.gif    
public String getUserName() dot.gif{
InBlock.gif        
return userName;
ExpandedSubBlockEnd.gif    }

InBlock.gif
ExpandedSubBlockStart.gifContractedSubBlock.gif    
public String execute() throws Exception dot.gif{
InBlock.gif        System.out.println(
"HelloAction.execute() begin");
InBlock.gif        
return SUCCESS;
ExpandedSubBlockEnd.gif    }

ExpandedBlockEnd.gif}

freemarker-quickstart03.gif

结果如下:
freemarker-quickstart04.gif

代码:freemarker.rar 去掉了webwork/xwork/freemarker lib,请自行添上。

参考:
xwork:http://www.opensymphony.com/xwork
webwork:http://www.opensymphony.com/
freemarker:http://freemarker.org/