1. 前置技术: FreeMarker
1.1 FreeMarker 介绍
1.1.1 模板引擎
只是根据模板的内容,将数据模型在模板中显示并输出文件(通常为html,也可以生成其它格式的文本文件)
- 数据模型:数据模型在java中可以是基本类型也可以List、Map、Pojo等复杂类型
- 模板
- 输出
1.1.2 常见的模板引擎
1.1.3 freemarker 概述
FreeMarker是一个模板引擎,一个基于模板生成文本输出的通用工具,使用纯Java编写
FreeMarker被设计用来生成HTML Web页面,特别是基于MVC模式的应用程序
虽然FreeMarker具有一些编程的能力,但通常由Java程序准备要显示的数据,由FreeMarker生成页面,通过模板显示准备的数据(如下图)
FreeMarker不是一个Web应用框架,而适合作为Web应用框架一个组件
FreeMarker与容器无关,因为它并不知道HTTP或Servlet;FreeMarker同样可以应用于非Web应用程序环境
FreeMarker更适合作为Model2框架(如Struts)的视图组件,你也可以在模板中使用JSP标记库
FreeMarker是免费的
而且你还可以通过Eclipse的插件来编辑FreeMarker,经过验证,FreeMarker 最好的 Eclipse 编辑插件是 JBoss Tools
1.2 FreeMarker快速入门
- 步骤一:编写controller,需要使用@Controller
package com.czxy.xuecheng.controller;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.GetMapping;
@Controller //注意:不能使用@RestController,需要返回一个视图(找页面)
public class FreeMarkerController {
@GetMapping("/testpath")
public String testMethod(){
return "test";
}
}
- 步骤二:编写视图页面
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
第一个页面
</body>
</html>
2.1 模型数据
- FreeMarker从spring mvc的
模型
中获得数据,并进行解析
2.1.1 标准 handler
- 步骤一:编写标准handler,返回值类型 ModelAndView
/**
* 使用modelandview创建视图
* @return
*/
@GetMapping("/model1")
public ModelAndView model1(){
// 创建一个新的modelandview
ModelAndView modelAndView = new ModelAndView();
// 设置数据
HashMap<String, String> map = new HashMap<>();
map.put("name","陈晨");
map.put("age","20");
modelAndView.addObject("user",map);
modelAndView.setViewName("model1");
return modelAndView;
}
- 步骤二:编写模板,根据view名称确定页面名称
姓名: ${user.name}<br/>
年龄: ${user.age}
2.1.2 返回视图名
- 方法的返回值,就是视图名
- 在通过方法参数,获得Model
- spring mvc 底层将
视图
和模型
组合在一起,自动生成ModelAndView,返归到方式1 - 步骤一:编写方法:返回值 + Model
/**
* 使用Model创建视图
* @param model
* @return
*/
@GetMapping("/model2")
public String model2(Model model){
HashMap<String, String> map = new HashMap<>();
map.put("name","陈晨");
map.put("age","20");
model.addAttribute("user",map);
return "model2";
}
- 步骤二:编写模板
姓名: ${user.name}<br/>
年龄: ${user.age}
2.1.3 自定义数据(解耦)
- 返回值为视图名
- 方法参数为自定义内容,使用Map可以编写
键值对
- 步骤一:编写方法,返回值 + 自定义数据
/**
* 自定义数据
* @param map
* @return
*/
@GetMapping("/model3")
public String model3(Map map){
HashMap<String, String> mp = new HashMap<>();
mp.put("name","陈晨");
mp.put("age","20");
map.put("user",mp);
return "model3";
}
- 步骤二:编写视图(页面)
姓名: ${user.name}<br/>
年龄: ${user.age}
2.2 常见指令
2.2.1 list指令
- 语法
<#list 集合 as 变量>
</#list>
-
步骤一:编写JavaBean,User对象(username,password,age)及其构造
-
步骤二:编写controller,List集合存放一组数据
/**
* 集合模型数据
* @param model
* @return
*/
@GetMapping("/list")
public String list(Model model){
ArrayList<User> list = new ArrayList<>();
list.add(new User("陈晨","1234",20));
list.add(new User("陈纪成","4321",20));
model.addAttribute("alluser",list);
return "list";
}
- 步骤三:编写模板,list.ftl
<#list alluser as user>
${user_index + 1}--${user.username}--${user.password}--${user.age}<br/>
</#list>
2.2.2 遍历 Map集合
- 数据获取方式:
//通过 . 依次获得
语法:${集合变量.key值.属性名}
例如:${allUser.user1.username}
//通过 [] 获得,允许[]中使用变量,如果是字符串需要使用引号
语法:${集合变量['key值'].属性名}
例如:${allUser['user1'].username}
- 获得map的所有key
语法:集合变量?keys
- 步骤一:编写controller,Model + Map<String,User>
/**
* map添加模型数据
* @param model
* @return
*/
@GetMapping("/map")
public String map(Model model){
HashMap<String, User> map = new HashMap<>();
map.put("user1",new User("陈晨","1234",20));
map.put("user2",new User("陈纪成","4321",20));
model.addAttribute("alluser",map);
return "map";
}
- 步骤二:编写模板,通过遍历map的key,遍历map数据
<#list alluser?keys as k>
${k}--${alluser[k].username}--${alluser[k].password}--${alluser[k].age}<br/>
</#list>
2.2.3 if指令
- 语法
<#if 条件>
</#if>
- 步骤一: 编写Controller
/**
* if标签添加模型数据
* @param model
* @return
*/
@GetMapping("/if")
public String _if(Model model){
model.addAttribute("token",1234);
model.addAttribute("token2",4321);
return "if";
}
- 步骤二:编写模板
<#if token = 1234>
token是1234
</#if><br/>
<#if token2 != 1234>
token2不是1234
</#if>
错误演示
2.2.4 空值处理
-
变量??
,如果不为空返回true,如果为空返回false-
不为空处理
<#if token?? > token不为空 </#if>
-
为空处理
<#if !token2?? > token2为空 <br/> </#if>
-
2.2.5 默认值
//语法
变量!默认值
- 实例
${token3!'3的默认值'} <br/>
2.2.6 内建函数
- 语法
变量?函数
- 步骤一:修改pom,添加fastjson依赖
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>fastjson</artifactId>
<version>1.2.67</version>
</dependency>
- 步骤二:准备数据
/**
* 内建函数
* @param model
* @return
*/
@GetMapping("/method")
public String method(Model model){
ArrayList<String> list = new ArrayList<>();
list.add("陈晨");
list.add("优秀");
model.addAttribute("list",list);
model.addAttribute("birthday",new Date());
model.addAttribute("money",99999);
model.addAttribute("user",new User("陈晨","1234",20));
return "method";
}
- 步骤三:ftl模板显示
${list?size}<br/>
显示年月日:${birthday?date}<br/>
显示时分秒:${birthday?time}<br/>
显示日期+时间:${birthday?datetime}<br/>
自定义时间:${birthday?string("yyyy年MM月")}<br/>
用户名:${user.username}<br/>
密码:${user.password}<br/>
${money}<br/>
${money?c}<br/>
${user}<br/>
2.3 静态化
2.3.1 模板文件静态化
- 模板文件
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
${name}
</body>
</html>
- 生产静态化页面
package com.czxy.xuecheng;
import freemarker.template.Template;
import org.apache.commons.io.FileUtils;
import org.junit.Test;
import org.springframework.ui.freemarker.FreeMarkerTemplateUtils;
import java.io.File;
import java.util.HashMap;
public class FreeMarketTest {
@Test
public void FreeMarketTest() throws Exception{
// 创建配置类
freemarker.template.Configuration configuration = new freemarker.template.Configuration(freemarker.template.Configuration.getVersion());
// 设置模板路劲
String classpath = this.getClass().getResource("/").getPath();
File templatesDir = new File(classpath, "/templates/");
configuration.setDirectoryForTemplateLoading(templatesDir);
// 设置字符集
configuration.setDefaultEncoding("UTF-8");
// 加载模板
Template template = configuration.getTemplate("test.ftl");
// 创建模型数据
HashMap<String, Object> map = new HashMap<>();
map.put("name","FreeMarket整合文件静态化");
// 静态化
String content = FreeMarkerTemplateUtils.processTemplateIntoString(template, map);
// 输出
File file = new File(templatesDir, "test.html");
System.out.println(file.getAbsolutePath());
FileUtils.writeStringToFile(file,content);
}
}
- 测试结果
2.3.2 模板字符串静态化
- 定义模板字符串,使用freemarker静态化程序生成html文件
package com.czxy.xuecheng;
import freemarker.cache.StringTemplateLoader;
import freemarker.template.Configuration;
import freemarker.template.Template;
import org.apache.commons.io.FileUtils;
import org.junit.Test;
import org.springframework.ui.freemarker.FreeMarkerTemplateUtils;
import java.io.File;
import java.util.HashMap;
public class GenerateHtmlByStringTest {
@Test
public void GenerateHtmlByStringTest() throws Exception {
// 模板字符串
String templatesString =
"<html>" +
" <head>" +
" <meta charset=\"UTF-8\">" +
" <title>标题</title>" +
" </head>" +
" <body>" +
" ${name}" +
// " </body>" +
"</html>";
// 加载模板
StringTemplateLoader stringTemplateLoader = new StringTemplateLoader();
stringTemplateLoader.putTemplate("myTemplate",templatesString);
// 创建配置类
Configuration configuration = new Configuration(Configuration.getVersion());
configuration.setTemplateLoader(stringTemplateLoader);
// 获得模板
Template template = configuration.getTemplate("myTemplate", "UTF-8");
//创建模型数据
HashMap<String, Object> map = new HashMap<>();
map.put("name","静态文件测试代码");
// 静态化
String content = FreeMarkerTemplateUtils.processTemplateIntoString(template, map);
// 输出
String classpath = this.getClass().getResource("/").getPath();
File templateFile = new File(classpath, "/templates/");
System.out.println(templateFile.getAbsolutePath());
FileUtils.writeStringToFile(templateFile,content);
}
}