1. 什么是Freemarker
FreeMarker是一個(gè)用Java語言編寫的模板引擎埃仪,它基于模板來生成文本輸出。FreeMarker與Web容器無關(guān)么库,即在Web運(yùn)行時(shí)甘有,它并不知道Servlet或HTTP亏掀。它不僅可以用作表現(xiàn)層的實(shí)現(xiàn)技術(shù),而且還可以用于生成XML温算,JSP或Java 等间影。
目前企業(yè)中:主要用Freemarker做靜態(tài)頁面或是頁面展示
2. Freemarker的使用方法
把freemarker的jar包添加到工程中巩割。
Maven工程添加依賴
<dependency>
<groupId>org.freemarker</groupId>
<artifactId>freemarker</artifactId>
<version>2.3.23</version>
</dependency>
原理:
使用步驟:
第一步:創(chuàng)建一個(gè)Configuration對(duì)象,直接new一個(gè)對(duì)象。構(gòu)造方法的參數(shù)就是freemarker對(duì)于的版本號(hào)萝嘁。
第二步:設(shè)置模板文件所在的路徑牙言。
第三步:設(shè)置模板文件使用的字符集咱枉。一般就是utf-8.
第四步:加載一個(gè)模板蚕断,創(chuàng)建一個(gè)模板對(duì)象。
第五步:創(chuàng)建一個(gè)模板使用的數(shù)據(jù)集入挣,可以是pojo也可以是map。一般是Map葛假。
第六步:創(chuàng)建一個(gè)Writer對(duì)象障陶,一般創(chuàng)建一FileWriter對(duì)象聊训,指定生成的文件名抱究。
第七步:調(diào)用模板對(duì)象的process方法輸出文件。
第八步:關(guān)閉流带斑。
模板:
${hello}
@Test
public void genFile() throws Exception {
// 第一步:創(chuàng)建一個(gè)Configuration對(duì)象,直接new一個(gè)對(duì)象。構(gòu)造方法的參數(shù)就是freemarker對(duì)于的版本號(hào)朋凉。
Configuration configuration = new Configuration(Configuration.getVersion());
// 第二步:設(shè)置模板文件所在的路徑。
configuration.setDirectoryForTemplateLoading(new File("D:/workspaces-itcast/term197/taotao-item-web/src/main/webapp/WEB-INF/ftl"));
// 第三步:設(shè)置模板文件使用的字符集亲怠。一般就是utf-8.
configuration.setDefaultEncoding("utf-8");
// 第四步:加載一個(gè)模板主胧,創(chuàng)建一個(gè)模板對(duì)象。
Template template = configuration.getTemplate("hello.ftl");
// 第五步:創(chuàng)建一個(gè)模板使用的數(shù)據(jù)集习勤,可以是pojo也可以是map踪栋。一般是Map。
Map dataModel = new HashMap<>();
//向數(shù)據(jù)集中添加數(shù)據(jù)
dataModel.put("hello", "this is my first freemarker test.");
// 第六步:創(chuàng)建一個(gè)Writer對(duì)象图毕,一般創(chuàng)建一FileWriter對(duì)象夷都,指定生成的文件名。
Writer out = new FileWriter(new File("D:/temp/term197/out/hello.html"));
// 第七步:調(diào)用模板對(duì)象的process方法輸出文件予颤。
template.process(dataModel, out);
// 第八步:關(guān)閉流囤官。
out.close();
}
3. 模板的語法
訪問map中的key
${key}
訪問pojo中的屬性
Student對(duì)象。學(xué)號(hào)蛤虐、姓名党饮、年齡
${key.property}
取集合中的數(shù)據(jù)
<#list 集合 as 循環(huán)的變量>
<#list studentList as student>
${student.id}/${studnet.name}
</#list>
去循環(huán)中的下標(biāo)
<#list studentList as student>
${student_index}
</#list>
判斷
<#if student_index % 2 == 0>
<#else>
</#if>
日期類型格式化
Null值的處理
Include標(biāo)簽
<#include “模板名稱”>
4. Freemarker整合spring
4.1. 創(chuàng)建整合spring的配置文件
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:p="http://www.springframework.org/schema/p"
xmlns:context="http://www.springframework.org/schema/context"
xmlns:dubbo="http://code.alibabatech.com/schema/dubbo" xmlns:mvc="http://www.springframework.org/schema/mvc"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc-4.2.xsd
http://code.alibabatech.com/schema/dubbo http://code.alibabatech.com/schema/dubbo/dubbo.xsd
http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd">
<bean id="freemarkerConfig"
class="org.springframework.web.servlet.view.freemarker.FreeMarkerConfigurer">
<property name="templateLoaderPath" value="/WEB-INF/ftl/" />
<property name="defaultEncoding" value="UTF-8" />
<property name="freemarkerSettings">
<!-- 設(shè)置默認(rèn)的編碼方式,原先是GBK笆焰,需要設(shè)置成utf-8 -->
<props>
<!--用于解決前端報(bào)空指針問題 不用再空值后面+ 劫谅!號(hào)-->
<prop key="classic_compatible">true</prop>
<!-- <prop key="defaultEncoding">utf-8</prop>
<prop key="template_exception_handler">rethrow</prop> -->
</props>
</property>
</bean>
</beans>
需要編寫一Controller進(jìn)行測試
4.2 Controller
請(qǐng)求的url:/genhtml
參數(shù):無
返回值:ok (String, 需要使用@ResponseBody)
業(yè)務(wù)邏輯:
1、從spring容器中獲得FreeMarkerConfigurer對(duì)象捏检。
2荞驴、從FreeMarkerConfigurer對(duì)象中獲得Configuration對(duì)象。
3贯城、使用Configuration對(duì)象獲得Template對(duì)象熊楼。
4、創(chuàng)建數(shù)據(jù)集
5能犯、創(chuàng)建輸出文件的Writer對(duì)象鲫骗。
6、調(diào)用模板對(duì)象的process方法踩晶,生成文件执泰。
7、關(guān)閉流渡蜻。
加載配置文件:
@Controller
public class HtmlGenController {
@Autowired
private FreeMarkerConfigurer freeMarkerConfigurer;
@RequestMapping("/genhtml")
@ResponseBody
public String genHtml()throws Exception {
// 1术吝、從spring容器中獲得FreeMarkerConfigurer對(duì)象。
// 2茸苇、從FreeMarkerConfigurer對(duì)象中獲得Configuration對(duì)象排苍。
Configuration configuration = freeMarkerConfigurer.getConfiguration();
// 3、使用Configuration對(duì)象獲得Template對(duì)象学密。
Template template = configuration.getTemplate("hello.ftl");
// 4淘衙、創(chuàng)建數(shù)據(jù)集
Map dataModel = new HashMap<>();
dataModel.put("hello", "1000");
// 5、創(chuàng)建輸出文件的Writer對(duì)象腻暮。
Writer out = new FileWriter(new File("D:/temp/term197/out/spring-freemarker.html"));
// 6彤守、調(diào)用模板對(duì)象的process方法,生成文件西壮。
template.process(dataModel, out);
// 7遗增、關(guān)閉流。
out.close();
return "OK";
}
}
5. 商品詳情頁面靜態(tài)化
5.1 網(wǎng)頁的靜態(tài)化方案
輸出文件的名稱:商品id+“.html”
輸出文件的路徑:工程外部的任意目錄款青。
網(wǎng)頁訪問:使用nginx訪問網(wǎng)頁。在此方案下tomcat只有一個(gè)作用就是生成靜態(tài)頁面霍狰。
工程部署:可以把taotao-item-web部署到多個(gè)服務(wù)器上抡草。
生成靜態(tài)頁面的時(shí)機(jī):商品添加后,生成靜態(tài)頁面蔗坯】嫡穑可以使用Activemq,訂閱topic(商品添加)
3.5.2. MessageListener
需要實(shí)現(xiàn)MessageListener宾濒,把Active的客戶端jar包的依賴添加到工程中腿短。
業(yè)務(wù)邏輯:
1、創(chuàng)建一個(gè)MessageListener接口的實(shí)現(xiàn)類
2、從message中取商品id
3橘忱、查詢商品基本消息赴魁、商品描述。
4钝诚、創(chuàng)建商品詳情頁面的模板颖御。
5、指定文件輸出目錄
6凝颇、生成靜態(tài)文件潘拱。
安裝http服務(wù)器。
public class HtmlGenListener implements MessageListener {
@Autowired
private ItemService itemService;
@Autowired
private FreeMarkerConfigurer freeMarkerConfigurer;
@Value("${HTML_OUT_PATH}")
private String HTML_OUT_PATH;
@Override
public void onMessage(Message message) {
try {
// 1拧略、創(chuàng)建一個(gè)MessageListener接口的實(shí)現(xiàn)類
// 2芦岂、從message中取商品id
TextMessage textMessage = (TextMessage) message;
String strItemId = textMessage.getText();
Long itemId = new Long(strItemId);
// 3、查詢商品基本消息垫蛆、商品描述禽最。
TbItem tbItem = itemService.getItemById(itemId);
Item item = new Item(tbItem);
TbItemDesc tbItemDesc = itemService.getItemDescById(itemId);
//創(chuàng)建數(shù)據(jù)集
Map data = new HashMap<>();
data.put("item", item);
data.put("itemDesc", tbItemDesc);
// 4、創(chuàng)建商品詳情頁面的模板月褥。
// 5弛随、指定文件輸出目錄
Configuration configuration = freeMarkerConfigurer.getConfiguration();
Template template = configuration.getTemplate("item.htm");
FileWriter out = new FileWriter(new File(HTML_OUT_PATH + itemId + ".html"));
// 6、生成靜態(tài)文件宁赤。
template.process(data, out);
//關(guān)閉流
out.close();
} catch (Exception e) {
e.printStackTrace();
}
}
}
3.5.3. Spring配置文件
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:context="http://www.springframework.org/schema/context" xmlns:p="http://www.springframework.org/schema/p"
xmlns:aop="http://www.springframework.org/schema/aop" xmlns:tx="http://www.springframework.org/schema/tx"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-4.2.xsd
http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-4.2.xsd
http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-4.2.xsd http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-4.2.xsd
http://www.springframework.org/schema/util http://www.springframework.org/schema/util/spring-util-4.2.xsd">
<!-- 真正可以產(chǎn)生Connection的ConnectionFactory舀透,由對(duì)應(yīng)的 JMS服務(wù)廠商提供 -->
<bean id="targetConnectionFactory" class="org.apache.activemq.ActiveMQConnectionFactory">
<property name="brokerURL" value="tcp://192.168.25.168:61616" />
</bean>
<!-- Spring用于管理真正的ConnectionFactory的ConnectionFactory -->
<bean id="connectionFactory"
class="org.springframework.jms.connection.SingleConnectionFactory">
<!-- 目標(biāo)ConnectionFactory對(duì)應(yīng)真實(shí)的可以產(chǎn)生JMS Connection的ConnectionFactory -->
<property name="targetConnectionFactory" ref="targetConnectionFactory" />
</bean>
<!--這個(gè)是主題目的地,一對(duì)多的 -->
<bean id="topicDestination" class="org.apache.activemq.command.ActiveMQTopic">
<constructor-arg value="item-add-topic" />
</bean>
<!-- 配置消息監(jiān)聽器 -->
<bean id="htmlGenListener" class="com.taotao.item.listener.HtmlGenListener"/>
<!-- 配置監(jiān)聽容器 -->
<!-- 消息監(jiān)聽容器 -->
<bean class="org.springframework.jms.listener.DefaultMessageListenerContainer">
<property name="connectionFactory" ref="connectionFactory" />
<property name="destination" ref="topicDestination" />
<property name="messageListener" ref="htmlGenListener" />
</bean>
</beans>