1. 程式人生 > >【SpringMVC之FreeMark(一)】spring mvc中使用freemark的方法

【SpringMVC之FreeMark(一)】spring mvc中使用freemark的方法

    模板技術在現代的軟體開發中有著重要的地位,而目前最流行的兩種模板技術恐怕要算freemarker和velocity了,webwork2.2對兩者都有不錯的支援,也就是說在webwork2中你可以隨意選擇使用freemarker或velocity作為view,模板技術作為view的好處是很多,尤其和jsp比較起來優點更大,眾所周知jsp需要在第一次被執行的時候編譯成servlet,那麼這個過程是很慢的,當然很多應用伺服器都提供預編譯的功能,但是在開發的時候仍然給我們程式設計師帶來了很多痛苦,每次修改都要多幾秒鐘,那在一天的開發中就有很多時間浪費在jsp的編譯上了。用webwork in action的作者的話來說:“每次修改之後重新執行都要等等幾秒是令人失望的,而頻繁地修改jsp更是會令你的失望情緒變本加厲“。我們把模板技術引入到view中去可以帶來更好的開發效率,而且模板的速度要比jsp快(雖然編譯過後的jsp在速度上已經滿足我的需求了,呵呵)。 當然模板技術可以用在很多領域,可不只在view那裡。我們可以通過模板技術來生成xml,生成jsp,生成java檔案等等,說到這裡,大家通常會使用模板技術用在公司的框架裡,這樣就可以很快速的生成添刪改查的程式碼,需要的只是模板,其他比如還有郵件模板等等。 

    以上是模板的作用,那麼現在開源的模板技術有好幾種,多了之後就有一個選擇的問題了,如何選擇一個滿足自己需要的模板的呢,寫了一個例子,我使用了幾種設計模式來完成了這個例子,這個例子中,同時使用了freemarker和velocity,這樣同學們可以通過程式碼很直觀的比較兩種模板技術,通過這個例子,我認識到freemarker在功能上要比velocity強大 
1。在view層的時候,它提供了format日期和數字的功能,我想大家都有在頁面上format日期或數字的經驗,用jsp的同學可能對jstl的fmt標籤很有感情,使用了freemarker之後也可以使用freemarker提供的功能來formmat日期和資料,這個功能我想是很貼心的

2。通過我的使用我發現freemaker的eclipseplugin要比velocity的eclipseplugin好,好在很多地方呢,freemarker的外掛除了支援freemarker語法也支援html語句,而velocity的外掛貌似只支援velocity的語法,html就只是用普通的文字來顯示了,在這一點上freemarker佔上風了

3。freemarker對jsptag的支援很好,算了,不到迫不得已還是不要這樣做吧。

jsp的第一次執行,就要執行servlet,如果開發時頻繁的修改jsp,會導致開發速度比較慢;(每改一次,要重新編譯一次);

編譯過後,模板的速度也要比jsp快.

具體的freemark頁面上的使用:見http://blog.csdn.net/nengyu/article/details/6829244

最近做的專案中要在spring mvc中實現freemark 載入html模板,關鍵實現如下:

第一步:引入freemark.jar包

第二步:web.xml中的配置

複製程式碼
    <!--  freemarker 配置 -->
    <bean id="freeMarkerConfigurer"
        class="com.test.common.freemarker.CustomFreeMarkerConfigurer">   <!--freemark的配置檔案類-->
        <property name="templateLoaderPaths">
            <list>
            <value>/WEB-INF/template/</value>   <!--html檔案的存放位置-->
            </list>
            </property>
        <property name="freemarkerSettings">
            <props>
                <prop key="template_update_delay">5</prop>
                <prop key="default_encoding">UTF-8</prop>
                <prop key="locale">zh_CN</prop>
                <prop key="url_escaping_charset">UTF-8</prop>
                <prop key="date_format">yyyy-MM-dd</prop>
                <prop key="time_format">HH:mm:ss</prop>
                <prop key="datetime_format">yyyy-MM-dd HH:mm:ss</prop>
                <prop key="number_format">0.######</prop>
                <prop key="boolean_format">true,false</prop> 
                <prop key="classic_compatible">true</prop>
                <prop key="whitespace_stripping">true</prop>
            </props>
        </property>
    </bean>
    <!-- freemark 頁面解析器 -->
    <bean id="viewResolver" class="org.springframework.web.servlet.view.freemarker.FreeMarkerViewResolver">
        <property name="viewClass" value="org.springframework.web.servlet.view.freemarker.FreeMarkerView" />
        <property name="contentType" value="text/html; charset=utf-8" />
        <property name="exposeSpringMacroHelpers" value="true"/>
        <property name="cache" value="true" />
        <property name="suffix" value=".html" />
        <property name="order" value="1" />
    </bean>
複製程式碼

配置檔案類: com.test.common.freemarker.CustomFreeMarkerConfigurer

複製程式碼
public class CustomFreeMarkerConfigurer extends FreeMarkerConfigurer {

    @Override
    protected TemplateLoader getAggregateTemplateLoader(
            List<TemplateLoader> templateLoaders) {
         <!-- HtmlTemplateLoader 這個類用來自定義html模板  -->
        return new HtmlTemplateLoader(super.getAggregateTemplateLoader(templateLoaders));
    }

    
}
複製程式碼

第三步:在html中使用freemark標籤

<div onclick="showHideDiv('${corpUser.corpUserProblemInfo.corpUserId}')">
             <#list corpUser.forbiddenInfoList as forbiddenRecord>
                 <#if forbiddenRecord_index<2>
                      <div>
                       <span>${forbiddenRecord.time} </span>
                       <span>${forbiddenRecord.remark}</span>
                      </div>
                 <#else>
                     <div name="hideDiv${corpUser.corpUserProblemInfo.corpUserId}" style="display: none">
                         <span>${forbiddenRecord.time} </span>
                         <span>${forbiddenRecord.remark}</span>
                     </div>
                 </#if>
             </#list>
            </div>


自定義html模板類:HtmlTemplateLoader,加escape  html指令, escape指令在解析模版時起作用,而不是執行時起作用

複製程式碼
public class HtmlTemplateLoader implements TemplateLoader {
     
    private static final String HTML_ESCAPE_PREFIX= "<#escape x as x?html>";
    private static final String HTML_ESCAPE_SUFFIX = "</#escape>";
    
    private final TemplateLoader delegate;
    
    public HtmlTemplateLoader(TemplateLoader delegate) {
        this.delegate = delegate;
    }
    
    /* (non-Javadoc)
     * @see freemarker.cache.TemplateLoader#closeTemplateSource(java.lang.Object)
     */
    @Override
    public void closeTemplateSource(Object templateSource) throws IOException {
        delegate.closeTemplateSource(templateSource);
    }

    /* (non-Javadoc)
     * @see freemarker.cache.TemplateLoader#findTemplateSource(java.lang.String)
     */
    @Override
    public Object findTemplateSource(String name) throws IOException {
        return delegate.findTemplateSource(name);
    }

    /* (non-Javadoc)
     * @see freemarker.cache.TemplateLoader#getLastModified(java.lang.Object)
     */
    @Override
    public long getLastModified(Object templateSource) {
        return delegate.getLastModified(templateSource);
    }

    /* (non-Javadoc)
     * @see freemarker.cache.TemplateLoader#getReader(java.lang.Object, java.lang.String)
     * 在讀取template檔案之後, 在前後套上<#escape>標籤
     */
    @Override
    public Reader getReader(Object templateSource, String encoding) throws IOException {
        Reader reader = delegate.getReader(templateSource, encoding);
        String templateText = IOUtils.toString(reader);
        return new StringReader(HTML_ESCAPE_PREFIX+templateText + HTML_ESCAPE_SUFFIX);
    }

}
複製程式碼

escape指令body區的ftl的interpolations都會被自動加上escape表示式。但是不會影響字串內的interpolations。而且也只會影響到body內出現的interpolations,比如不會影響到include的ftl的interpolations。

<#escape x as x?html>
First name: ${firstName}
Last name: ${lastName}
Maiden name: ${maidenName}
</#escape>
等同於:

First name: ${firstName?html}
Last name: ${lastName?html}
Maiden name: ${maidenName?html} 具體的freemark指令見: freemarker學習筆記--指令參考: http://www.cnblogs.com/pengfeisun/articles/1623182.html