freemarker

FreeMarker是一个用Java语言编写的模板引擎,它基于模板来生成文本输出。FreeMarker与Web容器无关,即在Web运行时,它并不知道Servlet或HTTP。它不仅可以用作表现层的实现技术,而且还可以用于生成XML,JSP或Java 等。

页面的静态化  有的较多

中的注释都是以#号表示的



第一个项目结构

代码的实现

package cn.itcast.freemarker.model;

public class Group {
	private String name;
	
	String id;

	public String getName() {
		return name;
	}

	public void setName(String name) {
		this.name = name;
	}

	public Group(String name) {
		super();
		this.name = name;
	}

	public Group() {
	}
	
	public void sayHello(){
		System.out.println("hello");
	}
	

	public void sayHello2(){
		System.out.println("hello");
	}
	
	public void sayHello1(){
		System.out.println("hello");
		
		System.out.println("hello2");
		
		System.out.println("hello3");
	}
	
	public void test(){

		System.out.println("lisi");

		System.out.println("wangwu");
		System.out.println("wangwu");
	}
}

package cn.itcast.freemarker.model;

public class User {
	private int id;
	private String name;
	private int age;
	private Group group;
	
	private String ddd;
	
	public Group getGroup() {
		return group;
	}
	public void setGroup(Group group) {
		this.group = group;
	}
	public int getId() {
		return id;
	}
	public void setId(int id) {
		this.id = id;
	}
	public String getName() {
		return name;
	}
	public void setName(String name) {
		this.name = name;
	}
	public int getAge() {
		return age;
	}
	public void setAge(int age) {
		this.age = age;
	}
	
	
	public void remove(){
		
	}
}

package cn.itcast.util;

import java.io.BufferedWriter;
import java.io.File;
import java.io.FileOutputStream;
import java.io.OutputStreamWriter;
import java.io.Writer;
import java.util.Map;

import freemarker.template.Configuration;
import freemarker.template.Template;

public class FMutil {
	
	/**
	 * 
	 * @param ftlName:模板名称
	 * @param fileName:生成的页面名称
	 * @param map:数据
	 * @throws Exception
	 */
	public void ouputFile(String ftlName, String fileName,  Map<String, Object> map) throws Exception{
		//创建fm的配置
		Configuration config = new Configuration();
		//指定默认编码格式
		config.setDefaultEncoding("UTF-8");
		//设置模板的包路径,包的路径使用/来分隔
		config.setClassForTemplateLoading(this.getClass(), "/ftl");
		获得包的模板
		Template template = config.getTemplate(ftlName);
		//指定文件输出的路径
		String path = "D:/fm";
		//定义输出流,注意的必须指定编码
		Writer writer = new BufferedWriter(new OutputStreamWriter(new FileOutputStream(new File(path+"/"+fileName)),"UTF-8"));
		//生成模板
		template.process(map, writer);
	}

}

fm1.ftl

${username}
fm2.ftl

<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Insert title here</title>
</head>
<body>
<h1>${username}</h1>
</body>
</html>
fm3.ftl
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Insert title here</title>
</head>
<body>
<h1>${user.id}-------${user.name}-------${user.age}</h1>


<#-- 注释的写法-->
	<#if user.age lt 10>
		小孩
	<#elseif user.age lt 16>
		未成年
	<#else>
		已经成年
	</#if>
  
</body>
</html>

fm4.ftl
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Insert title here</title>
</head>
<body>
<#list userList as user>
	<#-- list的索引变量名+"_index" -->
	${user_index}---------${user.id}-----${user.name}-------${user.age}<br>
</#list>

</body>
</html>

fm5.ftl

<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Insert title here</title>
<#include "/top1.ftl">
</head>
<body>
<#list userList as user>
${user.id}-----${user.name}-------${user.age}<br>
</#list>
</body>
</html>
fm6.ftl

<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Insert title here</title>

</head>
<body>
<#-- 如果所取的属性值为空默认不处理会报错,如果想显示空(xxx.yy)!-->
${user.id}-----${user.name}-------${user.age}-----${(user.group)!}<br>


${user.group!"空值"}
${(user.group.name)!}
<#-- 三层以上不如不加括号用!直接取值不成功必须加括号,按规范无论几层都加括号-->


${(a.b)!}

<#-- ()??非空判断-->

<#if (user.group)??>
不为空
<#else>
为空
</#if>

</body>
</html>
fm6.ftl
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Insert title here</title>

</head>
<body>

<#assign name="zhangsan">
${name}

<#assign num=10>
${num+10}
 
<#assign num="10">
${num+10}
<#--布尔类型必须要转成字符串来输出-->
<#assign is=true>
${is?string}

${(a.b)???string}

<#-- 日期需要转成字符串输出 -->
${now?string("yyyy-MM-dd HH:mm:ss")}

<#--如果变量重复后边的变量值会覆盖前面的-->
<#assign bir="1985-04-22 12:33:33"?date("yyyy-MM-dd HH:mm:ss")>
${bir}

<br>
<#assign bir="1985-04-22 12:33:33"?datetime("yyyy-MM-dd HH:mm:ss")>

${bir}

<#-- 把html转成文本类型 -->
${"<br/>"?html}

${"abcd"?left_pad(10,"-")}

${1.6?int}


</body>
</html>
fm7.ftl

<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Insert title here</title>

</head>
<body>

<#assign name="zhangsan">
${name}

<#assign num=10>
${num+10}
 
<#assign num="10">
${num+10}
<#--布尔类型必须要转成字符串来输出-->
<#assign is=true>
${is?string}

${(a.b)???string}

<#-- 日期需要转成字符串输出 -->
${now?string("yyyy-MM-dd HH:mm:ss")}

<#--如果变量重复后边的变量值会覆盖前面的-->
<#assign bir="1985-04-22 12:33:33"?date("yyyy-MM-dd HH:mm:ss")>
${bir}

<br>
<#assign bir="1985-04-22 12:33:33"?datetime("yyyy-MM-dd HH:mm:ss")>

${bir}

<#-- 把html转成文本类型 -->
${"<br/>"?html}

${"abcd"?left_pad(10,"-")}

${1.6?int}


</body>
</html>
productDetail.ftl
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<head>
<meta charset="utf-8">
<meta name="author" content="http://www.asiainfo-linkage.com/" />
<meta name="copyright" content="asiainfo-linkage.com 版权所有,未经授权禁止链接、复制或建立镜像。" />
<meta name="description" content="中国移动通信 name.com"/>
<meta name="keywords" content="中国移动通信 name.com"/>
<meta name="viewport" content="width=device-width, initial-scale=1.0, user-scalable=yes, minimum-scale=1.0, maximum-scale=1.0"/>
<meta name="apple-mobile-web-app-capable" content="yes" />
<meta http-equiv="X-UA-Compatible" content="IE=EmulateIE10" />
<title>商品详细_移动商城_中国移动通信</title>
<link rel="icon" href="/favicon.ico" type="image/x-icon" />
<link rel="shortcut icon" href="/favicon.ico" type="image/x-icon" />
<link rel="search" type="application/opensearchdescription+xml" href="../opensearch.xml" title="移动购物" />
<link rel="stylesheet" href="../res/css/style.css" />
<script src="../res/js/jquery.js"></script>
<script src="../res/js/com.js"></script>
<script type="text/javascript">
<#assign path="http://localhost:8088/ecps-portal">
<#assign upload="http://localhost:8080/pic/">
$(function(){
	//拿到第一个a链接
	var firstA =  $(".box_orange li div a:first");
	//获取到sku的价钱
	var skuPrice = firstA.attr("skuPrice");
	//获取到市场价
	var marketPrice = firstA.attr("marketPrice");
	//设置sku价钱和市场价
	$("#skuPrice").html("¥"+skuPrice);
	$("#marketPrice").html("¥"+marketPrice);
	//获取sku的Id
	var skuId = firstA.attr("skuId");
	//验证sku的库存
	$.ajax({
		url:"${path}/item/validateStock.do",
		type:"post",
		dataType:"text",
		data:{
			skuId:skuId
		},
		success:function(responseText){
			if(responseText == "no"){
				//如果没有库存对购买和加入购物车的按钮来做隐藏
				$("#isStock").html("缺货");
				$("#buyNow").hide();
				$("#addCart").hide();
			}else{
				//如果有库存对购买和加入购物车的按钮来做显示
				$("#isStock").html("有货");
				$("#buyNow").show();
				$("#addCart").show();
			}
		},
		error:function(){
			alert("系统错误");
		}
		
	})
	//点击sku的a链接的时候
	$(".box_orange li a").click(function(){
		//移除所用选中的样式
		$(".box_orange li div a").each(function(){
			$(this).removeClass();
		});
		//点击的sku加上选中样式
		$(this).attr("class","here");
		var skuPrice = $(this).attr("skuPrice");
		var marketPrice = $(this).attr("marketPrice");
		$("#skuPrice").html("¥"+skuPrice);
		$("#marketPrice").html("¥"+marketPrice);
		var skuId = $(this).attr("skuId");
		$.ajax({
			url:"${path}/item/validateStock.do",
			type:"post",
			dataType:"text",
			data:{
				skuId:skuId
			},
			success:function(responseText){
				if(responseText == "no"){
					$("#isStock").html("缺货");
					$("#buyNow").hide();
					$("#addCart").hide();
				}else{
					$("#isStock").html("有货");
					$("#buyNow").show();
					$("#addCart").show();
				}
			},
			error:function(){
				alert("系统错误");
			}
			
		})
		
	});

	$("#loginAlertIs").click(function(){
		tipShow('#loginAlert');
	});

	$("#promptAlertIs").click(function(){
		tipShow('#promptAlert');
	});

	$("#transitAlertIs").click(function(){
		tipShow('#transitAlert');
	});

	var $smallList = $(".smallList"),
		$smallL = $(".smallL"),
		$smallR = $(".smallR"),
		smallLen = $(".smallList a").length,
		smallNum = 0;
	$smallList.css("width",(smallLen*60));
	$smallL.live("click",function(){
		if(smallNum > 0){
			$smallList.stop(true,true).animate({
				"left":"+="+60
			},400);
			smallNum--;
		}
	});
	$smallR.live("click",function(){
		if(smallNum <= (smallLen-5)){
			$smallList.stop(true,true).animate({
				"left":"-="+60
			},400);
			smallNum++;
		}
	});

	$('#ecpsShareIcon a').click(function(){
		
		var type   = $(this).attr('class');
		
		var title  = document.title;
		var url    = window.location.href;
		var imgUrl = '';
		var href   = '';

		var share  = [
			{id:'0',type:'sinawb',name:'分享到新浪微博', href: ['http://v.t.sina.com.cn/share/share.php?url=',  encodeURIComponent(url), '&title=', encodeURIComponent(title)].join(''), bp: '0px 0px'},
			{id:'1',type:'qqwb',name: '分享到腾讯微博', href: ['http://v.t.qq.com/share/share.php?url=',  encodeURIComponent(url), '&title=', encodeURIComponent(title)].join(''), bp: '0px -16px'},
			{id:'2',type:'renren',name: '分享到人人网', href: ['http://www.connect.renren.com/share/sharer?url=',  encodeURIComponent(url), '&title=', encodeURIComponent(title)].join(''), bp: '0px -32px'},
			{id:'3',type:'qqzone',name: '分享到QQ空间', href: ['http://sns.qzone.qq.com/cgi-bin/qzshare/cgi_qzshare_onekey?url=',  encodeURIComponent(url), '&title=', encodeURIComponent(title)].join(''), bp: '0px -48px'},
			{id:'4',type:'sohuwb',name: '分享到搜狐微博', href: ['http://t.sohu.com/third/post.jsp?content=utf-8&url=',  encodeURIComponent(url), '&title=', encodeURIComponent(title)].join(''), bp: '0px -64px'},
			{id:'5',type:'',name: '分享到开心网', href: ['http://www.kaixin001.com/repaste/bshare.php?rurl=',  encodeURIComponent(url), '&rtitle=', encodeURIComponent(title)].join(''), bp: '0px -80px'},
			{id:'6',type:'',name: '分享到51社区', href: ['http://share.51.com/share/outSiteShare.php?uri=' , encodeURIComponent(url) ,'&title=' ,encodeURIComponent(title)].join(''), bp: '0px -96px'}
		];

		for(var i=0; i<share.length; i++){
			if(type == share[i].type){
				href = share[i].href;
			};
		}

		if(type == 'copy'){

			var copyText = url.replace(/[.]{1}\d[.]{1}/gi, ".");
			copyText = copyText.replace(/\.+u+\d+\.+html/,".html");
			copyText = title + "\r\n" + copyText + "\r\n";
			if (window.clipboardData){
				window.clipboardData.setData("Text", copyText);
				alert('复制成功!');
			}
		}else{
			$(this).attr('href',href);
		}

	});

	$('.sub').mousedown(function(){
		var num = $('.num').val();
		--num;
		if(num == 0){
			$('#sub_add_msg').html('您填写的数字超过购买下限,单次购买下限为<var>1</var>件。');
			$('#sub_add_msg').show();
			return;
		}else{
			$('#sub_add_msg').hide();	
		}
		$('.num').val(num);
		
	});

	$('.add').mousedown(function(){
		var num = $('.num').val();
		++num;
		if(num == 6){
			$('#sub_add_msg').html('您填写的数字超过购买上限,单次购买上限为<var>5</var>件。');
			$('#sub_add_msg').show();
			return;
		}else{
			$('#sub_add_msg').hide();
		}
		$('.num').val(num);
	});
	
});
function buy(){
	window.location.href = "./shop/confirmProductCase.jsp";
}

function addCart(){
	window.location.href = "./shop/car.jsp";
}
</script>
</head>
<body>
<div id="tipAlert" class="w tips">
	<p class="l">本网站将于4月11日12:00进行系统维护,维护期间,本站将暂停业务办理等相关业务,敬请见谅。</p>
	<p class="r"><a href="javascript:void(0);" title="关闭" οnclick="$('#tipAlert').hide();"></a></p>
</div>

<div class="bar"><div class="bar_w">
	<p class="l">
		<!-- 未登录 -->
		<b class="l">
			<a href="#" title="个人客户" class="here">个人客户</a>
			<a href="#" title="企业客户">企业客户</a>
		</b>
		<span class="l">
			欢迎来到中国移动!<a href="javascript:void(0);" title="登录" id="loginAlertIs" class="orange"><samp>[</samp>请登录<samp>]</samp></a> <a href="passport/register.html" title="免费注册">免费注册</a>
			<a href="javascript:void(0);" id="promptAlertIs" title="promptAlert">promptAlert</a>
			<a href="javascript:void(0);" id="transitAlertIs" title="transitAlert">transitAlert</a>
		</span>
		<!-- 登录后
		<span class="l">
			您好,<a href="passport/personalInfo.html" title="13717782727">13717782727</a>!   <a href="#" title="我的账户" class="blue">我的账户</a>   <a href="#" title="我要办理" class="blue">我要办理</a>  <a href="passport/loginOut.html" title="退出" class="orange"><samp>[</samp>退出<samp>]</samp></a>
		</span>
		-->
	</p>
	<ul class="r uls">
	<!--
	<li class="dev"><a href="#" title="我的订单">我的订单</a></li>
	<li class="dev"><a href="#" title="我的收藏">我的收藏</a></li>
	<li class="dev"><a href="#" title="帮助中心">帮助中心</a></li>
	-->
	<li class="dev"><a href="#" title="在线客服">在线客服</a></li>
	<li class="dev"><a href="#" title="关于中国移动">关于中国移动</a></li>
	<li class="dev after"><a href="#" title="English">English</a></li>
	
	</ul>
</div></div>

<div class="w header">
	<h1><a href="http://www.bj.10086.cn" title="中国移动通信">中国移动通信</a></h1>
	<div class="area">
		<dl id="city">
			<dt><a href="javascript:void(0);" title="贵州">贵州<samp class="inb"></samp></a></dt>
			<dd class="bx hidden">
				<div class="tl"></div><div class="tr"></div>
				<ul class="ul">
				<li><a href="http://www.bj.10086.cn" title="北京">北京</a></li>
				<li><a href="http://www.gd.10086.cn" title="广东">广东</a></li>
				<li><a href="http://www.sh.10086.cn" title="上海">上海</a></li>
				<li><a href="http://www.tj.10086.cn" title="天津">天津</a></li>
				<li><a href="http://www.cq.10086.cn" title="重庆">重庆</a></li>
				<li><a href="http://www.ln.10086.cn" title="辽宁">辽宁</a></li>
				<li><a href="http://www.js.10086.cn" title="江苏">江苏</a></li>
				<li><a href="http://www.he.10086.cn" title="河北">河北</a></li>
				<li><a href="http://www.sc.10086.cn" title="四川">四川</a></li>
				<li><a href="http://www.sn.10086.cn" title="陕西">陕西</a></li>
				<li><a href="http://www.sx.10086.cn" title="山西">山西</a></li>
				<li><a href="http://www.ha.10086.cn" title="河南">河南</a></li>
				<li><a href="http://www.jl.10086.cn" title="吉林">吉林</a></li>
				<li><a href="http://www.sd.10086.cn" title="山东">山东</a></li>
				<li><a href="http://www.ah.10086.cn" title="安徽">安徽</a></li>
				<li><a href="http://www.hn.10086.cn" title="湖南">湖南</a></li>
				<li><a href="http://www.gx.10086.cn" title="广西">广西</a></li>
				<li><a href="http://www.jx.10086.cn" title="江西">江西</a></li>
				<li><a href="http://www.gz.10086.cn" title="贵州">贵州</a></li>
				<li><a href="http://www.yn.10086.cn" title="云南">云南</a></li>
				<li><a href="http://www.xz.10086.cn" title="西藏">西藏</a></li>
				<li><a href="http://www.gs.10086.cn" title="甘肃">甘肃</a></li>
				<li><a href="http://www.zj.10086.cn" title="浙江">浙江</a></li>
				<li><a href="http://www.fj.10086.cn" title="福建">福建</a></li>
				<li><a href="http://www.hi.10086.cn" title="海南">海南</a></li>
				<li><a href="http://www.hb.10086.cn" title="湖北">湖北</a></li>
				<li><a href="http://www.nx.10086.cn" title="宁夏">宁夏</a></li>
				<li><a href="http://www.qh.10086.cn" title="青海">青海</a></li>
				<li><a href="http://www.xj.10086.cn" title="新疆">新疆</a></li>
				<li><a href="http://www.hl.10086.cn" title="黑龙江">黑龙江</a></li>
				<li class="col6"><a href="http://www.nm.10086.cn" title="内蒙古">内蒙古</a></li>
				<li class="col3"><a href="http://www.chinamobileltd.com" title="China Mobile Ltd">China Mobile Ltd</a></li>
				<li class="col3"><a href="http://labs.10086.cn" title="中国移动研究院">中国移动研究院</a></li>
				<li class="col3"><a href="http://www.cmdi.10086.cn" title="中国移动设计院">中国移动设计院</a></li>
				</ul>
				<div class="fl"></div><div class="fr"></div>
			</dd>
		</dl>
	</div>
	<p title="移动改变生活"><span>移动</span>改变生活<samp>>></samp></p>
</div>

<div class="w nav">
	<ul class="uls">
	<li><a href="#" title="服务与支持" class="a"><b>服务与支持</b></a></li>
	<li id="shop" class="here"><a href="#" title="网上营业厅" class="a"><b>网上营业厅</b></a>
		<div class="col4 hidden">
			<dl class="col">
				<dt title="手机商城">手机商城</dt>
				<dd><a href="#" title="诺基亚">诺基亚</a></dd>
				<dd><a href="#" title="华为">华为</a></dd>
				<dd><a href="#" title="三星">三星</a></dd>
				<dd><a href="#" title="最新优惠">中兴</a></dd>
			</dl>
			<dl class="col2">
				<dt title="网上选号">网上选号</dt>
				<dd><a href="#" title="全球通">全球通</a></dd>
				<dd><a href="#" title="动感地带">动感地带</a></dd>
				<dd><a href="#" title="神州行">神州行</a></dd>
			</dl>
			<dl class="col3">
				<dt title="优惠活动">优惠活动</dt>
				<dd><a href="#" title="购机返话费">购机返话费</a></dd>
				<dd><a href="#" title="优惠购机">优惠购机</a></dd>
			</dl>
			<span></span>
		</div>
	</li>
	<li id="my"><a href="#" title="我的移动" class="a"><b>我的移动</b></a>
		<div class="col2 hidden">
			<dl class="col">
				<dt title="我的账户">我的账户</dt>
				<dd><a href="#" title="套餐余量查询">套餐余量查询</a></dd>
				<dd><a href="#" title="积分查询">积分查询</a></dd>
				<dd><a href="#" title="业务状态查询">业务状态查询</a></dd>
				<dd><a href="#" title="充值缴费" class="red">充值缴费</a></dd>
				<dd><a href="#" title="详单查询">详单查询</a></dd>
				<dd><a href="#" title="余额查询">余额查询</a></dd>
				<dd><a href="#" title="账单查询">账单查询</a></dd>
			</dl>
			<dl class="col2">
				<dt title="我要办理">我要办理</dt>
				<dd><a href="#" title="快速查找">快速查找</a></dd>
				<dd><a href="#" title="产品推荐">产品推荐</a></dd>
				<dd><a href="#" title="生活配对">生活配对</a></dd>
				<dd><a href="#" title="最新优惠">最新优惠</a></dd>
			</dl>
			<dl class="col3">
				<dt title="移动生活">移动生活</dt>
				<dd><a href="#" title="手机阅读">手机阅读</a></dd>
				<dd><a href="#" title="无线音乐俱乐部">无线音乐俱乐部</a></dd>
				<dd><a href="#" title="手机游戏">手机游戏</a></dd>
			</dl>
			<span></span>
		</div>
	</li>
	<li><a href="#" title="首页" class="a"><b>首页</b></a></li>
	</ul>
</div>

<div class="w sch">
	<div class="l">
		<dl class="goto">
			<dt title="快捷办理通道">快捷办理通道<i class="inb"></i></dt>
			<dd class="hidden">
				<a href="#" target="_blank" title="移动数据流量详单">移动数据流量详单</a>
				<a href="#" target="_blank" title="家庭亲情网">家庭亲情网</a>
				<a href="#" target="_blank" title="虚拟网业务">虚拟网业务</a>
				<a href="#" target="_blank" title="全球通商旅套餐">全球通商旅套餐</a>
				<a href="#" target="_blank" title="短信业务">短信业务</a>
				<a href="#" target="_blank" title="彩铃业务">彩铃业务</a>
				<a href="#" target="_blank" title="WLAN业务(含校园版)">WLAN业务(含校园版)</a>
				<a href="#" target="_blank" title="G3可视电话">G3可视电话</a>
				<a href="#" target="_blank" title="全球通上网套餐">全球通上网套餐</a>
				<a href="#" target="_blank" title="飞信业务">飞信业务</a>
			</dd>
		</dl>
		<p><a href="#" title="购机选号">购机选号</a><samp>|</samp><a href="#" title="网上交费">网上交费</a><samp>|</samp><a href="#" title="积分商城">积分商城</a><samp>|</samp><a href="http://www.gz.10086.cn/zf/" target="_blank">资费专区</a></p>
	</div>

	<form method="post" action="" name="" class="r">
		热门搜索:<a href="#" title="GPRS">GPRS</a><samp>|</samp><a href="#" title="全球通新88套餐">全球通新88套餐</a>
		<select name="screahType" id="screahType">
			<option>商城</option>
			<option>号卡</option>
			<option>门户</option>
		</select><input type="text" class="txt_sch gray" id="screahWord" name="screahWord" οnfοcus="if(this.value=='请输入商品名称关键字'){this.value='';this.className='txt_sch'}" οnblur="if(this.value==''){this.value='请输入商品名称关键字';this.className='txt_sch gray'}" value="请输入商品名称关键字" /><input type="submit" value="搜索" class="hand btn60x26" /></form>
</div>

<div class="w loc">
	
	<p class="l"><a href="#" title="商城首页">商城首页</a><samp>|</samp><a href="#" title="我的商城">我的商城</a></p>

	<dl id="cart" class="cart l">
		<dt><a href="#" title="结算">结算</a>购物车:<b id="">123</b>件</dt>
		<dd class="hidden">
			<p class="alg_c hidden">购物车中还没有商品,赶紧选购吧!</p>
			<h3 title="最新加入的商品">最新加入的商品</h3>
			<ul class="uls">
				<li>
					<a href="#" title="倍力通(Prestone)超级全合成机油5W-40 SM级 4L倍力通(Prestone)超级全合成机油5W-40 SM级 4L"><img src="../res/img/pic/p50x50.jpg" alt="倍力通(Prestone)超级全合成机油5W-40 SM级 4L倍力通(Prestone)超级全合成机油5W-40 SM级 4L" /></a>
					<p class="dt"><a href="#" title="倍力通(Prestone)超级全合成机油5W-40 SM级 4L倍力通(Prestone)超级全合成机油5W-40 SM级 4L">倍力通(Prestone)超级全合成机油5W-40 SM级 4L倍力通(Prestone)超级全合成机油5W-40 SM级 4L</a></p>
					<p class="dd">
						<b><var>¥3599</var><span>x1</span></b>
						<a href="javascript:void(0);" title="删除" class="del">删除</a>
					</p>
				</li>
				<li>
					<a href="#" title="倍力通(Prestone)超级全合成机油5W-40 SM级 4L倍力通(Prestone)超级全合成机油5W-40 SM级 4L"><img src="../res/img/pic/p50x50b.jpg" alt="倍力通(Prestone)超级全合成机油5W-40 SM级 4L倍力通(Prestone)超级全合成机油5W-40 SM级 4L" /></a>
					<p class="dt"><a href="#" title="倍力通(Prestone)超级全合成机油5W-40 SM级 4L倍力通(Prestone)超级全合成机油5W-40 SM级 4L">倍力通(Prestone)超级全合成机油5W-40 SM级 4L倍力通(Prestone)超级全合成机油5W-40 SM级 4L</a></p>
					<p class="dd">
						<b><var>¥3599</var><span>x1</span></b>
						<a href="javascript:void(0);" title="删除" class="del">删除</a>
					</p>
				</li>
				<li>
					<a href="#" title="倍力通(Prestone)超级全合成机油5W-40 SM级 4L倍力通(Prestone)超级全合成机油5W-40 SM级 4L"><img src="../res/img/pic/p50x50c.jpg" alt="倍力通(Prestone)超级全合成机油5W-40 SM级 4L倍力通(Prestone)超级全合成机油5W-40 SM级 4L" /></a>
					<p class="dt"><a href="#" title="倍力通(Prestone)超级全合成机油5W-40 SM级 4L倍力通(Prestone)超级全合成机油5W-40 SM级 4L">倍力通(Prestone)超级全合成机油5W-40 SM级 4L倍力通(Prestone)超级全合成机油5W-40 SM级 4L</a></p>
					<p class="dd">
						<b><var>¥3599</var><span>x1</span></b>
						<a href="javascript:void(0);" title="删除" class="del">删除</a>
					</p>
				</li>
				<li>
					<a href="#" title="倍力通(Prestone)超级全合成机油5W-40 SM级 4L倍力通(Prestone)超级全合成机油5W-40 SM级 4L"><img src="../res/img/pic/p50x50.jpg" alt="倍力通(Prestone)超级全合成机油5W-40 SM级 4L倍力通(Prestone)超级全合成机油5W-40 SM级 4L" /></a>
					<p class="dt"><a href="#" title="倍力通(Prestone)超级全合成机油5W-40 SM级 4L倍力通(Prestone)超级全合成机油5W-40 SM级 4L">倍力通(Prestone)超级全合成机油5W-40 SM级 4L倍力通(Prestone)超级全合成机油5W-40 SM级 4L</a></p>
					<p class="dd">
						<b><var>¥3599</var><span>x1</span></b>
						<a href="javascript:void(0);" title="删除" class="del">删除</a>
					</p>
				</li>
			</ul>
			<div>
				<p>共<b>4</b>件商品    共计<b class="f20">¥3599.00</b></p>
				<a href="#" title="去购物车结算" class="inb btn120x30c">去购物车结算</a>
			</div>
		</dd>
	</dl>

	<p class="r"><a href="index.html" title="商城首页">商城首页</a><samp>></samp><a href="#" title="手机商城">手机商城</a><samp>></samp><a href="#" title="HTC">HTC</a><samp>></samp><span class="gray">HTC A6390</span></p>

</div>

<div class="w ofc mt"> 
	<div class="l wl">

		<h2 class="h2 h2_l"><em title="商品分类">商品分类</em><cite></cite></h2>
		<div class="box bg_gray">
			<ul class="ul left_nav">
				<li><a href="#" title="网上选号"><img src="../res/img/gray/ln01.gif" alt="网上选号" />网上选号</a></li>
				<li><a href="#" title="手机商城"><img src="../res/img/gray/ln02.gif" alt="手机商城" />手机商城</a></li>
				<li><a href="#" title="优惠活动"><img src="../res/img/gray/ln03.gif" alt="优惠活动" />优惠活动</a></li>
			</ul>
		</div>

		<h2 class="h2 h2_l mt"><em title="销量排行榜">销量排行榜</em><cite></cite></h2>
		<div class="box bg_white">
			<ul class="uls x_150x150">
				<li class="here">
					<var class="sfont">1.</var>
					<a href="#" title="张同来" target="_blank" class="pic"><img src="../res/img/pic/p140X140b.png" alt="摩托罗拉XT319" /></a>
					<dl>
						<!-- dt 11个文字+... -->
						<dt><a href="#" title="摩托罗拉XT319" target="_blank">摩托罗拉摩托罗拉托罗拉...</a></dt>
						<!-- dd 23个文字+... -->
						<dd class="h40">摩托罗拉摩托罗拉托罗拉拉摩托罗拉摩托罗拉托罗罗...</dd>
						<dd><span class="gray">抢购价:</span><var class="red b f14">¥3599</var></dd>
					</dl>
				</li>
				<li>
					<var class="sfont">2.</var>
					<a href="#" title="张同来" target="_blank" class="pic"><img src="../res/img/pic/p140X140b.png" alt="摩托罗拉XT319" /></a>
					<dl>
						<dt><a href="#" title="摩托罗拉XT319" target="_blank">摩托罗拉XT319</a></dt>
						<dd class="h40">3G手机(黑)WCDMA/GSM 新品上市!!下单就返</dd>
						<dd><span class="gray">抢购价:</span><var class="red b f14">¥3599</var></dd>
					</dl>
				</li>
				<li>
					<var class="sfont">3.</var>
					<a href="#" title="张同来" target="_blank" class="pic"><img src="../res/img/pic/p140X140b.png" alt="摩托罗拉XT319" /></a>
					<dl>
						<dt><a href="#" title="摩托罗拉XT319" target="_blank">摩托罗拉XT319</a></dt>
						<dd class="h40">3G手机(黑)WCDMA/GSM 新品上市!!下单就返</dd>
						<dd><span class="gray">抢购价:</span><var class="red b f14">¥3599</var></dd>
					</dl>
				</li>
				<li>
					<var class="sfont">4.</var>
					<a href="#" title="张同来" target="_blank" class="pic"><img src="../res/img/pic/p140X140b.png" alt="摩托罗拉XT319" /></a>
					<dl>
						<dt><a href="#" title="摩托罗拉XT319" target="_blank">摩托罗拉XT319</a></dt>
						<dd class="h40">3G手机(黑)WCDMA/GSM 新品上市!!下单就返</dd>
						<dd><span class="gray">抢购价:</span><var class="red b f14">¥3599</var></dd>
					</dl>
				</li>
				<li>
					<var class="sfont">5.</var>
					<a href="#" title="张同来" target="_blank" class="pic"><img src="../res/img/pic/p140X140b.png" alt="摩托罗拉XT319" /></a>
					<dl>
						<dt><a href="#" title="摩托罗拉XT319" target="_blank">摩托罗拉XT319</a></dt>
						<dd class="h40">3G手机(黑)WCDMA/GSM 新品上市!!下单就返</dd>
						<dd><span class="gray">抢购价:</span><var class="red b f14">¥3599</var></dd>
					</dl>
				</li>
				<li>
					<var class="sfont">6.</var>
					<a href="#" title="张同来" target="_blank" class="pic"><img src="../res/img/pic/p140X140b.png" alt="摩托罗拉XT319" /></a>
					<dl>
						<dt><a href="#" title="摩托罗拉XT319" target="_blank">摩托罗拉XT319</a></dt>
						<dd class="h40">3G手机(黑)WCDMA/GSM 新品上市!!下单就返</dd>
						<dd><span class="gray">抢购价:</span><var class="red b f14">¥3599</var></dd>
					</dl>
				</li>
				<li>
					<var class="sfont">7.</var>
					<a href="#" title="张同来" target="_blank" class="pic"><img src="../res/img/pic/p140X140b.png" alt="摩托罗拉XT319" /></a>
					<dl>
						<dt><a href="#" title="摩托罗拉XT319" target="_blank">摩托罗拉XT319</a></dt>
						<dd class="h40">3G手机(黑)WCDMA/GSM 新品上市!!下单就返</dd>
						<dd><span class="gray">抢购价:</span><var class="red b f14">¥3599</var></dd>
					</dl>
				</li>
				<li>
					<var class="sfont">8.</var>
					<a href="#" title="张同来" target="_blank" class="pic"><img src="../res/img/pic/p140X140b.png" alt="摩托罗拉XT319" /></a>
					<dl>
						<dt><a href="#" title="摩托罗拉XT319" target="_blank">摩托罗拉XT319</a></dt>
						<dd class="h40">3G手机(黑)WCDMA/GSM 新品上市!!下单就返</dd>
						<dd><span class="gray">抢购价:</span><var class="red b f14">¥3599</var></dd>
					</dl>
				</li>
				<li>
					<var class="sfont">9.</var>
					<a href="#" title="张同来" target="_blank" class="pic"><img src="../res/img/pic/p140X140b.png" alt="摩托罗拉XT319" /></a>
					<dl>
						<dt><a href="#" title="摩托罗拉XT319" target="_blank">摩托罗拉XT319</a></dt>
						<dd class="h40">3G手机(黑)WCDMA/GSM 新品上市!!下单就返</dd>
						<dd><span class="gray">抢购价:</span><var class="red b f14">¥3599</var></dd>
					</dl>
				</li>
				<li>
					<var class="sfont">10.</var>
					<a href="#" title="张同来" target="_blank" class="pic"><img src="../res/img/pic/p140X140b.png" alt="摩托罗拉XT319" /></a>
					<dl>
						<dt><a href="#" title="摩托罗拉XT319" target="_blank">摩托罗拉XT319</a></dt>
						<dd class="h40">3G手机(黑)WCDMA/GSM 新品上市!!下单就返</dd>
						<dd><span class="gray">抢购价:</span><var class="red b f14">¥3599</var></dd>
					</dl>
				</li>
			</ul>
			<script language="javascript" type="text/javascript">
			$('.x_150x150').each(function(i, items_list){ 
				$(items_list).find('li').hover(function(){
					$(items_list).find('li').each(function(j, li){
						$(li).removeClass('here');
					});
					$(this).addClass('here');
				},function(){});
			});
			</script>
		</div>

		<h2 class="h2 h2_l mt"><em title="我的浏览记录">我的浏览记录</em><cite></cite></h2>
		<div class="box bg_white">
			<ul class="uls x_50x50">
				<li>
					<a href="#" title="张同来" target="_blank" class="pic"><img src="../res/img/pic/p140X140b.png" alt="摩托罗拉XT319" /></a>
					<dl>
						<!-- dt 8个文字+... -->
						<dt><a href="#" title="摩托罗拉XT319" target="_blank">摩托罗拉摩托罗拉拉...</a></dt>
						<dd class="orange">¥3599 ~ ¥4599</dd>
					</dl>
				</li>
				<li>
					<a href="#" title="张同来" target="_blank" class="pic"><img src="../res/img/pic/p140X140b.png" alt="摩托罗拉XT319" /></a>
					<dl>
						<dt><a href="#" title="摩托罗拉XT319" target="_blank">摩托罗拉XT319</a></dt>
						<dd class="orange">¥3599 ~ ¥4599</dd>
					</dl>
				</li>
				<li>
					<a href="#" title="张同来" target="_blank" class="pic"><img src="../res/img/pic/p140X140b.png" alt="摩托罗拉XT319" /></a>
					<dl>
						<dt><a href="#" title="摩托罗拉XT319" target="_blank">摩托罗拉XT319</a></dt>
						<dd class="orange">¥3599 ~ ¥4599</dd>
					</dl>
				</li>
				<li>
					<a href="#" title="张同来" target="_blank" class="pic"><img src="../res/img/pic/p140X140b.png" alt="摩托罗拉XT319" /></a>
					<dl>
						<dt><a href="#" title="摩托罗拉XT319" target="_blank">摩托罗拉XT319</a></dt>
						<dd class="orange">¥3599 ~ ¥4599</dd>
					</dl>
				</li>
				<li>
					<a href="#" title="张同来" target="_blank" class="pic"><img src="../res/img/pic/p140X140b.png" alt="摩托罗拉XT319" /></a>
					<dl>
						<dt><a href="#" title="摩托罗拉XT319" target="_blank">摩托罗拉XT319</a></dt>
						<dd class="orange">¥3599 ~ ¥4599</dd>
					</dl>
				</li>
			</ul>
		</div>

		<div class="ad200x75 mt"><img src="../res/img/pic/ad200x75.jpg" alt="" /></div>

		<div class="ad200x169 mt"><img src="../res/img/pic/ad200x169.jpg" alt="" /></div>

		<div class="ad200x244 mt"><img src="../res/img/pic/ad200x244.jpg" alt="" /></div>

	</div>
	<div class="r wr">
		
		<div class="product">
        	<h2>${item.itemName }<span class="gray f14">${item.promotion }</span></h2>
			<div class="showPro">
				<div class="big"><a id="showImg" class="cloud-zoom" href="${upload }${item.imgSize1}" rel="adjustX:10,adjustY:-1"><img title="optional title display" alt="" src="${upload }${item.imgSize1}"></a></div>
				
				<div class="small">
					<span class="smallL" title="向左"> </span>
					<div class="smallBox">
						<div class="smallList">
							<a class="cloud-zoom-gallery here" title="red" href="${upload }${item.imgSize1}" rel="useZoom: 'showImg', smallImage: '${upload }${item.imgSize1}'"><img alt="thumbnail 1" src="${upload }${item.imgSize1}"></a>
							<a class="cloud-zoom-gallery" title="blue" href="${upload }${item.imgSize1}" rel="useZoom: 'showImg', smallImage: '${upload }${item.imgSize1}'"><img alt="thumbnail 2" src="${upload }${item.imgSize1}"></a>
							<a class="cloud-zoom-gallery" title="blue" href="${upload }${item.imgSize1}" rel="useZoom: 'showImg', smallImage: '${upload }${item.imgSize1}'"><img alt="thumbnail 3" src="${upload }${item.imgSize1}"></a>
							<a class="cloud-zoom-gallery" title="blue" href="${upload }${item.imgSize1}" rel="useZoom: 'showImg', smallImage: '${upload }${item.imgSize1}'"><img alt="thumbnail 4" src="${upload }${item.imgSize1}"></a>
							<a class="cloud-zoom-gallery" title="blue" href="${upload }${item.imgSize1}" rel="useZoom: 'showImg', smallImage: '${upload }${item.imgSize1}'"><img alt="thumbnail 5" src="${upload }${item.imgSize1}"></a>
						</div>
					</div>
					<span class="smallR" title="向右"> </span>
				</div>

				<div class="share mt">
	
					<div id="ecpsShareIcon">
						<div class="iconSmall iconRight">
							<span>分享到:</span><a href="javascript:void(0);" target="_blank" class="sinawb" title="分享到新浪微博"></a><a href="javascript:void(0);" target="_blank" class="qqwb" title="分享到腾讯微博"></a><a href="javascript:void(0);" target="_blank" class="renren" title="分享到人人网"></a><a href="javascript:void(0);" target="_blank" class="qqzone" title="分享到QQ空间"></a><a href="javascript:void(0);" target="_blank" class="sohuwb" title="分享到搜狐微博"></a><a href="javascript:void(0);" class="copy" title="复制链接">复制链接</a>
						</div>
					</div>

				</div>

			</div>

			<form method="post" action="" name="" class="infor">
				<ul class="uls form">
				
				<li><label>移 动 价:</label><span class="word"><b id="skuPrice" class="f14 red mr">¥3999.00</b>(市场价:<del id="marketPrice">¥5789.00</del>)</span></li>
				<li><label>商品编号:</label><span class="word">${item.itemNo }</span></li>
				<li><label>商品评价:</label><span class="word"><span class="val_no val3d4" title="4分">4分</span><var class="blue">(已有17人评价)</var></span></li>
				<li><label>运  费:</label><span class="word">包邮    <a href="javascript:void(0);" class="blue">配送区域</a></span></li>
				<li><label>库  存:</label><span id="isStock" class="word">有货</span></li>
				<li><label>支付方式:</label><div class="pre word p16x16">
					<span title="网银支付" class="bank">网银支付</span>
					<span title="支付宝" class="pay">支付宝</span>
					<span title="手机支付" class="moblie">手机支付</span>
				</div></li>
				</ul>
				
				<div class="box_orange">
					<ul class="uls form">
					<li><label>规  格:</label><div class="pre spec">
						<#list item.skuList as sku> 
							<#if sku_index == 0>
								<a href="javascript:void(0);" skuId="${sku.skuId }" skuPrice="${sku.skuPrice }" marketPrice="${(sku.marketPrice)! }" class="here">
									<#list sku.specList as spec>
										${spec.specValue }
									</#list>
								</a>
							<#else>
								<a href="javascript:void(0);" skuId="${sku.skuId }" skuPrice="${sku.skuPrice }" marketPrice="${(sku.marketPrice)! }">
									<#list sku.specList as spec>
										${spec.specValue }
									</#list>
								</a>
							</#if>
						</#list>
						
					</div></li>
					<li><label>我 要 买:</label><a href="javascript:void(0);" class="inb sub"></a><input readonly type="text" name="" value="1" class="num" size="3" /><a href="javascript:void(0);" class="inb add"></a><em id="sub_add_msg" class="red"></em></li>
					<li class="submit"><input id="buyNow" type="button" value="" class="hand btn138x40" οnclick="buy();"/><input id="addCart" type="button" value="" class="hand btn138x40b" οnclick="addCart()"/><a href="#" title="加入收藏" class="inb fav">加入收藏</a></li>
					
					
					</ul>
				</div>

			

			</form>

		</div>

		<div class="confirm mt">
			<div class="tl"></div><div class="tr"></div>
			<div class="ofc">

				<dl class="dl_msg">
				<dt><b class="f14 blue">营销活动</b><span class="gray">选择营销活动以获得更多优惠。</span></dt>
				<dd>1、全球通50优惠购机 <a href="#" title="title">[查看详情]</a></dd>
				<dd>2、畅想计划 <a href="#" title="title">[查看详情]</a></dd>
				<dd>3、2011全球通88套餐终端营销活动 <a href="#" title="title">[查看详情]</a></dd>
				</dl>

			</div>
			<div class="fl"></div><div class="fr"></div>
		</div>

		<h2 class="h2 h2_ch mt"><em>
			<a href="javascript:void(0);" title="商品描述" rel="#detailTab1" class="here">商品描述</a>
			<a href="javascript:void(0);" title="规格参数" rel="#detailTab2">规格参数</a>
			<a href="javascript:void(0);" title="包装信息" rel="#detailTab3">包装信息</a></em><cite></cite></h2>
		<div class="box bg_white ofc">
		
			<div id="detailTab1" class="detail">

				${(item.itemClob.itemDesc)! }

			</div>
			
			<div id="detailTab2" style="display:none">
						
				<table cellspacing="0" summary="" class="tab tab7">
				<thead>
				<tr>
				<th colspan="2">基本参数</th>
				</tr>     
				</thead>
				<tbody>
				<#list item.paraList as para>
					<tr>
						<th width="15%" class="alg_r">${para.featureName }</th>
						<td>${para.paraValue }</td>
					</tr>
				</#list>
				        
				
				</tbody>
				</table>

			</div>

			<div id="detailTab3" class="detail" style="display:none">

	<pre class="f14">
	商品标配请您以包装清单为准:
	iPhone 4s *1,
	带遥控功能和麦克风的 Apple 耳机 *1,
	Dock Connector to USB 线缆 *1,
	USB 电源转换器 *1,
	SIM 弹出工具 *1,
	包装、说明书、保修卡*1,
	</pre>

			</div>

			<dl class="dl_help">
				<dd>
					本产品全国联保,享受三包服务,质保期为:一年质保<br />
					如因质量问题或故障,凭厂商维修中心或特约维修点的质量检测证明,享受7日内退货,15日内换货,15日以上在质保期内享受免费保修等三包服务!<br />
					售后服务电话:<var class="blue">400-830-8300</var><br />
					品牌官方网站:<var class="blue">http://www.huawei.com/cn/</var>
				</dd>
				<dt>服务承诺:</dt>
				<dd>
					中国移动手机购商城向您保证所售商品均为正品行货,自带机打发票,与商品一起寄送。凭质保证书及中国移动手机购商城发票,可享受全国联保服务,与您亲临商场选购的商品享受相同的质量保证。<br />
					中国移动手机购商城还为您提供具有竞争力的商品价格和运费政策,请您放心购买!(钟表除外)<br />
					<span class="blue"><b>注:</b>因厂家会在没有任何提前通知的情况下更改产品包装、产地或者一些附件,本司不能确保客户收到的货物与商城图片、产地、附件说明完全一致。只能确保为原厂正货!并且保证与当时市场上同样主流新品一致。若本商城没有及时更新,请大家谅解!</span><br />
				</dd>
				<dt class="red">权利声明:</dt>
				<dd>中国移动手机购商城上的所有商品信息、客户评价、商品咨询、网友讨论等内容,是中国移动手机购商城重要的经营资源,未经许可,禁止非法转载使用。</dd>
			</dl>

		</div>

	</div>
</div>

<div class="mode">
	<div class="tl"></div><div class="tr"></div>
	<ul class="uls">
		<li class="first">
			<span class="guide"></span>
			<dl>
			<dt title="购物指南">购物指南</dt>
			<dd><a href="#" title="在线购机/预约购机流程">在线购机/预约购机流程</a></dd>
			<dd><a href="#" target="_blank" title="预约选号流程">预约选号流程</a></dd>
			</dl>
		</li>
		<li>
			<span class="way"></span>
			<dl>
			<dt title="支付方式">支付方式</dt>
			<dd><a href="#" title="在线支付">在线支付</a></dd>
			<dd><a href="#" title="退款周期">退款周期</a></dd>
			</dl>
		</li>
		<li>
			<span class="help"></span>
			<dl>
			<dt title="配送方式">配送方式</dt>
			<dd><a href="#" title="配送说明">配送说明</a></dd>
			<dd><a href="#" title="配送时间">配送时间</a></dd>
			<dd><a href="#" title="配送费用">配送费用</a></dd>
			<dd><a href="#" title="货品签收">货品签收</a></dd>
			</dl>
		</li>
		<li>
			<span class="service"></span>
			<dl>
			<dt title="售后服务">售后服务</dt>
			<dd><a href="#" target="_blank" title="退换货流程">退换货流程</a></dd>
			<dd><a href="#" target="_blank" title="售后服务点">售后服务点</a></dd>
			</dl>
		</li>
		<li>
			<span class="problem"></span>
			<dl>
			<dt title="常见问题">常见问题</dt>
			<dd><a href="#" target="_blank" title="配送时限是几天?">配送时限是几天?</a></dd>
			<dd><a href="#" target="_blank"title="付款方式有哪些?">付款方式有哪些?</a></dd>
			<dd><a href="#" target="_blank"title="如何签收商品?">如何签收商品?</a></dd>
			<dd><a href="#" target="_blank"title="是否提供三包售后?">是否提供三包售后?</a></dd>
			</dl>
		</li>
	</ul>
</div>

<div class="w footer">
	<p><a href="#" title="新闻公告">新闻公告</a><samp>|</samp><a href="#" title="法律声明">法律声明</a><samp>|</samp><a href="#" title="诚招英才">诚招英才</a><samp>|</samp><a href="#" title="联系我们">联系我们</a><samp>|</samp><a href="#" title="采购信息">采购信息</a><samp>|</samp><a href="#" title="企业合作">企业合作</a><samp>|</samp><a href="#" title="站点导航">站点导航</a><samp>|</samp><a href="#" title="网站地图">网站地图</a></p>
	<p>掌上营业厅:<a href="#" title="掌上营业厅:wap.10086.cn">wap.10086.cn</a>  语音自助服务:10086  短信营业厅:10086  <a href="http://www.bj.10086.cn/index/10086/channel/index.shtml">自助终端网点查询</a>  <a href="http://www.bj.10086.cn/index/10086/channel/index.shtml">满意100营业厅网点查询</a>  <a href="http://www.bj.10086.cn/index/10086/download/index.shtml">手机客户端下载</a></p>
	<p><a href="#" title="京ICP备05002571" class="inb i18x22"></a> 京ICP备05002571<samp>|</samp>中国移动通信集团 版权所有</p>
</div>

<div id="loginAlert" class="alt login" style="display:none">
	<h2 class="h2"><em title="登录">登录</em><cite></cite></h2>
	<a href="javascript:void(0);" id="loginAlertClose" class="close" title="关闭"></a>
	<div class="cont">
		<ul class="uls form">
		<li id="loginAlertError" class="errorTip" style="display:none"></li>
		<li>
			<label>帐号类型:</label>
			<dl class="bg_text" style="z-index:3">
				<dd class="hidden">
					<a href="javascript:void(0);" title="手机号码">手机号码</a>
					<a href="javascript:void(0);" title="用户名">用户名</a>
				</dd>
				<dt title="请选择帐号类型">请选择帐号类型</dt>
			</dl>
		</li>
		<li>
			<label>手机号码:</label>
			<span class="bg_text">
				<input type="text" maxlength="50" vld="{required:true}" name="loginUserName" id="loginUserName" reg1="^\w+((-\w+)|(\.\w+))*\@[A-Za-z0-9]+((\.|-)[A-Za-z0-9]+)*\.[A-Za-z0-9]+$" desc="用户名长度不超过50个,必须是邮箱格式!" />
				<em id="userNameLabel" class="def">请输入手机号码</em>
			</span>
			<span class="word"><a title="免费注册" href="/ecps-portal/ecps/portal/register.do">免费注册</a></span>
		</li>
		<li>
			<label>登录模式:</label>
			<dl class="bg_text" style="z-index:2">
				<dd class="hidden">
					<a href="javascript:void(0);" title="服务密码">服务密码</a>
					<a href="javascript:void(0);" title="网站密码">网站密码</a>
				</dd>
				<dt title="请选择帐号类型">请选择登录模式</dt>
			</dl>
		</li>
		<li><label>服务密码:</label>
			<span class="bg_text"><input type="password" vld="{required:true}" maxlength="20" name="loginPassword" id="loginPassword" value="" reg1="^.{6,20}$" desc="密码长度范围为6-20,允许为中英文、数字或特殊字符!" /></span>
		</li>
		<li>
			<label for="captcha">验 证 码:</label>
			<span class="bg_text small"><input type="text" vld="{required:true}" maxlength="7" name="loginCaptcha" id="loginCaptcha" value="" reg1="^\w{6}$" desc="验证码不正确" /></span>
			<img alt="换一张" id="loginCaptchaCode" class="code" οnclick="this.src='/ecps-portal/captcha.svl?d='+new Date().getTime();" src="../res/img/pic/code.png" /><a href="#" οnclick="document.getElementById('loginCaptchaCode').src='/ecps-portal/captcha.svl?d='+new Date().getTime();" title="换一张">换一张</a>
		</li>
		<li class="gray"><label> </label><input type="checkbox" name="">记住我的手机号码</li>
		<li><label> </label><input type="button" id="loginSubmit" class="hand btn66x23" value="登 录" οnclick="loginAjax('/ecps-portal/ecps/portal/item/landingAjax.do');" ><a title="忘记密码?" href="/ecps-portal/ecps/portal/getpwd/getpwd1.do">忘记密码?</a></li>
		<!--li class="alg_c dev gray">还不是移动商城会员?<a title="免费注册" href="/ecps-portal/ecps/portal/register.do">免费注册</a></li-->
		</ul>
	</div>
</div>

<div id="promptAlert" class="alt prompt" style="display:none">
	<h2 class="h2"><em title="提示">提示</em><cite></cite></h2>
	<a href="javascript:void(0);" id="promptAlertClose" class="close" title="关闭"></a>
	<div class="cont">
		<dl class="dl_msg">
			<dt>请在新页面完成支付!</dt>
			<dd>支付完成前请不要关闭此窗口,<br />完成支付后请根据您的情况点击下面的按钮。</dd>
			<dd><a href="#" title="遇到付款问题" class="inb btn96x23 mr20">遇到付款问题</a><a href="#" title="已完成支付" class="inb btn96x23">已完成支付</a></dd>
			<dd class="alg_r"><a href="#" title="返回选择其他支付方式">返回选择其他支付方式>></a></dd>
		</dl>
	</div>
</div>

<div id="transitAlert" class="alt transit" style="display:none">
	<h2 class="h2"><em title="提示">提示</em><cite></cite></h2>
	<a href="javascript:void(0);" id="transitAlertClose" class="close" title="关闭"></a>
	<div class="cont">
		<div class="warningMsg">
			<p class="indent">您即将访问的网站不属于中国移动通信集团公司门户网站站群范围,任何通过使用中国移动通信集团公司门户网站站群链接到的第三方页面均系第三方平台制作或提供,您可能从该第三方网页上获得资讯及享用服务,中国移动通信集团公司对其合法性概不负责,也不承担任何法律责任。</p>
			<p class="alg_c"><input type="button" class="hand btn66x23" value="确 定" /></p>
		</div>
	</div>
</div>

</body>
</html>

top1.ftl

<h1>欢迎${username}</h1>
package com.rl.test;

import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import org.junit.Before;
import org.junit.Test;

import cn.itcast.freemarker.model.User;
import cn.itcast.util.FMutil;

public class FMTest {
	
	FMutil fm;
	Map<String, Object> map ;

	@Before
	public void setUp() throws Exception {
		fm = new FMutil();
		map = new HashMap<String, Object>();
	}

	//静态页面生成 zhangsan
	@Test
	public void test1() throws Exception {
		map.put("username", "zhangsan");
		fm.ouputFile("fm1.ftl", "fm1.html", map);
	}
	@Test
	public void test2() throws Exception {
		map.put("username", "zhangsan");
		fm.ouputFile("fm2.ftl", "fm2.html", map);
	}
	
	@Test
	public void test3() throws Exception {
		User user = new User();
		user.setId(1);
		user.setName("dalang");
		user.setAge(30);
		
		map.put("user", user);
		fm.ouputFile("fm3.ftl", "fm3.html", map);
	}
	
	@Test
	public void test4() throws Exception {
		List<User> userList = new ArrayList<User>();
		for(int i = 0 ; i < 10; i++){
			User user = new User();
			user.setId(1+i);
			user.setName("dalang");
			user.setAge(13+i);
			userList.add(user);
		}
		map.put("userList", userList);
		fm.ouputFile("fm4.ftl", "fm4.html", map);
	}
	
	@Test
	public void test5() throws Exception {
		List<User> userList = new ArrayList<User>();
		for(int i = 0 ; i < 10; i++){
			User user = new User();
			user.setId(1+i);
			user.setName("dalang");
			user.setAge(13+i);
			userList.add(user);
		}
		map.put("userList", userList);
		map.put("username", "西门庆");
		fm.ouputFile("fm5.ftl", "fm5.html", map);
	}
	
	@Test
	public void test6() throws Exception {
		User user = new User();
		user.setId(1);
		user.setName("dalang");
		user.setAge(13);
		map.put("user", user);
		fm.ouputFile("fm6.ftl", "fm6.html", map);
	}
	@Test
	public void test7() throws Exception {
		map.put("now", new Date());
		fm.ouputFile("fm7.ftl", "fm7.html", map);
	}

}
pom.xml

<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
  <modelVersion>4.0.0</modelVersion>

  <groupId>org.konghao.freemarker</groupId>
  <artifactId>freemarker-hello</artifactId>
  <version>0.0.1-SNAPSHOT</version>
  <packaging>jar</packaging>

  <name>freemarker-hello</name>
  <url>http://maven.apache.org</url>

  <properties>
    <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
  </properties>

  <dependencies>
    <dependency>
      <groupId>junit</groupId>
      <artifactId>junit</artifactId>
      <version>4.7</version>
      <scope>test</scope>
    </dependency>
    <dependency>
	  <groupId>org.freemarker</groupId>
	  <artifactId>freemarker</artifactId>
	  <version>2.3.19</version>
	</dependency>
  </dependencies>
</project>


  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
JAVA模版引擎Freemarker常用标签(一) 1. if指令 这是一个典型的分支控制指令,该指令的作用完全类似于Java语言中的if,if指令的语法格式如下: <#if condition>... <#elseif condition>... <#elseif condition>... <#else> ... </#if> 例子如下: <#assign age=23> <#if (age>60)>老年人 <#elseif (age>40)>中年人 <#elseif (age>20)>青年人 <#else> 少年人 </#if> 输出结果是:青年人 上面的代码中的逻辑表达式用括号括起来主要是因为里面有>符号,由于FreeMarker会将>符号当成标签的结束字符,可能导致程序出错,为了避免这种情况,我们应该在凡是出现这些符号的地方都使用括号. <#if animals.python.price < animals.elephant.price> Pythons are cheaper than elephants today. <#else> Pythons are not cheaper than elephants today. </#if> 2、 switch , case , default , break指令 这些指令显然是分支指令,作用类似于Java的switch语句,switch指令的语法结构如下: <#switch value> <#case refValue>...<#break> <#case refValue>...<#break> <#default>... </#switch> 3、 list, break指令 list指令是一个迭代输出指令,用于迭代输出数据模型中的集合,list指令的语法格式如下: <#list sequence as item> ... </#list> 上面的语法格式中,sequence就是一个集合对象,也可以是一个表达式,但该表达式将返回一个集合对象,而item是一个任意的名字,就是被迭代输出的集合元素.此外,迭代集合对象时,还包含两个特殊的循环变量: item_index:当前变量的索引值 item_has_next:是否存在下一个对象 也可以使用<#break>指令跳出迭代 例子如下: <#list ["星期一", "星期二", "星期三", "星期四", "星期五", "星期六", "星期天"] as x> ${x_index + 1}.${x}<#if x_has_next>,</if> <#if x="星期四"><#break></#if> </#list> <p>We have these animals: <table border=1> <tr><th>Name<th>Price <#list animals as being> <tr><td>${being.name}<td>${being.price} Euros </#list> </table> 输出为: <p>We have these animals: <table border=1> <tr><th>Name<th>Price <tr><td>mouse<td>50 Euros <tr><td>elephant<td>5000 Euros <tr><td>python<td>4999 Euros </table> 4、include指令 include指令的作用类似于JSP的包含指令,用于包含指定页.include指令的语法格式如下: <#include filename [options]> 在上面的语法格式中,两个参数的解释如下: filename:该参数指定被包含的模板文件 options:该参数可以省略,指定包含时的选项,包含encoding和parse两个选项,其中encoding指定包含页面时所用的解码集,而parse指定被包含文件是否作为FTL文件来解析,如果省略了parse选项值,则该选项默认是true. <html> <head> <title>Test page</title> </head> <body> <h1>Test page</h1> <p>Blah blah... <#include "/copyright_footer.html"> </body> </html> 5、 import指令 该指令用于导入FreeMarker模板中的所有变量,并将该变量放置在指定的Map对象中,import指令的语法格式如下: <#import "/lib/common.ftl" as com> 上面的代码将导入/lib/common.ftl模板文件中的所有变量,将这些变量放置在一个名为com的Map对象中. 创建库 ? 下面是一个创建库的例子(假设保存在lib/my_test.ftl中): <#macro copyright date> <p>Copyright (C) ${date} Julia Smith. All rights reserved. <br>Email: ${mail}</p> </#macro> <#assign mail = "jsmith@acme.com"> ? 使用import指令导入库到模板中,Freemarker会为导入的库创建新的名字空间,并可以通过import指令中指定的散列变量访问库中的变量: <#import "/lib/my_test.ftl" as my> <#assign mail="fred@acme.com"> <@my.copyrightdate="1999-2002"/> ${my.mail} ${mail} 输出结果: <p>Copyright (C) 1999-2002 Julia Smith. All rights reserved. <br>Email: jsmith@acme.com</p> jsmith@acme.com fred@acme.com 可以看到例子中使用的两个同名变量并没有冲突,因为它们位于不同的名字空间 l 可以使用assign指令在导入的名字空间中创建或替代变量,下面是一个例子: <#import "/lib/my_test.ftl" as my> ${my.mail} <#assign mail="jsmith@other.com" in my> ${my.mail} l 输出结果: jsmith@acme.com jsmith@other.com l 数据模型中的变量任何地方都可见,也包括不同的名字空间,下面是修改的库: <#macro copyright date> <p>Copyright (C) ${date} ${user}. All rights reserved.</p> </#macro> <#assign mail = "${user}@acme.com"> l 假设数据模型中的user变量的值是Fred,则下面的代码: <#import "/lib/my_test.ftl" as my> <@my.copyright date="1999-2002"/> ${my.mail} l 输出结果: <p>Copyright (C) 1999-2002 Fred. All rights reserved.</p> 1.6 算术运算符 FreeMarker表达式中完全支持算术运算,FreeMarker支持的算术运算符包括:+, - , * , / , % 看如下的代码: <#assign x=5> ${ x * x - 100 } ${ x /2 } ${ 12 } 输出结果是: -75 2.5 2 在表达式中使用算术运算符时要注意以下几点: 1,运算符两边的运算数字必须是数字 2,使用+运算符时,如果一边是数字,一边是字符串,就会自动将数字转换为字符串再连接,如:${3 + "5"},结果是:35 使用内建的int函数可对数值取整,如: <#assign x=5> ${ (x/2)?int } ${ 1.1?int } ${ 1.999?int } ${ -1.1?int } ${ -1.999?int } 结果是:2 1 1 -1 -1 1.7 比较运算符 表达式中支持的比较运算符有如下几个: 1. =或者==:判断两个值是否相等. 2. !=:判断两个值是否不等. 3. >或者gt:判断左边值是否大于右边值 4. >=或者gte:判断左边值是否大于等于右边值 5. <或者lt:判断左边值是否小于右边值 6. <=或者lte:判断左边值是否小于等于右边值 注意:=和!=可以用于字符串,数值和日期来比较是否相等,但=和!=两边必须是相同类型的值,否则会产生错误,而且FreeMarker是精确比 较,"x","x ","X"是不等的.其它的运行符可以作用于数字和日期,但不能作用于字符串,大部分的时候,使用gt等字母运算符代替>会有更好的效果,因为 FreeMarker会把>解释成FTL标签的结束字符,当然,也可以使用括号来避免这种情况,如:<#if (x>y)> 1.8 逻辑运算符 逻辑运算符有如下几个: 逻辑与:&& 逻辑或:|| 逻辑非:! 逻辑运算符只能作用于布尔值,否则将产生错误 1.9 内建函数 FreeMarker还提供了一些内建函数来转换输出,可以在任何变量后紧跟?,?后紧跟内建函数,就可以通过内建函数来轮换输出变量.下面是常用的内建的字符串函数: html:对字符串进行HTML编码 cap_first:使字符串第一个字母大写 lower_case:将字符串转换成小写 upper_case:将字符串转换成大写 trim:去掉字符串前后的空白字符 下面是集合的常用内建函数 size:获取序列中元素的个数 下面是数字值的常用内建函数 int:取得数字的整数部分,结果带符号 例如: <#assign test="Tom & Jerry"> ${test?html} ${test?upper_case?html} 结果是:Tom & Jerry TOM & JERRY 1.10 空值处理运算符 FreeMarker对空值的处理非常严格,FreeMarker的变量必须有值,没有被赋值的变量就会抛出异常,因为FreeMarker未赋值 的变量强制出错可以杜绝很多潜在的错误,如缺失潜在的变量命名,或者其他变量错误.这里所说的空值,实际上也包括那些并不存在的变量,对于一个Java的 null值而言,我们认为这个变量是存在的,只是它的值为null,但对于FreeMarker模板而言,它无法理解null值,null值和不存在的变 量完全相同. 为了处理缺失变量,FreeMarker提供了两个运算符: !: 指定缺失变量的默认值 ??: 判断某个变量是否存在 其中,!运算符的用法有如下两种: variable!或variable!defaultValue,第一种用法不给缺失的变量指定默认值,表明默认值是空字符串,长度为0的集合,或者长度为0的Map对象. 使用!指定默认值时,并不要求默认值的类型和变量类型相同.使用??运算符非常简单,它总是返回一个布尔值,用法为:variable??,如果该变量存在,返回true,否则返回false ########################### 最常用的概念 1、 scalars:存储单值 字符串:简单文本由单或双引号括起来。 数字:直接使用数值。 日期:通常从数据模型获得 布尔值:true或false,通常在<#if …>标记中使用 2、 hashes:充当其它对象的容器,每个都关联一个唯一的查询名字 具有一个唯一的查询名字和他包含的每个变量相关联。 3、 sequences:充当其它对象的容器,按次序访问 使用数字和他包含的每个变量相关联。索引值从0开始。 4、 集合变量: 除了无法访问它的大小和不能使用索引来获得它的子变量:集合可以看作只能由<#list...>指令使用的受限sequences。 5、 方法:通过传递的参数进行计算,以新对象返回结果 方法变量通常是基于给出的参数计算值在数据模型中定义。 6、 用户自定义FTL指令:宏和变换器 7、 节点 节点变量表示为树型结构中的一个节点,通常在XML处理中使用。 在模板里对sequences和hashes初始化 sequences 1. [“you”,”me”,”he”] 2. 1..100 3. [ {“Akey”:”Avalue”},{“Akey1”:”Avalue1”}, {“Bkey”:”Bvalue”},{“Bkey1”:”Bvalue1”}, ] hashes {“you”:”a”,”me”:”b”,”he”:”c”} 注释标志 <#-- 这里是注释 --> 旧版本的freemarker采用的是<#comment> 注释 </#comment>方法 sequences内置方法 sequence?first 返回sequence的第一个值;前提条件sequence不能是null sequence?last 返回sequence最后一个值 sequence?reverse 反转sequence的值 sequence?size 返回sequence的大小 sequence?sort 对sequence按里面的对象toString()的结果进行排序 sequence?sort_by(value) 对sequence 按里面的对象的属性value进行排序 如: sequence里面放入的是10 个user对象,user对象里面包含name,age等属性 sequence?sort_by(name) 表示所有的user按user.name进行排序 hashes内置方法 hash?keys 返回hash里的所有keys, 返回结果类型sequence hash?values 返回hash里的所有value, 返回结果类型sequence 模板 使用FTL(freeMarker模板语言)编写 组成部分 一、整体结构 1、注释:<#--注释内容-->,不会输出。 2、文本:直接输出。 3、interpolation:由 ${var} 或 #{var} 限定,由计算值代替输出。 4、FTL标记 二.表达式 1、直接指定值: 1-1、字符串: 由双引号或单引号括起来的字符串,其中的特殊字符(如' " \等)需要转义。 1-2、raw字符串: 有一种特殊的字符串称为raw字符串,被认为是纯文本,其中的\和{等不具有特殊含义,该类字符串在引号前面加r,下面是一个例子: ${r"/${data}"year""}屏幕输出结果为:/${data}"year" 转义 含义 序列 \" 双引号(u0022) \' 单引号(u0027) \\ 反斜杠(u005C) \n 换行(u000A) \r Return (u000D) \t Tab (u0009) \b Backspace (u0008) \f Form feed (u000C) \l < \g > \a & \{ { \xCode 4位16进制Unicode代码 1-3、数字:直接输入,不需要引号 1)、精度数字使用“.”分隔,不能使用分组符号 2)、目前版本不支持科学计数法,所以“1E3”是错误的 3)、不能省略小数点前面的0,所以“.5”是错误的 4)、数字8、+8、08和8.00都是相同的 1-4、布尔值:true和false,不使用引号 1-5、序列:由逗号分隔的子变量列表,由[]方括号限定。 1)、子变量列表可以是表达式 2)、可以使用数字范围定义数字序列,不需要方括号限定,例如2..5等同于[2, 3, 4, 5],但是更有效率,可以定义反递增范围如:5..2。 1-6、散列(hash) 1)、由逗号分隔的键/值列表,由{}大括号限定,键和值之间用冒号分隔,如:{"key1":valu1,"key2":"character string"....} 2)、键和值都是表达式,但是键必须是字符串。 2、获取变量: 2-1、顶层变量:${变量名} 变量名只能是字母、数字、下划线、$、#、@ 的组合,且不能以数字开头。 2-2、散列:有两种方法 1)、点语法:变量名字和顶层变量的名字受同样的限制 2)、方括号语法:变量名字无限制,可以是任意的表达式的结果 book.author.name book.author.["name"] book["author"].name book["author"]["name"] 以上是等价的。 2-3、序列:使用散列的方括号语法获取变量,方括号中的表达式结果必须为数字。注意:第一个项目的索引为0。可以使用 [startindex..endindex]语法获取序列片段。 2-4、特殊变量:FreeMarker内定义变量,使用.variablename语法访问。 3、字符串操作 3-1、interpolation:使用${}或#{}在文本部分插入表达式的值,例如: ${"hello${username}!"} ${"${username}${username}${username}"} 也可以使用+来获得同样的结果: ${"hello"+username+"!"} ${username+username+username} 注意:${}只能用于文本部分而不能出现于标记内。 <#if ${user.login}>或<#if "${user.login}">都是错误的; <#if user.login>是正确的。 本例中user.login的值必须是布尔类型。 3-2、子串: 举例说明:假如user的值为"Big Joe" ${user[0]}${user[4]}结果是:BJ ${user[1..4]}结果是:ig J 4、序列操作 4-1、连接操作:可以使用+来操作,例如: ["title","author"]+["month","day"] 5、散列操作 5-1、连接操作:可以使用+来操作,如果有相同的KEY,则右边的值会替代左边的值,例如: {"title":散列,"author":"emma"}+{"month":5,"day":5}+{"month":6}结果month的值就是6。 6、算术运算 6-1、操作符:+、-、*、/、% 除+号以外的其他操作符两边的数据,必须都是数字类型。 如果+号操作符一边有一个字符型数据,会自动将另一边的数据转换为字符型数据,运算结果为字符型数据。 6-2、比较操作符: 1}、= 2}、== 3}、!= 4}、< 5}、<= 6}、> 7}、>= 1-3的操作符,两边的数据类型必须相同,否则会产生错误 4-7的操作符,对于日期和数字可以使用,字符串不可以使用。 注意: 1}、FreeMarker是精确比较,所以"x" "x " "X"是不等的。 2}、因为<和>对FTL来说是开始和结束标记,所以,可以用两种方法来避免这种情况: 一种是使用括号<#if (a<b)> 另一是使用替代输出,对应如下: < lt <= lte > gt >= gte 6-3、逻辑操作符:只能用于布尔值,否则会出现错误。 &&(and)与运算 ||(or)或运算 !(not)非运算 6-4、内建函数:使用方法类似于访问散列的子变量,只是使用?代替.例如:${test?upper_case?html} 常用的内建函数列举如下: 1}、字符串使用: html:对字符串进行HTML编码 cap_first:字符串第一个字母大写 lower_first:字符串第一个字母小写 upper_case:将字符串转换成大写 trim:去掉字符前后的空白字符 2)、序列使用: size:获得序列中元素的数目 3)、数字使用: int:取得数字的整数部分 7、操作符的优先顺序: 后缀:[subbarName][subStringRange].(mathodParams) 一元:+expr、-expr、! (not) 内建:? 乘法:*、/、% 加法:+、- 关系:<、<=、>、>= (lt、lte、gt、gte) 相等:=、==、!= 逻辑与:&& (and) 逻辑或:|| (or) 数字范围:.. 四、interpolation inperpolation只能用于文本,有两种类型:通用interpolation及数字interpolation 1、通用interpolation 如${expr} 1-1、插入字符串值:直接输出表达式结果。 1-2、插入数字值:根据缺省格式(由setting指令设置)将表达式结果转换成文本输出;可以使用内建函数string来格式化单个interpolation 如: <#setting number_format="currency" /> <#assign answer=42 /> ${answer} <#-- ¥42.00 --> ${answer?string} <#-- ¥42.00 --> ${answer?string.number} <#-- 42 --> ${answer?string.currency} <#-- ¥42.00 --> ${answer?string.percent} <#-- 42,00% --> 1-3、插入日期值:根据缺省格式(由setting指令设置)将表达式结果转换成文本输出;可以使用内建函数string来格式化单个interpolation 如: ${lastupdata?string("yyyy-MM-dd HH:mm:ss zzzz")} <#-- 2003-04-08 21:24:44 Pacific Daylight Time --> ${lastupdata?string("EEE,MMM d, ''yy")} <#-- tue,Apr 8, '03 --> ${lastupdata?string("EEEE,MMMM dd, yyyy,hh:mm:ss a '('zzz')'")} <#-- Tuesday,April 08, 2003, 09:24:44 PM (PDT)--> 1-4、插入布尔值:根据缺省格式(由setting指令设置)将表达式结果转换成文本输出;可以使用内建函数string来格式化单个interpolation 如: <#assign foo=ture /> ${foo?string("yes","no")} <#-- yes --> 2、数字interpolation: 有两种形式: 1)、#{expr} 2)、#{expr;format}:format可以用来格式化数字,format可以是如下: mX:小数部分最小X位 MX:小数部分最大X位 例如: <#assign x=2.582 /> <#assign y=4 /> #{x;M2} <#-- 2.58 --> #{y;M2} <#-- 4 --> #{x;m1} <#-- 2.582 --> #{y;m1} <#-- 4.0 --> #{x;m1M2} <#-- 2.58 --> #{y;m1M2} <#-- 4.0 --> 宏 宏和变换器变量是两种不同类型的用户自定义指令,他们的区别是: 宏可以在模板中用macro指令来定义 变换器是在模板外由程序定义 1、宏:和某个变量关联的模板片段,以便在模板中通过用户自定义指令使用该变量 1-1、基本用法: 例如: <#macro greet> <font size="+2"> Hello JOE! </#macro> 使用时: <@greet></@greet> 如果没有体内容也可以用 <@greet /> 1-2、变量: 1)、可以在宏定义之后定义参数,宏参数是局部变量,只在宏定义中有效。如: <#macro greet person> <font size="+2"> Hello ${person}! </#macro> 使用时: <@greet person="emma"> and <@greet person="LEO"> 输出为: <font size="+2"> Hello emma! <font size="+2"> Hello LEO! 注意:宏的参数是FTL表达式,所以,person=emma和上面的例子中具有不同的意义,这意味着将变量emma的值传给person,这个值可能是任意一种数据类型,甚至是一个复杂的表达式。 宏可以有多个参数,使用时参数的次序是无关的,但是只能使用宏中定义的参数,并且对所有参数赋值。如: <#macro greet person color> <font size="+2" color="${color}"> Hello ${person}! </#macro> 使用时: <@greet color="black" person="emma" />正确 <@greet person="emma" />错误,color没有赋值,此时,如果在定义宏时为color定义缺省值<#macro greet person color="black">这样的话,这个使用方法就是正确的。 <@greet color="black" person="emma" bgcolor="yellow" />错误,宏greet定义中未指定bgcolor这个参数 2、嵌套内容: 2-1、自定义指令可以有嵌套内容,使用<#nested>指令,执行自定义指令开始和结束标记之间的模板片段。例如: <#macro greet> <#nested> </#macro> <@greet>hello Emma!</@greet> 输出为 hello Emma! 2-2、<#nested>指令可以被多次调用,例如 <#macro greet> <#nested> <#nested> <#nested> <#nested> </#macro> <@greet>hello Emma!</@greet> 输出为 hello Emma! hello Emma! hello Emma! hello Emma! 2-3、嵌套的内容可以是有效的FTL,例如: <#macro welcome> <#nested> </#macro> <#macro greet person color="black"> <font size="+2" color="${color}"> Hello ${person}! </#macro> <@welcome> <@greet person="Emma" color="red" /> <@greet person="Andrew" /> <@greet person="Peter" /> </@welcome> 输出为: <font size="+2" color="red"> Hello Emma! <font size="+2" color="black"> Hello Andrew! <font size="+2" color="black"> Hello Peter! 2-4、宏定义中的局部变量对嵌套内容是不可见的,例如: <#macro repeat count> <#local y="test" /> <#list 1..count as x> ${y}${count}/${x}:<#nested /> </#list> </#macro> <@repeat count=3> ${y?default("?")} ${x?default("?")} ${count?default("?")} </@repeat> 输出结果为 test 3/1:??? test 3/2:??? test 3/3:??? 2-5、在宏定义中使用循环变量,通常用来重复嵌套内容,基本用法为:作为nested指令的参数,传递循环变量的实际值,而在调用自定义指令时,在标记的参数后面指定循环变量的名字。 例如: <#macro repeat count> <#list 1..count as x> <#nested x,x/2,x==count /> </#list> </#macro> <@repeat count=4;c,halfc,last> ${c}. ${halfc} <#if last> last! </#if> </@repeat> 输出结果是 1. 0.5 2. 1 3. 1.5 4. 2last! 注意:指定循环变量的数目和用户定义指令开始标记指定的不同不会有问题 调用时,少指定循环变量,多指定的值会不见 调用时,多指定循环变量,多余的循环变量不会被创建 二、在模板中定义变量 1、在模板中定义的变量有三种类型 1-1、plain变量:可以在模板的任何地方访问,包括使用include指令插入的模板,使用assign指令创建和替换。 1-2、局部变量:在宏定义体中有效,使用local指令创建和替换。 1-3、循环变量:只能存在于指令的嵌套内容,由指令(如list)自动创建。 注意: 1)、宏的参数是局部变量,不是循环变量。 2)、局部变量隐藏同名的plain变量 3)、循环变量隐藏同名的plain变量和局部变量。 例如: <#assign x="plain"> 1. ${x} <#-- plain --> <@test /> 6. ${x} <#list ["loop"] as x> 7. ${x} <#-- loop --> <#assign x="plain2"> 8. ${x} <#-- loop --> </#list> 9. ${x} <#-- plain2 --> <#macro test> 2. ${x} <#-- plain --> <#local x="local"> 3. ${x} <#-- local --> <#list ["loop"] as x> 4. ${x} <#-- loop --> </#list> 5. ${x} <#-- local --> </#macro> 4)、内部循环变量隐藏同名的外部循环变量 <#list ["loop1"] as x> ${x} <#-- loop1 --> <#list ["loop2"] as x> ${x} <#-- loop2 --> <#list ["loop3"] as x> ${x} <#-- loop3 --> </#list> ${x} <#-- loop2 --> </#list> ${x} <#-- loop1 --> </#list> 5)、模板中的变量会隐藏数据模型中的同名变量,如果需访问数据模型中的变量,使用特殊变量global。 例如: 假设数据模型中的user值为Emma <#assign user="Man"> ${user} <#-- Man --> ${.global.user} <#-- Emma --> macro, nested, return 语法 <#macro name param1 param2 ... paramN> ... <#nested loopvar1, loopvar2, ..., loopvarN> ... <#return> ... </#macro> 用例 <#macro test foo bar="Bar"[A1] baaz=-1> Test text, and the params: ${foo}, ${bar}, ${baaz} </#macro> <@test foo="a" bar="b" baaz=5*5-2/> <@test foo="a" bar="b"/> <@test foo="a" baaz=5*5-2/> <@test foo="a"/> 输出 Test text, and the params: a, b, 23 Test text, and the params: a, b, -1 Test text, and the params: a, Bar, 23 Test text, and the params: a, Bar, -1 定义循环输出的宏 <#macro list title items> ${title?cap_first}: <ul> <#list items as x> <li>${x?cap_first} </#list> </#macro> <@list items=["mouse", "elephant", "python"] title="Animals"/> 输出结果 Animals: 包含body的宏 <#macro repeat count> <#list 1..count as x> <#nested x, x/2, x==count> </#list> </#macro> <@repeat count=4 ; c halfc last> ${c}. ${halfc} <#if last> Last!</#if> </@repeat> 输出 1. 0.5 2. 1 3. 1.5 4. 2 Last! t, lt, rt 语法 <#t> 去掉左右空白和回车换行 <#lt>去掉左边空白和回车换行 <#rt>去掉右边空白和回车换行 <#nt>取消上面的效果 B指令 freemarker指令有两种: 1、预定义指令:引用方式为<#指令名称> 2、用户定义指令:引用方式为<@指令名称>,引用用户定义指令时须将#换为@。 注意:如果使用不存在的指令,FreeMarker不会使用模板输出,而是产生一个错误消息。 freemarker指令由FTL标记来引用,FTL标记和HTML标记类似,名字前加#来加以区分。如HTML标记的形式为<h1></h1>则FTL标记的形式是<#list></#list>(此处h1标记和list指令没有任何功能上的对应关系,只是做为说明使用一下)。 有三种FTL标记: 1)、开始标记:<#指令名称> 2)、结束标记:</#指令名称> 3)、空标记:<#指令名称/> 注意: 1) FTL会忽略标记之中的空格,但是,<#和指令 与 </#和指令 之间不能有空格。 2) FTL标记不能够交叉,必须合理嵌套。每个开始标记对应一个结束标记,层层嵌套。 如: <#list> <li> ${数据} <#if 变量> game over! </#if> </#list> 注意事项: 1)、FTL对大小写敏感。所以使用的标记及interpolation要注意大小写。name与NAME就是不同的对象。<#list>是正确的标记,而<#List>则不是。 2)、interpolation只能在文本部分使用,不能位于FTL标记内。如<#if ${var}>是错误的,正确的方法是:<#if var>,而且此处var必须为布尔值。 3)、FTL标记不能位于另一个FTL标记内部,注释例外。注释可以位于标记及interpolation内部。 if, else, elseif 语法 <#if condition> ... <#elseif condition2> ... <#elseif condition3> ... ... <#else> ... </#if> 用例 <#if x = 1> x is 1 </#if> <#if x = 1> x is 1 <#else> x is not 1 </#if> We have these animals: <table border=1> <tr><th>Name<th>Price <#list animals as being> <tr> <td> <#if being.size = "large"></#if></#if> ${being.name} <#if being.size = "large"> <td>${being.price} Euros </#list> </table> <#if user = "Big Joe"> It is Big Joe </#if> <#if user != "Big Joe"> It is not Big Joe </#if> switch, case, default, break 语法 <#switch value> <#case refValue1> ... <#break> <#case refValue2> ... <#break> <#case refValueN> ... <#break> <#default> ... </#switch> 用例 字符串 <#switch being.size> <#case "small"> This will be processed if it is small <#break> <#case "medium"> This will be processed if it is medium <#break> <#case "large"> This will be processed if it is large <#break> <#default> This will be processed if it is neither </#switch> 数字 <#switch x> <#case x = 1> 1 <#case x = 2> 2 <#default> d </#switch> 如果x=1 输出 1 2, x=2输出 2, x=3 输出d list, break 语法 <#list sequence as item> ... <#if item = "spring"><#break></#if> ... </#list> 关键字 item_index:是list当前值的下标 item_has_next:判断list是否还有值 用例 <#assign seq = ["winter", "spring", "summer", "autumn"]> <#list seq as x> ${x_index + 1}. ${x}<#if x_has_next>,</#if> </#list> 输出 1. winter, 2. spring, 3. summer, 4. autumn include 语法 <#include filename> or <#include filename options> options包含两个属性 encoding=”GBK” 编码格式 parse=true 是否作为ftl语法解析,默认是true,false就是以文本方式引入.注意在ftl文件里布尔值都是直接赋值的如parse=true,而不是parse=”true” 用例 /common/copyright.ftl包含内容 Copyright 2001-2002 ${me}<br> All rights reserved. 模板文件 <#assign me = "Juila Smith"> <h1>Some test</h1> Yeah. <#include "/common/copyright.ftl" encoding=”GBK”> 输出结果 <h1>Some test</h1> Yeah. <html> <head> <title>Test page</title> </head> <body> <h1>Test page</h1> Blah blah... <#include "/copyright_footer.html"> </body> </html> Import 语法 <#import path as hash> 类似于java里的import,它导入文件,然后就可以在当前文件里使用被导入文件里的宏组件 用例 假设mylib.ftl里定义了宏copyright那么我们在其他模板页面里可以这样使用 <#import "/libs/mylib.ftl" as my> <@my.copyright date="1999-2002"/> "my"在freemarker里被称作namespace compress 语法 <#compress> ... </#compress> 用来压缩空白空间和空白的行 用例 <#assign x = " moo \n\n "> (<#compress> 1 2 3 4 5 ${moo} test only I said, test only </#compress>) 输出 (1 2 3 4 5 moo test only I said, test only) escape, noescape 语法 <#escape identifier as expression> ... <#noescape>...</#noescape> ... </#escape> 用例 主要使用在相似的字符串变量输出,比如某一个模块的所有字符串输出都必须是html安全的,这个时候就可以使用该表达式 <#escape x as x?html> First name: ${firstName} <#noescape>Last name: ${lastName}</#noescape> Maiden name: ${maidenName} </#escape> 相同表达式 First name: ${firstName?html} Last name: ${lastName } Maiden name: ${maidenName?html} assign 语法 <#assign name=value> or <#assign name1=value1 name2=value2 ... nameN=valueN> or <#assign same as above... in namespacehash> or <#assign name> capture this </#assign> or <#assign name in namespacehash> capture this </#assign> 用例 生成变量,并且给变量赋值 给seasons赋予序列值 <#assign seasons = ["winter", "spring", "summer", "autumn"]> 给变量test加1 <#assign test = test + 1> 给my namespage 赋予一个变量bgColor,下面可以通过my.bgColor来访问这个变量 <#import "/mylib.ftl" as my> <#assign bgColor="red" in my> 将一段输出的文本作为变量保存在x里 下面的阴影部分输出的文本将被赋值给x <#assign x> <#list 1..3 as n> ${n} <@myMacro /> </#list> </#assign> Number of words: ${x?word_list?size} ${x} <#assign x>Hello ${user}!</#assign> error <#assign x=” Hello ${user}!”> true 同时也支持中文赋值,如: <#assign 语法> java </#assign> ${语法} 打印输出: java global 语法 <#global name=value> or <#global name1=value1 name2=value2 ... nameN=valueN> or <#global name> capture this </#global> 全局赋值语法,利用这个语法给变量赋值,那么这个变量在所有的namespace中是可见的,如果这个变量被当前的assign语法覆盖如<#global x=2> <#assign x=1> 在当前页面里x=2将被隐藏,或者通过${.global.x}来访问[A2] setting 语法 <#setting name=value> 用来设置整个系统的一个环境 locale number_format boolean_format date_format, time_format, datetime_format time_zone classic_compatible 用例 假如当前是匈牙利的设置,然后修改成美国 ${1.2} <#setting locale="en_US"> ${1.2} 输出 1,2 1.2 因为匈牙利是采用“,”作为十进制的分隔符,美国是用“.” C一些常用方法或注意事项 表达式转换类 ${expression}计算expression并输出 #{ expression }数字计算#{ expression ;format}安格式输出数字format为M和m M表示小数点后最多的位数,m表示小数点后最少的位数如#{121.2322;m2M2}输出121.23 数字循环 1..5 表示从1到5,原型number..number 对浮点取整数 ${123.23?int} 输出123 给变量默认值 ${var?default(“hello world<br>”)?html}如果var is null那么将会被hello world<br>替代 判断对象是不是null <#if mouse?exists> Mouse found <#else> 也可以直接${mouse?if_exists})输出布尔形 常用格式化日期 openingTime必须是Date型,详细查看freemarker文档 Reference->build-in referece->build-in for date ${openingTime?date} ${openingTime?date_time} ${openingTime?time} 添加全局共享变量数据模型 在代码里的实现 cfg = Configuration.getDefaultConfiguration(); cfg.setSharedVariable("global", "you good"); 页面实现可以通过global指令,具体查看指令里的global部分 直接调用java对象的方法 ${object.methed(args)} 字符串处理(内置方法) html安全输出 “abc<table>sdfsf”?html 返回安全的html输出,替换掉html代码 xml安全输出 var?xml substring的用法 <#assign user=”hello jeen”> ${user[0]}${user[4]} ${user[1..4]} 输出 : ho ello 类似String.split的用法 “abc;def;ghi”?split(“;”)返回sequence 将字符串按空格转化成sequence,然后取sequence的长度 var?word_list 效果同 var?split(“ ”) var?word_list?size 取得字符串长度 var?length 大写输出字符 var?upper_case 小写输出字符 var?lower_case 首字符大写 var?cap_first 首字符小写 var?uncap_first 去掉字符串前后空格 var?trim 每个单词的首字符大写 var?capitalize 类似String.indexof: “babcdabcd”?index_of(“abc”) 返回1 “babcdabcd”?index_of(“abc”,2) 返回5 类似String.lastIndexOf last_index_of和String.lastIndexOf类似,同上 下面两个可能在代码生成的时候使用(在引号前加”\”) j_string: 在字符串引号前加”\” <#assign beanName = 'The "foo" bean.'> String BEAN_NAME = "${beanName?j_string}"; 打印输出: String BEAN_NAME = "The \"foo\" bean."; js_string: <#assign user = "Big Joe's \"right hand\"."> <script> alert("Welcome ${user}!"); </script> 打印输出: alert("Welcome Big Joe\'s \"right hand\"!"); 替换字符串 replace${s?replace(‘ba’, ‘XY’ )} ${s?replace(‘ba’, ‘XY’ , ‘规则参数’)}将s里的所有的ba替换成xy 规则参数包含:i r m s c f具体含义如下: ·i: 大小写不区分. ·f: 只替换第一个出现被替换字符串的字符串 ·r: XY是正则表达式 ·m: Multi-line mode for regular expressions. In multi-line mode the expressions ^ and $ match just after or just before, respectively, a line terminator or the end of the string. By default these expressions only match at the beginning and the end of the entire string. ·s: Enables dotall mode for regular expressions (same as Perl singe-line mode). In dotall mode, the expression . matches any character, including a line terminator. By default this expression does not match line terminators. ·c: Permits whitespace and comments in regular expressions. D freemarker在web开发中注意事项 freemarker与webwork整合 web中常用的几个对象 Freemarker的ftl文件中直接使用内部对象: ${Request ["a"]} ${RequestParameters["a"]} ${Session ["a"]} ${Application ["a"]} ${JspTaglibs ["a"]} 与webwork整合之后 通过配置的servlet 已经把request,session等对象置入了数据模型中 在view中存在下面的对象 我们可以在ftl中${req}来打印req对象 req - the current HttpServletRequest res - the current HttpServletResponse stack - the current OgnlValueStack ognl - the OgnlTool instance webwork - an instance of FreemarkerWebWorkUtil action - the current WebWork action exception - optional the Exception instance, if the view is a JSP exception or Servlet exception view view中值的搜索顺序 ${name}将会以下面的顺序查找name值 freemarker variables value stack request attributes session attributes servlet context attributes 在模板里ftl里使用标签 注意,如果标签的属性值是数字,那么必须采用nubmer=123方式给属性赋值 JSP页面 < contentType="text/html;charset=ISO-8859-2" language="java"%> < uri="/WEB-INF/struts-html.tld" prefix="html"%> < uri="/WEB-INF/struts-bean.tld" prefix="bean"%> <html> <body> <h1><bean:message key="welcome.title"/></h1> <html:errors/> <html:form action="/query"> Keyword: <html:text property="keyword"/><br> Exclude: <html:text property="exclude"/><br> <html:submit value="Send"/> </html:form> </body> </html> 模板ftl页面 <#assign html=JspTaglibs["/WEB-INF/struts-html.tld"]> <#assign bean=JspTaglibs["/WEB-INF/struts-bean.tld"]> <html> <body> <h1><@bean.message key="welcome.title"/></h1> <@html.errors/> <@html.form action="/query"> Keyword: <@html.text property="keyword"/><br> Exclude: <@html.text property="exclude"/><br> <@html.submit value="Send"/> </@html.form> </body> </html> 如何初始化共享变量 1. 初始化全局共享数据模型 freemark在web上使用的时候对共享数据的初始化支持的不够,不能在配置初始化的时候实现,而必须通过ftl文件来初始化全局变量。这是不能满主需求的,我们需要在servlet init的时候留出一个接口来初始化系统的共享数据 具体到和webwork整合,因为本身webwork提供了整合servlet,如果要增加全局共享变量,可以通过修改com.opensymphony.webwork.views.freemarker.FreemarkerServlet来实现,我们可以在这个servlet初始化的时候来初始化全局共享变量 与webwork整合配置 配置web.xml <servlet> <servlet-name>freemarker</servlet-name> <servlet-class>com.opensymphony.webwork.views.freemarker.FreemarkerServlet</servlet-class> <init-param> <param-name>TemplatePath</param-name> <param-value>/</param-value> <!—模板载入文件夹,这里相对context root,递归获取该文件夹下的所有模板--> </init-param> <init-param> <param-name>NoCache</param-name> <!—是否对模板缓存--> <param-value>true</param-value> </init-param> <init-param> <param-name>ContentType</param-name> <param-value>text/html</param-value> </init-param> <init-param> <param-name>template_update_delay</param-name> <!—模板更新时间,0表示每次都更新,这个适合开发时候--> <param-value>0</param-value> </init-param> <init-param> <param-name>default_encoding</param-name> <param-value>GBK</param-value> </init-param> <init-param> <param-name>number_format</param-name> <param-value>0.##########</param-value><!—数字显示格式--> </init-param> <load-on-startup>1</load-on-startup> </servlet> <servlet-mapping> <servlet-name>freemarker</servlet-name> <url-pattern>*.ftl</url-pattern> </servlet-mapping> E高级方法 自定义方法 ${timer("yyyy-MM-dd H:mm:ss", x)} ${timer("yyyy-MM-dd ", x)} 在模板中除了可以通过对象来调用方法外(${object.methed(args)})也可以直接调用java实现的方法,java类必须实现接口TemplateMethodModel的方法exec(List args). 下面以把毫秒的时间转换成按格式输出的时间为例子 public class LongToDate implements TemplateMethodModel { public TemplateModel exec(List args) throws TemplateModelException { SimpleDateFormat mydate = new SimpleDateFormat((String) args.get(0))); return mydate.format(new Date(Long.parseLong((String)args.get(1))); } } 将LongToDate对象放入到数据模型中 root.put("timer", new IndexOfMethod()); ftl模板里使用 <#assign x = "123112455445"> ${timer("yyyy-MM-dd H:mm:ss", x)} ${timer("yyyy-MM-dd ", x)} 输出 2001-10-12 5:21:12 2001-10-12 自定义 Transforms 实现自定义的<@transform>文本或表达式</@transform>的功能,允许对中间的最终文本进行解析转换 例子:实现<@upcase>str</@upcase> 将str转换成STR 的功能 代码如下: import java.io.*; import java.util.*; import freemarker.template.TemplateTransformModel; class UpperCaseTransform implements TemplateTransformModel { public Writer getWriter(Writer out, Map args) { return new UpperCaseWriter(out); } private class UpperCaseWriter extends Writer { private Writer out; UpperCaseWriter (Writer out) { this.out = out; } public void write(char[] cbuf, int off, int len) throws IOException { out.write(new String(cbuf, off, len).toUpperCase()); } public void flush() throws IOException { out.flush(); } public void close() { } } } 然后将此对象put到数据模型中 root.put("upcase", new UpperCaseTransform()); 在view(ftl)页面中可以如下方式使用 <@upcase> hello world </@upcase> 打印输出: HELLO WORLD F.Built-ins ${x?upper_case} – 小写变大写 ${test?html} - 转换为HTML编码格式 ${repeat("A", B)} – 复制B次A Example: ${test?html} ${test?upper_case?html} Assuming that test stores the string ``Tom & Jerry'', the output will be: Tom & Jerry TOM & JERRY --------- ${repeat("What", 3)} will print: :WhatWhatWhat 1. String内置的JavaScript转换: js_string 用途:用于JavaScript转义,转换',",换行等特殊字符 模板: <script> alert("${errorMessage?js_string}"); </script> 输出: <script> alert("Readonly\'s pet name is \"Cross Bone\""); </script> 2.内置的默认值处理:default 用途: 用于处理默认值 模本: User: ${userLogin.name?default("Anonymous")} <td>${(employee.department.manager.name)?default(" ")}</td> 输出: User: Anonymous <td> </td> 注,可以对整个对象树加上(),再用内置处理器这种方便的做法,偶也是最近刚学会的,以前一直用很傻的方法做..... 3. Sequence内置的计数器: xxx_index 用途:显示序号 模板: <#list employees as e> ${e_index}. ${e.name} </#list> 输出: 1. Readonly 2. Robbin 4. Sequence内置的分段器: chunk 用途:某些比较BT的排版需求 模板: <#assign seq = ['a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j']> <#list seq?chunk(4) as row> <ul> <li><#list row as cell>${cell} </#list> </#list> <#list seq?chunk(4, '-') as row> <tr> <td><#list row as cell>${cell} </#list></td> </tr> </#list> 输出: <ul> <li>a <li>b <li>c <li>d <ul> <li>e <li>f <li>g <li>h <ul> <li>i <li>j <tr> <td>a</td> <td>b</td> <td>c</td> <td>d</td> </tr> <tr> <td>e</td> <td>f</td> <td>g</td> <td>h</td> </tr> <tr> <td>i</td> <td>j</td> <td>-</td> <td>-</td> </tr> String ${"It's \"quoted\" and this is a backslash: \\"} ${'It\'s "quoted" and this is a backslash: } ${r"${foo}"} raw字符串,原封不动地现实引号中的内容 ps:前一种是用双引号来引用字符串,后一种是用单引号来引用字符串。 分别需要对双引号和单引号进行转义 ${"${user}${user}${user}${user}"} ${user + user + user + user} 效果相同 ★substring ${user[0]}${user[4]} ${user[1..4]} ${user[4..]} ★number 不支持科学计数法 小数点前面的零不能省略 ★sequences <#list ["winter", "spring", "summer", "autumn"] as x> ${x} </#list> <#list 2..5 as x> ${x} </#list> <#list [2,3,4,5] as x> ${x} </#list> 数组的拼接 <#list ["Joe", "Fred"] + ["Julia", "Kate"] as user> - ${user} </#list> ★hash <#assign ages = {"Joe":23, "Fred":25} + {"Joe":30, "Julia":18}> - Joe is ${ages.Joe} - Fred is ${ages.Fred} - Julia is ${ages.Julia} 注意重复的键对应的值取最后的一个 ★运算 ${5/2?int} 显示2 cap_first : 首字母大写 capitalize: 所有单词首刺目大写 html : 转换为HTML格式 < replaced with < > replaced with > & replaced with & " replaced with " index_of : 显示元素所在的位置 "abcabc"?index_of("bc") 返回值为1(下标从0开始) Contains:判断是否存在字符 <#if "piceous"?contains("ice")>It contains "ice"</#if> 输出: It contains "ice" Replace :替换 split(“XX”):截取XX之后的字符 <#list "someMOOtestMOOtext"?split("MOO") as x> - ${x} </#list> 输出: - some - test - text starts_with :字符串由什么开始返回布尔型 trim :去掉空格 seq_index_of 数组中元素的位置 <#assign colors = ["red", "green", "blue"]> ${colors?seq_index_of("blue")} 输出: 2 Default : 设置变量的默认值 Exists:放在if句 如果没有….. <#if mouse?exists> Mouse found <#else> No mouse found </#if> Creating mouse... <#assign mouse = "Jerry"> <#if mouse?exists> Mouse found <#else> No mouse found </#if> 输出 : No mouse found Creating mouse... Mouse found if_exists 放在一般语句 (${mouse?if_exists}) Creating mouse... <#assign mouse = "Jerry"> (${mouse?if_exists}) 输出: () Creating mouse... (Jerry) 删除空白行和空格 <#compress> ... </#compress> 让此标记内的代码都执行<#escape 后的?参数 <#escape> </#escape> <#escape x as x?html> From: ${mailMessage.From} Subject: ${mailMessage.Subject} <#noescape>Message: ${mailMessage.htmlFormattedBody}</#noescape> ... </#escape> 输出: From: ${mailMessage.From?html} Subject: ${mailMessage.Subject?html} Message: ${mailMessage.htmlFormattedBody} ... [A1]默认值 [A2]<#import “lib/abc.ftl” as abc>这里的abc叫做namespace chunk, is_date, last, root, j_string, contains, is_hash, long, float, ends_with, namespace, matches, time, values, seq_last_index_of, uncap_first, byte, substring, is_transform, web_safe, groups, seq_contains, is_macro, index_of, word_list, int, is_method, eval, parent, xml, number, capitalize, if_exists, rtf, node_type, double, is_directive, url, size, default, is_boolean, split, node_name, is_enumerable, seq_index_of, is_sequence, sort, is_node, sort_by, left_pad, cap_first, interpret, children, node_namespace, chop_linebreak, date, short, last_index_of, is_collection, ancestors, length, trim, datetime, is_string, reverse, c, keys, upper_case, js_string, has_content, right_pad, replace, is_hash_ex, new, is_number, is_indexable, lower_case, string, exists, html, first, starts_with ##############2222222222222222############### struts2.0 标签+ftl标签 FreeMarker中文API手册(完整) http://blog.csdn.net/junjun16818/article/details/6990068 三目: ${true?string('5','7')} ${line.class.simpleName} <#if line.class.simpleName=="ViewLine">你好</#if> list里面是object数组 <#if (areaList?exists)> <#list areaList as line> <span style="background-color:#${(sc[(line_index)%6])}">${line[1]}:${line[0]}</span> </#list> </#if> 取得list的长度: <#if (pageInfo.resultList?size>0)> 截取字符串:<#if news.title?length gt 14>${news.title.substring(0,14)}...<#else>${news.title?if_exists}</#if> 拆分字符数组 <#if (lineInfo.lineDate?exists)&&(lineInfo.lineDate?length>10)> <#list lineInfo.lineDate?split(",") as d> <input type="text" name="lineInfo.lineDate" id="lineDate" value="${d}" onclick="WdatePicker({dateFmt:'yyyy-MM-dd', skin:'whyGreen'})"/> </#list> </#if> 1.注释: 包含在<#--和--> 2.注意: 由于Freemarker会将>解释成FTL标记的结束字符,所以对于>和>=可以使用括号来避免这种情况,例如 <#if (x > y)> 3.<#local y = "test"> 定义局部变量 4.<#import "/lib/my_test.ftl" as my> 导入模板文件 指定名字空间 my 5. if指令 <#if animals.python.price < animals.elephant.price> Pythons are cheaper than elephants today. <#else> Pythons are not cheaper than elephants today. </#if> 6. list指令以及列表序号 <#list animals as being> 第${being_index+1}个<#--默认是0开始--> <tr><td>${being.name}<td>${being.price} Euros </#list> <#list ["winter", "spring", "summer", "autumn"] as x> ${x} </#list> <#list ["Joe", "Fred"] + ["Julia", "Kate"] as user> - ${user} </#list> 输出结果是: - Joe - Fred - Julia - Kate include指令 <#include "/copyright_footer.html"> 7.判断是否为空 ${userInfo.userName?if_exists} <#if ((user.sex)!'')=='1'>男<#elseif ((user.sex)!'')=='2'>女</#if> <#if searchType ? exists && searchType=='on'>checked</#if> <#if time ? exists && (time!'')=='y' || (time!'')=='m' || (time!'')=='d'>统计条件<#else>保证金返款数量</#if> <#if ((time)!'')=='y'>按年统计<#elseif ((time)!'')=='m'>按月统计<#elseif ((time)!'')=='d'>按日统计<#else>默认按日统计</#if> 8.截取字符串 ${carInfo.carNum.substring(0,1)} 9.freemarker的replace功能 替换字符串 replace 线路标签:${lineInfo.lineLableDescribe?replace('#','、')} ${s?replace(‘ba’, ‘XY’ )} ${s?replace(‘ba’, ‘XY’ , ‘规则参数’)}将s里的所有的ba替换成xy 规则参数包含: i r m s c f 具体含义如下: · i: 大小写不区分. · f: 只替换第一个出现被替换字符串的字符串 · r: XY是正则表达式 · m: Multi-line mode for regular expressions. In multi-line mode the expressions ^ and $ match just after or just before, respectively, a line terminator or the end of the string. By default these expressions only match at the beginning and the end of the entire string. · s: Enables dotall mode for regular expressions (same as Perl singe-line mode). In dotall mode, the expression . matches any character, including a line terminator. By default this expression does not match line terminators. · c: Permits whitespace and comments in regular expressions. 10.三目运算 ${true?string('5','7')} 11.string格式化单个Interpolation,下面是一个例子: <#setting number_format="currency"/> <#assign answer=42/> ${answer} ${answer?string} <#-- the same as ${answer} --> ${answer?string.number} ${answer?string.currency} ${answer?string.percent} 输出结果是: $42.00 $42.00 42 $42.00 4,200% 12.插入日期值:根据缺省格式(由#setting指令设置)将表达式结果转换成文本输出;可以使用内建函数string格式化单个Interpolation,下面是一个使用格式模式的例子: ${lastUpdated?string("yyyy-MM-dd HH:mm:ss zzzz")} ${lastUpdated?string("EEE, MMM d, ''yy")} ${lastUpdated?string("EEEE, MMMM dd, yyyy, hh:mm:ss a '('zzz')'")} 输出的结果类似下面的格式: 2003-04-08 21:24:44 Pacific Daylight Time Tue, Apr 8, '03 Tuesday, April 08, 2003, 09:24:44 PM (PDT) 13.插入布尔值:根据缺省格式(由#setting指令设置)将表达式结果转换成文本输出;可以使用内建函数string格式化单个Interpolation,下面是一个例子: <#assign foo=true/> ${foo?string("yes", "no")} 输出结果是: yes <#if cList?exists> <#assign index = 1 /> <#list cList as cList> <#if index==1 || index %3==0> <div class="base_row"> </#if> <div class="fldivlr5"><font class="font_gray">车型:</font></div> <div class="fldivlr5">三厢轿车</div> <#if index %3==0 || !cList_has_next> </div> </#if> <#assign index=index+1 /> </#list> </#if> Freemarker 内置函数 数字、字符串、日期格式化 一、 Sequence的内置函数 1. sequence?first 返回sequence的第一个值。 2. sequence?last 返回sequence的最后一个值。 3. sequence?reverse 将sequence的现有顺序反转,即倒序排序 4. sequence?size 返回sequence的大小 5. sequence?sort 将sequence中的对象转化为字符串后顺序排序 6. sequence?sort_by(value) 按sequence中对象的属性value进行排序 二、 Hash的内置函数 1. hash?keys 返回hash里的所有key,返回结果为sequence 2. hash?values 返回hash里的所有value,返回结果为sequence 例如: <#assign user={“name”:“hailang”, “sex”:“man”}> <#assign keys=user?keys> <#list keys as key> ${key}=${user[key]} </#list> 三、 操作字符串函数 1. substring(start,end)从一个字符串中截取子串 start:截取子串开始的索引,start必须大于等于0,小于等于end end: 截取子串的长度,end必须大于等于0,小于等于字符串长度,如果省略该参数,默认为字符串长度。 例子: ${‘str’?substring(0)}à结果为str ${‘str’?substring(1)}à结果为tr ${‘str’?substring(2)}à结果为r ${‘str’?substring(3)}à结果为 ${‘str’?substring(0,0)}à结果为 ${‘str’?substring(0,1)}à结果为s ${‘str’?substring(0,2)}à结果为st ${‘str’?substring(0,3)}à结果为str 2. cap_first 将字符串中的第一个单词的首字母变为大写。 ${‘str’?cap_first}à结果为Str 3. uncap_first将字符串中的第一个单词的首字母变为小写。 ${‘Str’?cap_first}à结果为str 4. capitalize将字符串中的所有单词的首字母变为大写 ${‘str’? capitalize}à结果为STR 5. date,time,datetime将字符串转换为日期 例如: <#assign date1=”2009-10-12”?date(“yyyy-MM-dd”)> <#assign date2=”9:28:20”?time(“HH:mm:ss”)> <#assign date3=” 2009-10-12 9:28:20”?time(“HH:mm:ss”)> ${date1}à结果为2009-10-12 ${date2}à结果为9:28:20 ${date3}à结果为2009-10-12 9:28:20 注意:如果指定的字符串格式不正确将引发错误。 6. ends_with 判断某个字符串是否由某个子串结尾,返回布尔值。 ${“string”?ends_with(“ing”)?string} 返回结果为true 注意:布尔值必须转换为字符串才能输出 7. html 用于将字符串中的<、>、&和“替换为对应得<>":& 8. index_of(substring,start)在字符串中查找某个子串,返回找到子串的第一个字符的索引,如果没有找到子串,则返回-1。 Start参数用于指定从字符串的那个索引处开始搜索,start为数字值。 如果start大于字符串长度,则start取值等于字符串长度,如果start小于0, 则start取值为0。 ${“string”?index_of(“in”) à结果为3 ${“string”?index_of(“ab”) à结果为-1 9.length返回字符串的长度 ${“string”?length}à结果为6 10. lower_case将字符串转为小写 ${“STRING”?lower_case}à结果为string 11.upper_case将字符串转为大写 ${“string”?upper_case}à结果为STRING 12. contains 判断字符中是否包含某个子串。返回布尔值 ${“string”?contains(“ing”)?string} à结果为true 注意:布尔值必须转换为字符串才能输出 13. number将字符串转换为数字 ${“111.11”?number}à结果为111.11 14.replace用于将字符串中的一部分从左到右替换为另外的字符串。 ${“strabg”?replace(“ab”,”in”)} à结果为string 15.split使用指定的分隔符将一个字符串拆分为一组字符串 <#list “This|is|split”?split(“|”) as s> ${s} </#list> 结果为: This is split 16. trim 删除字符串首尾空格 ${“ String ”?trim} à结果为String 四、 操作数字 1. c 用于将数字转换为字符串 ${123?c} à结果为123 2. string用于将数字转换为字符串 Freemarker中预订义了三种数字格式:number,currency(货币)和percent(百分比)其中number为默认的数字格式转换 例如: <#assign tempNum=20> ${tempNum} ${tempNum?string.number}或${tempNum?string(“number”)} à结果为20 ${tempNum?string.currency}或${tempNum?string(“currency”)} à结果为¥20.00 ${tempNum?string. percent}或${tempNum?string(“percent”)} à结果为2,000% 五、 操作布尔值 string 用于将布尔值转换为字符串输出 true转为“true”,false转换为“false” foo?string(“yes”,”no”)如果布尔值是true,那么返回“yes”,否则返回no <#assign index = 1 /> <#list pageInfo.resultList as p> <tr class=<#if index%2==0>"sealistra"<#else>"sealistrb"</#if> align="center"> <td align="center">${index}</td> ${p.userName?if_exists} <td><#if ((p.roleType)!'')=='1'>司机<#elseif ((p.roleType)!'')=='2'>乘客</#if></td> <td><#if ((p.journeyType)!'')=='1'>单程<#elseif ((p.journeyType)!'')=='2'>往返</#if></td> <td>${(p.ver)!""}</td> <td> <#if ((p.statusFlag)!'')=='0'>默认 <#elseif ((p.statusFlag)!'')=='1'>匹配成功 </#if> </td> <td> <#if p.createTime?exists >${p.createTime?string("yyyy-MM-dd HH:mm:ss")}</#if> </td> </tr> <#assign index=index+1 /> </#list> if, else, elseif 语法: <#if condition> ... <#elseif condition2> ... <#elseif condition3> ... ... <#else> ... </#if> 备注:condition、condition2···必须为boolean 类型,<#elseif ··>、<#else>可有0或多个。 实例: <#if x == 1> x is 1 <#elseif x == 2> x is 2 <#elseif x == 3> x is 3 <#elseif x > 4> x is 4 <#else> x is not 1 nor 2 nor 3 nor 4 </#if> 备注:< 或 > 号 必须转义,否则出错。。转义请参考其他文档。 switch, case, default, break 语法 <#switch value> <#case refValue1> ... <#break> <#case refValue2> ... <#break> ... <#case refValueN> ... <#break> <#default> ... </#switch> 备注:该指令官方不推荐使用了,可以用if, else, elseif 指令代替。 list, break 语法 <#list sequence as item> ... </#list> 备注: sequence 为一个sequence 或者 collection 类型。item 为 循环的变量。该指令中包含有两个特殊的循环变量, item_index:该值为当前循环的值。 item_has_next:该值为一个boolean类型,表明该循环是否含有下一个(是否为循环到了最后一个) 实例: <#assign seq = ["winter", "spring", "summer", "autumn"]> <#list seq as x> ${x_index + 1}. ${x}<#if x_has_next>,</#if> </#list> 输出: 1. winter, 2. spring, 3. summer, 4. autumn 实例: <#assign x=3> <#list 1..x as i> ${i} </#list> 备注:当x 为一个数值序列时,可以使用该list 列出两个数值之间的值。(适合于表格的序号填写) 实例: <#list seq as x> ${x} <#if x = "spring"><#break></#if> </#list> 备注:可以用<#if···><#break> 来终止该循环。 freemarker常见语法大全 FreeMarker的插值有如下两种类型:1,通用插值${expr};2,数字格式化插值:#{expr}或#{expr;format} ${book.name?if_exists } //用于判断如果存在,就输出这个值 ${book.name?default(‘xxx’)}//默认值xxx ${book.name!"xxx"}//默认值xxx ${book.date?string('yyyy-MM-dd')} //日期格式 ${book?string.number} 20 //三种不同的数字格式 ${book?string.currency}--<#-- $20.00 --> ${book?string.percent}—<#-- 20% --> <#assign foo=ture /> //声明变量,插入布尔值进行显示 ${foo?string("yes","no")} <#-- yes --> <等大小比较符号使用需要注意:(xml的原因),可以用于比较数字和日期 使用lt、lte、gt和gte来替代<、<=、>和>= 也可以使用括号<#if (x>y)> 内置函数: 调用区别于属性的访问,使用?代替. 常见的一些内置函数 对于字符串 html-对字符串进行HTML编码 cap_first-使字符串第一个字母大写 lower_case-将字符串转换成小写 trim-去掉字符串前后的空白字符 对于Sequences(序列) size-获得序列中元素的数目 对于数字 int-取得数字的整数部分(如-1.9?int的结果是-1) 对于集合,可以使用数组的方式,使用下标索引进行访问 逻辑判断: if................ <#if condition>... <#elseif condition2>... <#elseif condition3>...... <#else>... Boolean类型的空值判断 空值判断可以写成<#if book.name?? > //注意${}为变量的渲染显示,而<>为定义等操作符的定义 switch............ <#switch value> <#case refValue1> ... <#break> <#case refValue2> ... <#break> ... <#case refValueN> ... <#break> <#default> ... </#switch> 快速定义int区间的集合 <#assign l=0..100/> //注意不需要[] 3:循环读取集合: 注意/的使用 <#list student as stu> ${stu}<br/> </#list> 与jstl循环类似,也可以访问循环的状态 item_index:当前变量的索引值 item_has_next:是否存在下一个对象 其中item名称为as后的变量名,如stu 集合长度判断 <#if student?size != 0></#if> 判断=的时候,注意只要一个=符号,而不是== 宏/模板 初步了解: 使用更像一个闭包closure,可以定义后,在脚本中任意地方引用,并原地起作用 <#macro greet> <font size="+2">Hello Joe!</font> </#macro> 使用的方式为: <@greet></@greet> //同xml可以简写成<@greet/> 宏的参数定义,类似js,在宏名后 带参数进行传递定义 <#macro greet person color> ${person} </#macro> 调用带参数时,注意使用类似XML的属性格式进行传递,不需要关心顺序问题 <@greet person="Fred" color="black"/> 参数默认值定义,如果没有,就必须要求传递完整的参数列表 <#macro greet person color="black"> <font size="+2" color="${color}">Hello ${person}!</font> </#macro> 使用xml的嵌套内容进行传递宏调用,关键标签 <#nested> <#macro border> <table border=4 cellspacing=0 cellpadding=4><tr><td> <#nested> </tr></td></table> </#macro> 调用时: <@border>The bordered text</@border> <#nested> 标签可以在宏中多次调用,也可以将多个宏组合进行嵌套 for循环的精简版: <#list 1..count as x> </#list> 宏的循环变量,配合嵌套标签进行参数传递, <#macro repeat count> <#list 1..count as x> <#nested x, x/2, x==count> //这里的三个参数,将会传递到嵌套内容中 </#list> </#macro> <@repeat count=4 ; c, halfc, last> ${c}. ${halfc}<#if last> Last!</#if> //这里的内容由macro中的<#nested>进行参数的传递,传递的数量任意,当注意需要宏接受这些 </@repeat> 上述还需要注意;的使用 参数的数量是可变的,并不要求全部都有,但是效果不同 在模板中定义变量 在模板中定义的变量有三种类型: plain变量:可以在模板的任何地方访问,包括使用include指令插入的模板,使用assign指令创建和替换。 局部变量:在宏定义体中有效,使用local指令创建和替换。 循环变量:只能存在于指令的嵌套内容,由指令(如list)自动创建;宏的参数是局部变量,而不是循环变量 <#assign x = "plain"> //全局的plain变量 内部循环变量将会隐藏同名的外部循环变量 外部导入的使用,可以用于模块化,并且提供公用性 如:lib/my_lib.ftl文件 <#macro copyright date> <p>Copyright (C) ${date} Julia Smith. All rights reserved. <br>Email: ${mail}</p> </#macro> <#assign mail = "jsmith@acme.com"> lib/my_inc.ftl文件 <#import "/lib/my_test.ftl" as my> <#assign mail="fred@acme.com"> <@my.copyright date="1999-2002"/> ${my.mail} ${mail} 输出结果将不会出现冲突 对于库中的变量修改,使用in关键字 <#assign mail="jsmith@other.com" in my> 函数定义:区别于宏对象,带返回值 <#function name param1 param2><#return val></#function>函数,有返回参数 stringA[M .. N] 取子字符串,类似substring(stringA, M, N) <#include "/copyright_footer.html"> 导入其他页面元素 <#include filename options> options包含两个属性 encoding=”GBK” 编码格式 parse=true 是否作为ftl语法解析,默认是true,false就是以文本方式引入.注意在ftl文件里布尔值都是直接赋值的如parse=true,而不是 parse=”true” hash与list的定义 <#assign c= {"a":"orz","b":"czs"}> ${c.a} List片段可以采用: products[10..19] or products[5..] 的格式进行定义,当只局限于数字 <#assign c= [1,2,3,4,5,6,6,7]> <#list c[1..3] as v> ${v} </#list> 对变量的缺省处理 product.color!"red" 用compress directive或者transform来处理输出。 <#compress>...</#compress>:消除空白行。 <@compress single_line=true>...</@compress>将输出压缩为一行。都需要包裹所需文档 freemarker可用"["代替"<".在模板的文件开头加上[#ftl]. 数字输出的另外一种方式 #{c.a;m0} 区别于${},这个例子是用于输出数字的格式化,保留小数的位数,详细如下 数字格式化插值可采用#{expr;format}形式来格式化数字,其中format可以是: mX:小数部分最小X位 MX:小数部分最大X位 在定义字符串的时候,可以使用''或者"",对特殊字符,需要使用\进行转义 如果存在大量特殊字符,可以使用${r"..."}进行过滤 ${r"${foo}"} ${r"C:\foo\bar"} Map对象的key和value都是表达式,但是key必须是字符串 可以混合使用.和[""]访问 book.author["name"] //混合使用点语法和方括号语法 为了处理缺失变量,FreeMarker提供了两个运算符: 用于防止对象不存在而导致的异常 !:指定缺失变量的默认值 ??:判断某个变量是否存在,返回boolean值 noparse指令指定FreeMarker不处理该指定里包含的内容,该指令的语法格式如下: <#noparse>...</#noparse> ${firstName?html} 使用html对字符进行格式化处理,对于<等的过滤 escape , noescape指令,对body内的内容实用统一的表达式 看如下的代码: <#escape x as x?html> First name:${firstName} Last name:${lastName} Maiden name:${maidenName} </#escape> 上面的代码等同于: First name:${firstName?html} Last name:${lastName?html} Maiden name:${maidenName?html} 定义全局变量的方式 <#assign name1=value1 name2=value2 / > // 可以同时定义多个变量,也可以使用循环来给变量赋值 <#assign x> <#list ["星期一", "星期二", "星期三", "星期四", "星期五", "星期六", "星期天"] as n> ${n} </#list> </#assign> ${x} setting指令,用于动态设置freeMarker的运行环境: 该指令用于设置FreeMarker的运行环境,该指令的语法格式如下:<#setting name=value>,在这个格式中,name的取值范围包含如下几个: locale:该选项指定该模板所用的国家/语言选项 number_format:指定格式化输出数字的格式 boolean_format:指定两个布尔值的语法格式,默认值是true,false date_format,time_format,datetime_format:指定格式化输出日期的格式 time_zone:设置格式化输出日期时

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值