Freemarker

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>

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末决左,一起剝皮案震驚了整個(gè)濱河市愕够,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌佛猛,老刑警劉巖惑芭,帶你破解...
    沈念sama閱讀 221,548評(píng)論 6 515
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異继找,居然都是意外死亡遂跟,警方通過查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 94,497評(píng)論 3 399
  • 文/潘曉璐 我一進(jìn)店門婴渡,熙熙樓的掌柜王于貴愁眉苦臉地迎上來幻锁,“玉大人,你說我怎么就攤上這事边臼『宥” “怎么了?”我有些...
    開封第一講書人閱讀 167,990評(píng)論 0 360
  • 文/不壞的土叔 我叫張陵柠并,是天一觀的道長岭接。 經(jīng)常有香客問我富拗,道長,這世上最難降的妖魔是什么鸣戴? 我笑而不...
    開封第一講書人閱讀 59,618評(píng)論 1 296
  • 正文 為了忘掉前任啃沪,我火速辦了婚禮,結(jié)果婚禮上葵擎,老公的妹妹穿的比我還像新娘谅阿。我一直安慰自己,他們只是感情好酬滤,可當(dāng)我...
    茶點(diǎn)故事閱讀 68,618評(píng)論 6 397
  • 文/花漫 我一把揭開白布签餐。 她就那樣靜靜地躺著,像睡著了一般盯串。 火紅的嫁衣襯著肌膚如雪氯檐。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 52,246評(píng)論 1 308
  • 那天体捏,我揣著相機(jī)與錄音冠摄,去河邊找鬼。 笑死几缭,一個(gè)胖子當(dāng)著我的面吹牛河泳,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播年栓,決...
    沈念sama閱讀 40,819評(píng)論 3 421
  • 文/蒼蘭香墨 我猛地睜開眼拆挥,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了某抓?” 一聲冷哼從身側(cè)響起纸兔,我...
    開封第一講書人閱讀 39,725評(píng)論 0 276
  • 序言:老撾萬榮一對(duì)情侶失蹤,失蹤者是張志新(化名)和其女友劉穎否副,沒想到半個(gè)月后汉矿,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 46,268評(píng)論 1 320
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡备禀,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 38,356評(píng)論 3 340
  • 正文 我和宋清朗相戀三年洲拇,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片曲尸。...
    茶點(diǎn)故事閱讀 40,488評(píng)論 1 352
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡呻待,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出队腐,到底是詐尸還是另有隱情,我是刑警寧澤奏篙,帶...
    沈念sama閱讀 36,181評(píng)論 5 350
  • 正文 年R本政府宣布柴淘,位于F島的核電站迫淹,受9級(jí)特大地震影響,放射性物質(zhì)發(fā)生泄漏为严。R本人自食惡果不足惜敛熬,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,862評(píng)論 3 333
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望第股。 院中可真熱鬧应民,春花似錦、人聲如沸夕吻。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,331評(píng)論 0 24
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽涉馅。三九已至归园,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間稚矿,已是汗流浹背庸诱。 一陣腳步聲響...
    開封第一講書人閱讀 33,445評(píng)論 1 272
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留晤揣,地道東北人桥爽。 一個(gè)月前我還...
    沈念sama閱讀 48,897評(píng)論 3 376
  • 正文 我出身青樓,卻偏偏與公主長得像昧识,于是被迫代替她去往敵國和親钠四。 傳聞我的和親對(duì)象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 45,500評(píng)論 2 359

推薦閱讀更多精彩內(nèi)容