说了那么多JSP,最终我们的CMS使用的还是FreeMarker,下面是对这个框架的介绍。与前文的JSP做一个对比。
FreeMarker是一个模板引擎,相对于JSP,它做到更好的前后端分离,在模板中,是没有Java代码,减少了耦合,准确来说,FreeMarker是独立的,他和Java,Servlet无关。
这类模板引擎常用的一般有:JSP, FreeMarker, velocity
大多数情况下,JSP就可以满足我们的需求,对于小网站且分工不明确的企业,不需要做到前后分离。
而velocity做到了前后端分离,且性能较好,是小网站的不错选择。
但是,当网站变得极其复杂的时候,FreeMarker的性能相对是最好的,且支持JSP标签以及大量常用的功能,是个相当不错的选择。
下面说说FreeMarker的使用。
1.FreeMarker页面的组成
FreeMarker和HTML语言很类似,都是有起始和结束标签将内容包含起来
其中一般有四个部分:
类型 | 作用 | 案例 |
---|---|---|
1.文本内容 | 直接输出到视图上的内容 | 例如一个ftl文件中的html代码等 |
2.注释 | ftl里面的注释,不会输出,也不会变成HTML里面的注释 | <#– … –> |
3.插值 | 用来插入变量或者数据模型,简单来说就是替换数据 | ${…}或#{…} |
4.ftl指令 | 执行一些操作,这个会详细说 | #… |
知道了这四个,大纲基本上就出来了,其余的都是一些类似于宏定义的高级操作了。
FTL标签有以下需要注意的地方
FTL是区分大小写的。 list 是指令的名称而 List 就不是。
类似地 name和 n a m e 和 {Name} 或 ${NAME} 也是不同的。请注意非常重要的一点: 插值 仅仅可以在 文本 中使用。
FTL 标签 不可以在其他 FTL 标签 和 插值中使用。
比如, 这样做是 错误 的: <#if <#include ‘foo’>=’bar’>…<\/#if>注释 可以放在 FTL 标签 和 插值中
FreeMarker的标签通常有两种,开始标签和结束标签
FreeMarker的指令通常有两种,一种是自带的预定义标签,一种是用户自定义标签
- 预定义指令 用#开头
- 用户自定义指令 用@开头
请注意,FreeMarker 仅仅关心FTL标签的嵌套而不关心HTML标签的嵌套。
它只会把HTML看做是文本,不会来解释HTML。
如果你尝试使用一个不存在的指令(比如,输错了指令的名称), FreeMarker 就会拒绝执行模板,同时抛出错误信息。
FreeMarker会忽略FTL标签中多余的 空白标记。
2.FreeMarker的使用逻辑
和JSP相同,用一个公式来说:
输出=模板+数据模型
FreeMarker的数据模型成树状,类似于文件夹的结构:
(root)
|
+- user = "ant"
|
+- latestProduct
|
+- url = "index.html"
|
+- name = "black"
//取出数据:(我们完全可以把一级节点看成一个对象)
user
latestProduct.name
还有一种其他的样式:
(root)
|
+- animals
| |
| +- (1st)
| | |
| | +- name = "mouse"
| | |
| | +- size = "small"
| | |
| | +- price = 50
| |
| +- (2nd)
| | |
| | +- name = "elephant"
| | |
| | +- size = "large"
| | |
| | +- price = 5000
| |
| +- (3rd)
| |
| +- name = "python"
| |
| +- size = "medium"
| |
| +- price = 4999
|
+- misc
|
+- fruits
|
+- (1st) = "orange"
|
+- (2nd) = "banana"
//他有节点,但是没给节点名,此时就需要使用
animals[0].name
//注意,数组,或者List的起始是0
其中支持这些数据类型:
标量:
字符串
数字
布尔值
日期/时间 (日期,时间或日期时间)
容器:
哈希表
序列
集合
子程序:
方法和函数
其他:
节点
、
4.FreeMarker的使用小案例
在Maven使用JSP,肯定是要导入依赖的
<dependency>
<groupId>org.freemarker</groupId>
<artifactId>freemarker</artifactId>
<version>2.3.20</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context-support</artifactId>
<version>3.2.4.RELEASE</version>
</dependency>
前台:
<!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=ISO-8859-1">
<title>Insert title here</title>
</head>
<body>
Hello ${name}
</body>
</html>
后台:
package com.cms.controller;
import java.util.Date;
import java.util.HashMap;
import java.util.LinkedList;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.servlet.ModelAndView;
import com.cms.entity.User;
/**
*@author:gang
*@version:
**/
@Controller
@RequestMapping("/test")
public class FtlTest {
String name = "ant-black";
String id="11111";
int age = 22;
Date date = new Date();
User user = new User();
HashMap<String, String> ftlMap = new HashMap<String, String>();
LinkedList<String> ftlList = new LinkedList<String>();
String[][] arry={{"S1","S2","S3"},{"S4","S5","S6"}};
@RequestMapping("/ftltest")
public ModelAndView ftlTest(){
ModelAndView modelAndView = new ModelAndView();
modelAndView.addObject("name", name);
modelAndView.setViewName("ftltest");
return modelAndView;
}
}
配置:
可以看到,整合到Spring中后,其实和JSP的配置没有多大区别
<!-- 配置freeMarker的模板路径 -->
<bean class="org.springframework.web.servlet.view.freemarker.FreeMarkerConfigurer">
<property name="templateLoaderPath" value="/WEB-INF/static/ftl/" />
<property name="defaultEncoding" value="UTF-8" />
</bean>
<!-- freemarker视图解析器 -->
<bean class="org.springframework.web.servlet.view.freemarker.FreeMarkerViewResolver">
<property name="suffix" value=".ftl" />
<property name="contentType" value="text/html;charset=UTF-8" />
<!-- 此变量值为pageContext.request, 页面使用方法:rc.contextPath -->
<property name="requestContextAttribute" value="rc" />
</bean>
5.FreeMarker与JSP整合
当然,我们不仅仅是只要这一个,我们还需要在其他页面使用JSP
看看我改了什么:
<!-- 定义跳转的文件的前后缀 ,视图模式配置-->
<bean class="org.springframework.web.servlet.view.InternalResourceViewResolver">
<!-- 这里的配置我的理解是自动给后面action的方法return的字符串加上前缀和后缀,变成一个 可用的url地址 -->
<property name="order" value="1"></property>
<property name="prefix" value="/WEB-INF/static/cms/" />
<property name="suffix" value=".jsp" />
</bean>
<!-- 配置freeMarker的模板路径 -->
<bean class="org.springframework.web.servlet.view.freemarker.FreeMarkerConfigurer">
<property name="templateLoaderPath" value="/WEB-INF/static/ftl/" />
<property name="defaultEncoding" value="UTF-8" />
</bean>
<!-- freemarker视图解析器 -->
<bean class="org.springframework.web.servlet.view.freemarker.FreeMarkerViewResolver">
<property name="order" value="0"></property>
<property name="suffix" value=".ftl" />
<property name="contentType" value="text/html;charset=UTF-8" />
<!-- 此变量值为pageContext.request, 页面使用方法:rc.contextPath -->
<property name="requestContextAttribute" value="rc" />
</bean>
加入了:
这是我认为最简单的一种方法,按顺序查找,当然,还有其他的一些办法可以去看看这个博客:
链接
6.总结
FreeMarker先梳理到这里,后面再说说宏定义和FTL指令。
7.附件
参考:
http://www.oschina.net/p/freemarker
http://demojava.iteye.com/blog/800204
http://freemarker.foofun.cn/dgui_template_exp.html#dgui_template_exp_direct