在使用Struts2与Freemarker开发时候,可以通过使用Freemarker的宏(macro)来达到数据与页面分离的效果,使页面开发者与后台业务开发者分离,并提高了业务代码的重用性。
主要的思路如下。
首先是Struts2代码
package com.test.mms.article.web.tag;
import org.apache.struts2.ServletActionContext;
import org.springframework.context.annotation.Scope;
import com.opensymphony.xwork2.ActionSupport;
@SuppressWarnings("serial")
@Scope("prototype")
public class TagAction extends ActionSupport {
public String execute() {
String[] names = { "Lucy", "Lily", "Gordon" };
ServletActionContext.getRequest().setAttribute("names", names);
return SUCCESS;
}
}
接着是Freemarker的宏声明,因为使用了struts2-convention-plugin ,故不需要配置文件指定跳转关系。
<#macro Test_tag >
<@s.action name="tag" namespace="/article/web/tag" executeResult="false">
</@s.action>
<#nested names>
</#macro>
请求了TagAction并将executeResult指定为false,不返回页面,只从request中获取数据。
下面是具体调用宏的页面。MMS是Freemarker的命名空间。
<@MMS.Test_tag >
<#if names??>
<ul>
<#list names as name>
<li>
${name}
</li>
</#list>
</ul>
<#else>
我是空的
</#if>
</@MMS.Test_tag>
MMS.Test_tag宏的声明也可以进行如下优化
<#macro Test_tag inner="1">
<@s.action name="tag" namespace="/article/web/tag" executeResult="false">
</@s.action>
<#nested names,ages,educations>
<#if inner="0">
<#if names??>
<#list names as name>
<span>${name}</span>
</#list>
</#if>
</#if>
</#macro>
简单解释下,宏加入了一个新参数inner 默认值是1,当inner为0时候为names提供一个默认的样式,而ages,educations是另外两组数据不提供默认样式。