FreeMarker 快速入门

牧云@^-^@ 提交于 2019-11-29 02:18:43

什么是 FreeMarker?

       FreeMarker 是一款模板引擎:一种基于模板的、用来生成输出文本(任何来自于 HTML格式的文本用来

自动生成源代码)的通用工具。它是为 Java 程序员提供的一个开发包或者说是类库。它不是面向最终用户,

而是为程序员提供的可以嵌入他们开发产品的一款应用程序。

 

搭建SpringMVC+FreeMarker环境

 

    springmvc.xml 此处只贴出了配置FreeMarker的代码,hibernate配置等省略。

<!--对模型视图名称的解析,即在模型视图名称添加前后缀 -->
	<bean id="viewResolver"
	class="org.springframework.web.servlet.view.freemarker.FreeMarkerViewResolver">
		<property name="viewClass"
			value="org.springframework.web.servlet.view.freemarker.FreeMarkerView" />
		<property name="prefix" value="/" />
		<property name="suffix" value=".html" />
		<property name="contentType" value="text/html;charset=utf-8" />
		<property name="exposeRequestAttributes" value="true" />
		<property name="exposeSessionAttributes" value="true" />
		<property name="exposeSpringMacroHelpers" value="true" />
	</bean>


	<!-- 定义freemarker参数文件并载入 -->
	<bean id="freemarkerConfiguration"
		class="org.springframework.beans.factory.config.PropertiesFactoryBean">
		<property name="location" value="classpath:freemarker.properties" />
	</bean>
	<!-- 定义freemarker配置,包括模板根路径、参数 -->
	<bean id="freemarkerConfig"
		class="org.springframework.web.servlet.view.freemarker.FreeMarkerConfigurer">
		<!-- 注意: templateLoaderPath必须设置,否则freemarker找不到模板位置 -->
		<property name="templateLoaderPath" value="/WEB-INF" />
		<property name="freemarkerSettings" ref="freemarkerConfiguration" />
	</bean>

   

    web.xml就照标准的springmvc配置就行了

    当然别忘了配置freemaker.properties

 

    freemaker.properties

template_update_delay=0
defaultEncoding=UTF-8
url_escaping_charset=UTF-8
locale=zh_CN
boolean_format=true,false
datetime_format=yyyy-MM-dd HH:mm:ss
date_format=yyyy-MM-dd
time_format=HH:mm:ss
number_format=0.######
whitespace_stripping=true

   注释

              <#-- 此处是注释 -->

             注释freemaker代码,不要用html的注释,没有效果。

    打印值

    字符串

<#assign name="hello">
	${name}
<!-- 	输出hello -->

   数值

<#assign number=10>
	${number}
    <!--输出10 -->
<#assign number2=2.5>
   		${number2}
    <!--输出2.5 -->
<#assign avg = number/number2>
    	${avg}
<!--输出4 -->

   boolean

<#assign flag = true>
	${flag}
<!-- 	输出true -->
	<#assign flag2 = false>
	${flag2}
<!-- 	什么也没有输出 为空字符串-->
<#assign flag3 = "true">
	${flag3}
<!-- 	输出为true -->
	<#assign flag4 = "false">
	${flag4}
  <#if flag3> 为真 </#if> <!-- 打印为真,freemarker将字符串"true"转换为boolean -->

   运算符

   <#assign x=2>
    ${100-2}
   <!--  减   打印98 -->
    ${10/2}
   <!--  除  打印5 -->
    ${10*2}
   <!--   乘  打印20 -->
    ${9%2}
   <!--   取余  打印1 -->

   流程控制

<#assign x2 = 1>
	<#assign x3 = 5>
	<#assign x4 =6>
	<#if (x2<x3) >
		A
	</#if>
<!-- 	打印A,注意此处一定要加括号 -->
	<#if (x2>x3)>
		B
	<#else>
	    C
	</#if>
<!-- 	打印C -->
	<#if (x2>x3)>
		A
	<#elseif (x2>x4)>
		B
	<#elseif (x2<x4)>
		C
	</#if>
<!-- 	打印C -->
<#assign x5 =5>
	<#switch x5>
		<#case 10>
		 A
		<#break>
		
		<#case 5>
		 B
		<#break>
		<#default>
		 C
	</#switch>
  <!-- 	打印5 -->

    遍历

    List,Set

    后台传入一个uerList的list或者Set

<#list userList as user>
  ${user.name}
</#list>
<!--打印出用户名列表-->

     Map

      map为后台传入的Map集合

<#list map?keys as k>
		${k}
<!-- 		键 -->
		${map[k]}
<!-- 		值 -->
</#list>

  处理空值

 

  可在freemarker.properties中加一句classic_compatible=true如果对象为空将不会报错

 

<#if user??>
</#if>

<!-- 判断user对象是否为空,如果不为空执行if语句中的代码-->
<!-- 在变量后面加!处理变量值为空的情况-->
${user.name!}
<!-- 判断name是否为空 如果为空将什么也不显示-->
${(user.name)!}
<!-- 判断user和name是否都为空,如果有任意一个为空什么都不显示   如果你有多个对象连环调用属性请一定要加()不然freemarker只会判断最后一个变量,否则报错-->
${(user.name)!"您还没有登录"}
<!-- 如果变量为空的情况下,将显示默认值-->

    内置函数

    集合

     userList 为后台传入的对象集合

<#list userList?reverse  as li>
	${li.name}
	</#list>
   <!-- 	 ?reverse      将对象集合顺序反转 -->
	
	${(userList?first).name}
   <!-- 	 ?first  打印集合中第一个user对象的name -->
	 
	${(userList?last).name}
   <!-- 	?last      打印集合中最后一个user对象的name -->
	
	${userList?size}
   <!-- 	?size    打印集合的长度 -->
	
	<#list userList?sort  as li>
	${li.name}
	</#list><br>
    <!-- 	将对象转换为字符串  顺序排序 -->
	<#list userList?sort_by("id")  as li>
	${li.name}
	</#list><br>
    <!-- 	将对象中的属性值进行排序, 当前为user中的id排序 -->

   

    字符串

${"string"?substring(0)}
<!-- 从索引0开始截取字符串  为string -->
${"string"?substring(1)}
<!-- 从索引1开始截取字符串 为tring -->

${"string"?substring(0,1)}
<!-- 从索引0到1截取字符串  为 s -->
${"string"?substring(1,2)}
<!-- 从索引1到2截取字符串为 t -->

${"string"?cap_first}
<!-- 将字符串首字母变为大写  String-->
${"String"?uncap_first}
<!-- 将字符串首字母变为小写 string-->
${"string"?upper_case}
<!-- 将字符串全部转换为大写 -->
${"STRINg"?lower_case}
<!-- 将字符串全部转换为小写 -->
${"2014-11-11 9:0:0"?date("yyyy-MM-dd")}
<!-- 输出为2014-11-11 -->
${"string"?ends_with("ing")}
<!-- 判断字符串 是否已某段字符串结尾               打印true -->

${"string"?index_of("tr")}
<!-- 	判断某段字符串在一段字符串中出现的索引位置,如果没有返回-1           打印1 -->
${"string"?contains('ing')}
<!-- 判断一个字符串中是否包含某段字符串  返回true或false -->

${"strabgab"?replace("ab","in")}
<!-- 将字符串总包含的某段字符串全部替换掉  结果为stringin-->

<#list "this,is,freemaker"?split(",") as s>
    ${s}
</#list>
<!-- 使用指定的符号将字符串分割为数组 -->
${"  String       "?trim}
<!-- 去掉首位空格 -->

<#assign num = 1>
${num?string.number}
<!-- 转换为数字格式  1 -->
${num?string.currency}
<!-- 转换为货币格式  ¥1.00 -->
${num?string. percent}
<!-- 转换为百分比格式 100% -->

<#assign flag = true>
${flag?string("yes","no")}
<!-- 根据boolean类型的真假值来输出相应的字符串 -->

     freemarker宏定义

     宏定义的语法为:<#macro 宏名称 参数1  参数2   参数3 。。。></#macro>

     首先我们新建一个freemarker的ftl文件

     此处为spring.ftl

<#macro hello>
	<h1>hello,World!</h1>
</#macro>
<#-- 定义了一个名为hello的宏,在宏中我们可以写任意的html代码 -->

    然后在我的html页面引入

<#import  "../../page/spring.ftl" as h /> 
<!--引入文件 -->
<@h.hello />
<!--  调用名为hello的宏 -->

    然后运行项目打印的为

hello,World!

   下面再来个带参数的

<#macro welcome name age>
	<span>欢迎您,  ${age} 岁的   ${name} 先生,来到freemarker的世界</span>
</#macro>

    页面调用宏   

<@h.welcome "小李" 22/>

     打印为

欢迎您, 22 岁的 小李 先生,来到freemarker的世界

     宏嵌套 <#nested>,表示我们可以在宏的标签内加入任意的内容,包括宏

<#macro go>
	<#nested>
</#macro>

     页面调用

<#import  "../../page/spring.ftl" as h />
<@h.go>
 大家好!
</@h.go>

     此处打印的是:大家好!

    我们再来试试嵌套的,这里我定义了两个宏

<#macro go2>
	<#nested>
</#macro>

<#macro go3 name>	
	${name}
</#macro>

    页面调用 

<#import  "../../page/spring.ftl" as h />
<@h.go2>
	<@h.go3 "你好"/>,你今天过得快乐吗?
</@h.go2>

    此处打印的为:你好,你今天过得快乐吗?

 

    使用宏做一个freemarker分页

    首先我们的写个分页的ftl文件

    pager.ftl

     

<#-- 自定义的分页指令 
属性:
pageNo      当前页号(int类型)
pageSize    每页要显示的记录数(int类型)
pageCount   总页数
toURL       点击分页标签时要跳转到的目标URL(string类型)
-->
<#macro pager pageNo pageSize toURL pageCount>
	<#-- 输出分页表单 -->
	<div class="page">
		<form method="post" action="${toURL}" name="qPagerForm">
			<#--用于记录当前的页数 -->
			<input type='hidden' name ='page' />
			<#-- 上一页处理 -->
			<#if (pageNo == 1)>
			<span class="disabled"><a >上一页</a></span>
			<#else>
			<span ><a href="javascript:page(${pageNo - 1})">上一页</a></span>
			</#if>
			<#-- 如果前面页数过多,显示... -->
			<#assign start=1>
			<#if (pageNo > 4)>
				<#assign start=(pageNo - 2)>
				<a href="javascript:page(1)">1</a>
				<span style='color:#444693;'>...</span>
			</#if>
			<#-- 显示当前页号和它附近的页号 -->
			<#assign end=(pageNo + 2)>
			<#if (end > pageCount)>
				<#assign end=pageCount>
			</#if>
			<#list start..end as i>
				<#if (pageNo==i)>
					<span ><a  class="dq">${i}</a></span>
				<#else>
				    <span><a href="javascript:page(${i})">${i}</a></span>
				</#if>
			</#list>
			<#-- 如果后面页数过多,显示... -->
			<#if (end < pageCount - 1)>
				<span style='color:#444693;'>...</span>
			</#if>
			<#if (end < pageCount)>
				<a href="javascript:page(${pageCount})">${pageCount}</a>
			</#if>
			<#-- 下一页处理 -->
			<#if (pageNo == pageCount)>
				<span class="disabled"><a >下一页</a></span>
			<#else>
				<span>
				<a href="javascript:page(${pageNo + 1})">下一页</a>
				</span>
			</#if>
		</form>
		<script language="javascript">
			function page(no){
				var $qForm=$("form[name='qPagerForm']");
				$qForm.find("input[name='page']").val(no);
				$qForm.submit();
			}
		</script>
	</div> 
</#macro>

 

    我们只需将分页的结果对象传入页面,分页对象包括:分页的结果数据,当前页号,每页要显示的条数,总页数。

    

@RequestMapping(value="userList")
	public String userList(ModelMap modelMap,@RequestParam(defaultValue="1") int page){
		int pageSize = 8;
		Pagination p = userDmn.find(page, pageSize, "from User");
		modelMap.put("p", p);
		return "page/userList";
	}

    然后将数据循环在页面,页面调用分页宏

<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<script type="text/javascript" src="../js/jquery-1.7.1.min.js"></script>
<style type="text/css">
.page{height:30px; line-height:30px; margin:20px 0; clear:both;}
.page a{color:#444693; font-size:14px; border:1px solid #eeeeee; padding:5px 8px;text-decoration: none}
.page a.dq{background:#444693; padding:5px 8px; color:#fff;}
</style>
</head>
<body>
	<table>
		<tr>
			<th>ID</th>
			<th>用户名</th>
			<th>密码</th>
		</tr>
		<#list p.list as user>
			<tr>
			   <td>${user.id}</td>
			   <td>${user.name}</td>
			   <td>${user.pwd}</td>
			</tr>
		</#list>
	</table>
		<#import "../../page/pager.ftl" as page/>
		<@page.pager pageNo=p.pageNo pageSize = p.pageSize toURL="../user/userList" pageCount=p.getTotalPage()/>
</body>
</html>

    效果图:

     

 
 当我们在进行开发是,页面要引入许多js和css,特别是一些公用的文件,在此我们可以将这些代码写到一个宏中,要用的话就直接调用宏。

  

<#macro frontJs>
	<script type="text/javascript" src="../js/jquery-1.7.1.min.js"></script>
</#macro>

    在页面上调用宏

    

<#import "../../page/spring.ftl" as spring/>
<@spring.frontJs />

   

     就这样我们在页面中引入了js文件。
    当然我们在每个页面中都去写一个<#import />确实有点不爽,freemarker配置中有个属性叫                auto_import,,      叫做自动导入,

    

auto_import=spring.ftl as spring

   

     在此我们就不用引入spring.ftl文件了,因为已经自动导入了,现在我们在每个页面都可以直接使用,我们可以写一些常用的宏在ftl文件中,再自动导入。

   

<@spring.frontJs />

   

          在页面中往往有相同的主菜单和左菜单,脚部,我们都可以用这种方式来包含html代码。

   当然我们也可以用

   

<#include />

         来包含相同的html页面

 

   freemarker获取request对象

<bean id="viewResolver"
		class="org.springframework.web.servlet.view.freemarker.FreeMarkerViewResolver">
		<property name="viewClass"
			value="org.springframework.web.servlet.view.freemarker.FreeMarkerView" />
		<property name="prefix" value="/" />
		<property name="suffix" value=".html" />
		<property name="contentType" value="text/html;charset=utf-8" />
		<property name="requestContextAttribute" value="rc" />
		<property name="exposeRequestAttributes" value="true" />
		<property name="exposeSessionAttributes" value="true" />
		<property name="exposeSpringMacroHelpers" value="true" />
	</bean>

         在配置文件中加入一句

<property name="requestContextAttribute" value="rc" />

         这样就可以在页面中使用request对象了

${rc.contextPath}

   获取Session

User user = new User();
		user.setId(1);
		user.setName("li");
		user.setPwd("pwd");
		session.setAttribute("user",user );
${Session["user"].name}

    获取Session中user对象中的name值

 

   


标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!