目录
FreeMarker
什么是 FreeMarker? - FreeMarker 中文官方参考手册
1.主要内容
2.FreeMarker概述
2.1FreeMarker概念
2.2FreeMarker特性
2.2.1.通用目标
2.2.2.强大的模板语言
2.2.3.通用的数据模型
2.2.4.为Web准备
2.2.5.智能的国际化和本地化
2.2.6.强大的XML处理能力
2.3FreeMarker环境搭建
2.3.1.新建环境项目
pom.xml文件
<?xml version="1.0" encoding="UTF-8"?> <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.example</groupId> <artifactId>ferrmarker</artifactId> <version>1.0-SNAPSHOT</version> <packaging>war</packaging> <name>ferrmarker Maven Webapp</name> <!-- FIXME change it to the project's website --> <url>http://www.example.com</url> <properties> <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding> <maven.compiler.source>1.8</maven.compiler.source> <maven.compiler.target>1.8</maven.compiler.target> </properties> <dependencies> <!-- freemarker的坐标依赖 --> <dependency> <groupId>org.freemarker</groupId> <artifactId>freemarker</artifactId> <version>2.3.23</version> </dependency> <!-- servlet-api的坐标依赖 --> <dependency> <groupId>javax.servlet</groupId> <artifactId>javax.servlet-api</artifactId> <version>3.0.1</version> </dependency> </dependencies> <build> <finalName>ferrmarker</finalName> <!-- 插件地址: Tomcat http://tomcat.apache.org/maven-plugin-2.2/ Jetty https://www.eclipse.org/jetty/documentation/current/jetty-mavenplugin. html --> <plugins> <!-- 配置jetty插件 --> <plugin> <groupId>org.eclipse.jetty</groupId> <artifactId>jetty-maven-plugin</artifactId> <version>9.2.1.v20140609</version> </plugin> </plugins> </build> </project>
web.xml文件
<!DOCTYPE web-app PUBLIC "-//Sun Microsystems, Inc.//DTD Web Application 2.3//EN" "http://java.sun.com/dtd/web-app_2_3.dtd" > <web-app> <!-- FreeMarker的servlet配置--> <display-name>Archetype Created Web Application</display-name> <servlet> <servlet-name>freemarker</servlet-name> <servlet-class>freemarker.ext.servlet.FreemarkerServlet</servlet-class> <init-param> <!-- 模板路径--> <param-name>TemplatePath</param-name> <param-value>/</param-value> </init-param> <init-param> <!-- 模板默认的编码:UTF-8 --> <param-name>default_encoding</param-name> <param-value>UTF-8</param-value> </init-param> </servlet> <!-- 处理所有以.ft结尾的文件;ftl是free marker默认的文件后缀--> <servlet-mapping> <servlet-name>freemarker</servlet-name> <url-pattern>*.ftl</url-pattern> </servlet-mapping> </web-app>
参考网站:
运行成功
跟着教程一步一步来就好了
【优极限】JavaWeb-FreeMarker_超详细视频教程(由浅入深细致讲解,FreeMarker纯干货课程),FreeMarker美女程序员授课完整版_哔哩哔哩_bilibili
然后就是第一遍做没做出来,第二遍就好了呀
第一遍的问题
问题(1)
工作名和组名那里要改正
问题(2)
jetty:run -Djetty.port=9090
run后面是个空格然后才是-
3.FreeMarker的数据类型
3.1布尔类型
package com.xxxx.servlet; import javax.servlet.ServletException; import javax.servlet.annotation.WebServlet; import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import java.io.IOException; /** * @author yanchaochao * @date 2022/1/29 19:40 */ @WebServlet("/f02") public class FreeMarker02 extends HttpServlet { @Override protected void service(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { //设置数据 /*布尔类型*/ req.setAttribute("flag",true); req.getRequestDispatcher("template/f02.ftl").forward(req,resp); }
f02.ftl文件
<h4>FreeMarker 数据类型</h4> <#-- FreeMarker 数据类型 布尔书数据类型 不能在FreeMarker直接输出,如果要输出需要转换成字符串 方式一:?c 方式二:?string或?string(‘为true显示的内容’,为false时显示的内容) --> <h5>布尔类型</h5> ${flag?c}<br> ${flag?string}<br> ${flag?string('yes','no')}<br> ${flag?string('俺喜欢','她不中')}<br>
<#-- FreeMarker 数据类型 布尔书数据类型 不能在FreeMarker直接输出,如果要输出需要转换成字符串 方式一:?c 方式二:?string或?string(‘为true显示的内容’,为false时显示的内容) -->
3.2.日期类型
<#-- FreeMarker 数据类型 日期类型 不能在FreeMarker日期类型中直接输出,如果要输出需要转换成日期型或字符串 1.年月日: ?date 2.时分秒: ?time 3.年月日时分秒: ?datetime 4.自定义格式: ?string(”自定义") y年 M月 d日 H时 m分 s秒 -->
eg:FreeMarker.java文件
package com.xxxx.servlet; import javax.servlet.ServletException; import javax.servlet.annotation.WebServlet; import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import java.io.IOException; import java.util.Date; /** * @author yanchaochao * @date 2022/1/29 19:40 */ @WebServlet("/f02") public class FreeMarker02 extends HttpServlet { @Override protected void service(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { //设置数据 /*日期类型*/ req.setAttribute("createDate",new Date()); //请求转发到指定的模板页面--------template/f02.ftl req.getRequestDispatcher("template/f02.ftl").forward(req,resp); } }
f02.ftl文件
<h4>FreeMarker--数据类型</h4> <h5>布尔类型</h5> ${flag?c}<br> ${flag?string}<br> ${flag?string('yes','no')}<br> ${flag?string('俺喜欢','她不中')}<br> <#--、--> <#----> <#-- FreeMarker 数据类型 日期类型 不能在FreeMarker日期类型中直接输出,如果要输出需要转换成日期型或字符串 1.年月日: ?date 2.时分秒: ?time 3.年月日时分秒: ?datetime 4.自定义格式: ?string(”自定义") y年 M月 d日 H时 m分 s秒 --> <h5>日期类型</h5> ${createDate?date}<br> ${createDate?time}<br> ${createDate?datetime}<br> ${createDate?string("yyy/MM/dd HH:mm:ss")}<br> <#--根据自己的需求格式输出结果-->
3.3.数值类型
eg:FreeMarker.java文件
/*数值类型*/ req.setAttribute("age",18); req.setAttribute("num",10000); req.setAttribute("avg",5.5467);
f02.ftl文件
<h5>数值类型</h5> ${age}<br> ${num}<br> ${avg}<br> <#--将数值转化成字符串类型--> ${age?c}<br> <#--将数值转化成货币类型--> ${num?string.currency}<br> <#--将数值转化为百分比类型的字符串--> ${num?string.percent}<br> <#--将浮点型的数值转化成指定小数输出--> ${avg?string["0.##"]}
3.4.字符串类型
eg:FreeMarker.java文件
/*字符串类型*/ req.setAttribute("msg","hello"); req.setAttribute("msg2","freemarker");
f02.ftl文件
<h5>字符串类型</h5> ${msg} ${msg2} <#--1.截取字符串--> ${msg?substring(0,2)}<br> <#--2.首字母小写--> ${msg?uncap_first}<br> <#--3.首字母大写--> ${msg?cap_first}<br> <#--4.字母转小写输出--> ${msg?lower_case}<br> <#--5.字母转大写输出--> ${msg?upper_case}<br> <#--6.获取字符串的长度--> ${msg?length}<br> <#--7.是否以指定字符开头--> ${msg?starts_with("a")?string}<br> <#--8.是否以指定字符结尾--> ${msg?ends_with("o")?string}<br> <#--9.获取指定字符的索引--> ${msg?index_of("m")}<br> <#--10.去除字符串前后的空格--> ${msg?trim}<br> <#--11.替换字符串--> ${msg?replace("he","we")}<br> <h5>字符串类型</h5> ${msg} ${msg2} <#--1.截取字符串--> ${msg?substring(0,2)}<br> <#--2.首字母小写--> ${msg?uncap_first}<br> <#--3.首字母大写--> ${msg?cap_first}<br> <#--4.字母转小写输出--> ${msg?lower_case}<br> <#--5.字母转大写输出--> ${msg?upper_case}<br> <#--6.获取字符串的长度--> ${msg?length}<br> <#--7.是否以指定字符开头--> ${msg?starts_with("a")?string}<br> <#--8.是否以指定字符结尾--> ${msg?ends_with("o")?string}<br> <#--9.获取指定字符的索引--> ${msg?index_of("m")}<br> <#--10.去除字符串前后的空格--> ${msg?trim}<br> <#--11.替换字符串--> ${msg?replace("he","we")}<br>
字符串空值情况处理
3.5.sequence类型
1.数组
eg:FreeMarker.java文件
//数组 String[] stars = new String[]{"周杰伦","林俊杰","五月天","陈奕迅"}; req.setAttribute("stars",stars);
f02.ftl文件
<#--数组操作--> <#list stars as stars> ${stars}<br> </#list> 获取序列长度:${stars?size}<br> 获取第一个元素:${stars?first}<br> 获取最后一个元素:${stars?last}<br> <hr>
2.list
eg:FreeMarker.java文件
//List操作 List<String> citys = Arrays.asList("北京","上海","杭州","深圳"); req.setAttribute("cityList",citys);
f02.ftl文件
<#--list操作--> <#list cityList as city> ${city} - </#list> <hr> <#--排序--> <#--倒序输出--> <#list cityList?reverse as city> ${city} - </#list> <hr> <#--升序输出--> <#list cityList?sort as city> ${city} - </#list> <hr> <#--降序输出--> <#list cityList?sort?reverse as city> ${city} - </#list> <hr> <hr> <#list userList as user> 编号:${user.userId} 姓名:${user.uname} 编号:${user.uage} <br> </#list> <hr>
3.JavaBean的排序
eg:FreeMarker.java文件
//JavaBean集合 List<User> userList = new ArrayList<>(); userList.add(new User(1,"张三",22)); userList.add(new User(2,"李四",18)); userList.add(new User(3,"王五",20)); req.setAttribute("userList",userList);
User文件
package com.xxxx.servlet.entity; /** * @author yanchaochao * @date 2022/1/30 1:43 */ public class User { private Integer userId; private String uname; private Integer uage; public User() { } public User(Integer userId, String uname, Integer uage) { this.userId = userId; this.uname = uname; this.uage = uage; } public Integer getUserId() { return userId; } public void setUserId(Integer userId) { this.userId = userId; } public String getUname() { return uname; } public void setUname(String uname) { this.uname = uname; } public Integer getUage() { return uage; } public void setUage(Integer uage) { this.uage = uage; } }
f02.ftl文件
<#--JavaBean的排序--> <#list userList?sort_by("uage") as user> 编号:${user.userId} 姓名:${user.uname} 编号:${user.uage} <br> </#list>
3.6hash类型
eg:FreeMarker.java文件
//Map操作 Map<String,String> cityMap = new HashMap<>(); cityMap.put("sh","上海"); cityMap.put("bj","北京"); cityMap.put("sz","深圳"); req.setAttribute("cityMap",cityMap);
f02.ftl文件
<#--Hash--> <#list cityMap? keys as key> ${key} - ${cityMap[key]} </#list> <br> <#list cityMap? values as value> ${value} </#list> <br>
4.FreeMarker常见指令
4.1.assign自定义变量指令
<#assign name1=value1 name2=value2 ... nameN=valueN> 或 <#assign same as above... in namespacehash> 或 <#assign name> capture this </#assign> 或 <#assign name in namespacehash> capture this </#assign>
4.2.if, else, elseif
eg:FreeMarker03.java文件
package com.xxxx.servlet; /** * @author yanchaochao * @date 2022/1/30 2:35 */ import com.xxxx.servlet.entity.User; import javax.net.ssl.ManagerFactoryParameters; import javax.servlet.ServletException; import javax.servlet.annotation.WebServlet; import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import java.io.IOException; import java.util.*; @WebServlet("/f03") public class FreeMarker03 extends HttpServlet { @Override protected void service(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { //请求转发到指定的模板页面--------template/f03.ftl req.getRequestDispatcher("template/f03.ftl").forward(req,resp); } }
f02.ftl文件
<#--if, else, elseif--> <#assign score=60> <#if score lt 60> <h6>你个小渣渣</h6> <#elseif score == 80> <h6>分不在高,及格就行</h6> <#elseif score gt 60 &&score lt 80 > <h6>革命尚未成功,同志仍需努力</h6> <#else > <h6>哎呦不错哦!</h6> </#if> <#--判断数据是否存在--> <#assign list=""> <#if list??> 数据存在 <#else > 数据不存在 </#if>
4.3.list指令
eg:FreeMarker03.java文件
package com.xxxx.servlet; /** * @author yanchaochao * @date 2022/1/30 2:35 */ import com.xxxx.servlet.entity.User; import javax.net.ssl.ManagerFactoryParameters; import javax.servlet.ServletException; import javax.servlet.annotation.WebServlet; import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import java.io.IOException; import java.util.*; @WebServlet("/f03") public class FreeMarker03 extends HttpServlet { @Override protected void service(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { //请求转发到指定的模板页面--------template/f03.ftl req.getRequestDispatcher("template/f03.ftl").forward(req,resp); } }
f02.ftl文件
<#--list指令--> <hr> <#assign users = ["张三","李四","王五"]> <#list users as user> ${user} | </#list> <br> <#--判断数据不为空,再执行遍历(如果序列不存在,直接遍历会报错)--> <#if user2??> <#list users2 as user> ${user} </#list> </#if> <#assign users3=['a']> <#list users3 as user> ${user} <#else > 用户数据不存在! </#list>
4.4.macro自定义指令
<#--macro自定义指令--> <#macro address> 这个就是自定义的指令 </#macro> <#--使用自定义指令--> <@address></@address> <@address></@address> <@address></@address> <hr> <#--自定义有参数的指令--> <#macro queryUserByName uname> 通过用户名查询用户对象-${uname} </#macro> <@queryUserByName uname="admin"></@queryUserByName> <hr> <#macro queryUserByName02 uname upwd phone> 通过用户名查询用户对象-${uname}-${upwd}-${phone} </#macro> <@queryUserByName02 uname="张三" upwd= "123456" phone="666"></@queryUserByName02> <hr> <hr> <#--做一个九九乘法表--> <#macro cfb> <#list 1..9 as i> <#list 1..i as j> ${j} * ${i} = ${j*i} </#list> <br> </#list> </#macro> <@cfb></@cfb> <#--升级九九乘法表--> <#macro cfb02 num> <#list 1..num as i> <#list 1..i as j> ${j} * ${i} = ${j*i} </#list> <br> </#list> </#macro> <@cfb02 num=5></@cfb02>
4.5.nested占位指令
<#--占位指令--> <#macro test> <#nested > <br> 这是一段文本 <#nested > </#macro> <@test>xxxxxxxxxx</@test>
4.6.import导入指令
eg:FreeMarker04.java文件
package com.xxxx.servlet; /** * @author yanchaochao * @date 2022/1/30 11:24 */ import javax.servlet.ServletException; import javax.servlet.annotation.WebServlet; import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import java.io.IOException; @WebServlet("/f04") public class FreeMarker04 extends HttpServlet { @Override protected void service(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { //请求转发到指定的模板页面--------template/f03.ftl req.getRequestDispatcher("template/f04.ftl").forward(req,resp); } }
f04.ftl文件
<#--通过import指令引入命令空间--> <#--引用f03文件中的--> <#import "f03.ftl" as f3> <@f3.cfb></@f3.cfb> <hr> <#--设置一个通用文件调用--> <#import "commons.ftl" as cm> <@cm.cfb02 num =5></@cm.cfb02>
commons.ftl文件
<#macro cfb02 num> <#list 1..num as i> <#list 1..i as j> ${j} * ${i} = ${j*i} </#list> <br> </#list> </#macro> <@cfb02 num=5></@cfb02>
4.7.include包含指令
f04.ftl文件
<#--包含指令--> <#--html文件--> <#include "tset.html">
tset.html文件
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>包含</title> </head> <body> Hello </body> </html>
5.FreeMarker页面静态化
5.1.定义模板
5.2加载模板
NewsServlet.java文件
import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import java.io.File; import java.io.FileWriter; import java.io.IOException; import java.util.HashMap; import java.util.Map; /** * @author yanchaochao * @date 2022/1/30 11:50 */ @WebServlet("/news") public class NewsServlet extends HttpServlet { @Override protected void service(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { //实例化模板对象 Configuration configuration = new Configuration(); //设置加载模板的上下文 以及模板的加载路径(模板的存放路径) configuration.setServletContextForTemplateLoading(getServletContext(), "/template"); //设置模板的编码格式 configuration.setDefaultEncoding("UTF-8"); //加载模板文件 获取模板对象 Template template = configuration.getTemplate("news.ftl"); //设置数据模型 Map<String, Object> map = new HashMap<>(); map.put("title", "国务院联防联控机制:坚决防止春节返乡政策“一刀切”"); map.put("source", "光明网-《光明日报》"); map.put("pubTime", "2022-01-30 03:41"); map.put("content", "春节将至,一些群众返乡遇阻引发社会关注,国家卫健委新闻发言人米锋在1月29日国务院联防联控机制举行的发布会上表示,国务院联防联控机制综合组已进行核实,并及时反馈地方,要求立即整改,坚决防止返乡政策“简单化一刀切,让广大群众度过一个健康、欢乐、祥和的春节。"); //获取项目的根目录 String basePath = req.getServletContext().getRealPath("/"); //设置html的存放路径 File htmlFile = new File(basePath + "/html"); //判断文件(目录)是否存在 if (!htmlFile.exists()) { //如果文件目录不存在,则新建文件目录 htmlFile.mkdir(); } //得到生成的文件名(生成随机不重复的文件名) String fileName = System.currentTimeMillis() + ".html"; //创建html文件 File file = new File(htmlFile, fileName); //获取文件输出流 FileWriter writer = new FileWriter(file); //生成html(将数据模型填充到模板中) try { template.process(map, writer); } catch (TemplateException e) { e.printStackTrace(); } finally { //关闭资源 writer.flush(); writer.close(); } } }
new.ftl
<!DOCTYPE html> <html> <head> <#--freemarker模板中设置编码格式,否则中文有可能乱码--> <meta http-equiv="content-type" content="text/html;charset=UTF-8"> </head> <body> <#--新闻标题--> <h2 align="center">${title}</h2> <#--新闻来源和发布时间--> <p align="center"> 新闻来源:${source} 发布时间:${pubTime} </p> <#--新闻内容--> <p style="text-indent: 2em"> ${content} </p> </body> </html>
先运行
然后会在webapp中生成1643517894900.html
再次访问
http://localhost:9090/html/1643517894900.html
6.FreeMarker运算符
6.1.算术运算符
6.2.逻辑运算符
6.3.比较运算符
6.4.控制运算符
加我qq拿电子版2895548613