在最近项目中第一次使用Freemarker生成JSP网页,用此文章记录下Freemarker的一些常用方法。
转义符
转义符是我使用Freemarker遇到的第一个坑,由于不熟悉Freemarker对自身特殊关键字的处理,导致无法正常生成jsp网页。
在jsp中,我们经常在头部用java定义一些变量,然后在jsp页面中直接使用,如下所示,这样可以动态获取网站的css样式。
<%String ctx = request.getContextPath();
request.setAttribute("ctx",ctx);
%>
<link href="${ctx}/base/css/common.css" rel="stylesheet" type="text/css">
但如果把上面的代码直接拷贝到freemarker的ftl模板中,会报错。因为
本来也属于Freemarker的关键字,用于显示后台定义的get,set变量,当模板文件
{ctx}找不到后台定义的ctx的get,set属性就会报空指针错误。对于这种情况,Freemarker提供了自己的转移标签。{r'{}}。
如果希望正确生成上面的jsp代码,可以在模板文件中用以下写法。
<link href="${r'${ctx}'}/base/css/common.css" rel="stylesheet" type="text/css" />
在前台判断后台List对象是否空
Freemarker如果后台定义的对象为空,也会导致报错无法生成模板。这时需要使用以下语法。
<#if 对象名??>
</#if>
具体案例代码如下:
<#if emergencyNavLevel??>
<#list emergencyNavLevel as emergency>
<a href="javascript:void(0)" onclick="tabSearch('EMERGENCY','${emergency}');">${emergency}</a>
</#list>
</#if>
还有以下情况,对象user,name为user的属性的情况,user,name都有可能为空,那么可以写成${(user.name)!”},表示user或者name为null,都显示为空。判断为空。代码如下:
<#if (user.name)??>
……
</#if>
前台循环输出后台List对象
无论structs的标签还是jstl的标签,前台经常需要把后台的List对象循环输出,Freemarker也提供了自己的标签在前台循环输出后台的定义的List对象。
例如:在后台定义了
private List<SysBusiListField> queryList;
public List<SysBusiListField> getQueryList() {
return queryList;
}
public void setQueryList(List<SysBusiListField> queryList) {
this.queryList = queryList;
}
Freemarker在ftl模板中输出语法为
<#list queryList as query>
</#list>
if else语法如下所示
<#if>
<#if>
<#elseif>
<#elseif>
<#else>
</#if>
if else也可以用于多层嵌套,具体案例中代码如下
<#list queryList as query>
<#if query.tdAlign==0>
<h:column <#if query.tdWidth == 0><#else>width="${query.tdWidth}"</#if> align="left" <#if query.tdValue="checkbox">headerTitle="<input type='checkbox' name='slectAll' value='checkbox' onclick='selectAll(this.checked);'>"<#else>headerTitle="${query.thCaption}"</#if> >
</#if>
<#if query.tdAlign==1>
<h:column <#if query.tdWidth == 0><#else>width="${query.tdWidth}"</#if> align="center" <#if query.tdValue="checkbox">headerTitle="<input type='checkbox' name='slectAll' value='checkbox' onclick='selectAll(this.checked);'>"<#else>headerTitle="${query.thCaption}"</#if>>
</#if>
<#if query.tdAlign==2>
<h:column <#if query.tdWidth == 0><#else>width="${query.tdWidth}"</#if> align="right" <#if query.tdValue="checkbox">headerTitle="<input type='checkbox' name='slectAll' value='checkbox' onclick='selectAll(this.checked);'>"<#else>headerTitle="${query.thCaption}"</#if>>
</#if>
<#if query.tdValue=='checkbox'><!-- selectbox -->
<input type="checkbox" name="selectedRow" value="<s:property value="id"/>" />
</#if>
<#if query.tdValue=='sequence'><!-- selectbox -->
<%=(currentPageNo-1)*pageSize+count-1%>
</#if>
<#if query.tdValue != 'status'>
<#if query.tdValue == 'createTime'>
<a target="blank" href="<s:property value="itemUrl" />" >
<s:date name="createTime" format="yyyy-MM-dd HH:mm:ss"/>
</a>
<#elseif query.tdValue == 'flContent'>
<s:if test='flContent == "1"'>
待联合审批
</s:if>
<s:elseif test='flContent == "2"'>
待联合盖章
</s:elseif>
<s:elseif test='flContent == "3"'>
待分发
</s:elseif>
<s:elseif test='flContent == "4"'>
已分发
</s:elseif>
<#elseif query.tdValue == 'status'>
<a target="blank" href="<s:property value="itemUrl" />" >
<s:if test="${query.tdValue}==1">
在办
</s:if>
<s:if test="${query.tdValue}==2">
已办
</s:if>
<s:if test="${query.tdValue}==3">
已注销
</s:if>
<s:if test="${query.tdValue}==4">
将注销
</s:if>
<s:if test="${query.tdValue}==5">
已归档
</s:if>
<s:if test="${query.tdValue}==17">
草稿
</s:if>
</a>
<#else>
<a target="blank" href="<s:property value="itemUrl" />" >
<s:property value="${query.tdValue}" />
</a>
</#if>
</#if>
</h:column>
</#list>
另外一些常用语法
item_index:当前变量的索引值
item_has_next:是否存在下一个对象 其中item名称为as后的变量名
具体案例代码如下:
<#list conditionList as conditon>
<#if conditon.srhInputType!=3><td class="td_search_title">${conditon.thCaption}:</td></#if>
<td class="td_search_box">
<#if conditon.srhInputType==0><!-- textbox -->
<input name="searchValue['${conditon.tdValue }']">
</#if>
<#if conditon.srhInputType==1><!-- datebox -->
<input readonly="" style="width: 80px" name="searchValue['${conditon.tdValue}_start']" inputtype="text">
<script type="text/javascript">
Calendar.setup( {
inputField : "searchValue['${conditon.tdValue }_start']",
ifFormat : "%Y-%m-%d"
});
</script>
至<input readonly="" style="width: 80px" name="searchValue['${conditon.tdValue}_end']" inputtype="text">
<script type="text/javascript">
Calendar.setup( {
inputField : "searchValue['${conditon.tdValue}_end']",
ifFormat : "%Y-%m-%d"
});
</script>
</#if>
<#if conditon.srhInputType==2><!-- selectbox -->
<select size="1" style="width:80px" name="searchValue['${r'${conditon.tdValue}'}']" inputtype="select"></select>
</#if>
<#if !conditon_has_next && conditon_index%3 == 1><td></td><td><input type="button" value="搜索" class="btnSo ml5" onclick="conditionSearch()"> <input name="" type="button" onclick="document.forms[0].reset();defaultEvent('search')" ;="" value="重置" class="btn2"></td></#if>
<#if !conditon_has_next && conditon_index%3 == 0><td></td><td></td><td></td><td><input type="button" value="搜索" class="btnSo ml5" onclick="defaultEvent('search')"> <input name="" type="button" onclick="document.forms[0].reset();defaultEvent('search')" ;="" value="重置" class="btn2"></td></#if>
<#if !conditon_has_next && conditon_index%3 == 2></tr><tr><td colspan="2"></td><td></td><td></td><td></td><td><input type="button" value="搜索" class="btnSo ml5" onclick="defaultEvent('search')"> <input name="" type="button" onclick="document.forms[0].reset();defaultEvent('search')" ;="" value="重置" class="btn2"></td></#if>
<#if conditon_has_next && conditon_index%3 == 2></tr><tr></#if>
</td>
</#list>