freemarker學習 (servlet + freemarker -> Struts2+freemarker -> springMVC+freemarker)

什麼是freemarker?html

  freemarker相似於jsp,但不是jsp!怎麼說呢?freemarker文件後綴是.ftl,它不像jsp本質是servlet,它將構建模板、解析模板、使用模板分離開來了。java

  這個回答很好:源於:https://zhidao.baidu.com/question/489425455706898652.htmlweb

  運行機制就不大同樣,jsp是編譯成繼承自servlet的class文件,運行jsp就是運行一個servlet
  而freemarker就是套模板,經過模板+內容直接生成HTML而後輸出
  從開發角度來講
  freemarker 自帶一套模板語言,語法實現更簡單直觀,並且能夠經過marco宏編寫控件,若是宏沒法知足,freemarker也還提供了不少JAVA擴展接口。
  而JSP無論JSTL仍是其餘,都是靠taglib實現的,taglib的效率其實並不高,因此在複雜頁面的渲染上 ,freemarker會明顯高於jsp
  同時 ,freemarker也不只僅侷限於B/S應用,能夠普遍應用到好比代碼生成、票據打印模板等各個方面spring

  jsp的功能在freemarker基本上都提供了,有jsp經驗的上手會比較簡單緩存

 

servlet + freemarker:服務器

  導入freemarker jar包: mvc

<dependency>
            <groupId>org.freemarker</groupId>
            <artifactId>freemarker</artifactId>
            <version>2.3.23</version>
        </dependency>

 

如何使用模板技術:app

  

public class TestFreemarker { public static void main(String[] args) throws Exception{ //一、建立Freemark配置實例
        Configuration cfg = new Configuration(); cfg.setDirectoryForTemplateLoading(new File("template")); //二、建立數據模型
        Map root = new HashMap(); root.put("user", "老高"); root.put("random",  new Random().nextInt(100)); List<Address> addressList = new ArrayList<Address>(); addressList.add(new Address("中國", "北京")); addressList.add(new Address("法國", "巴黎")); root.put("addressList", addressList); //三、加載模板文件
        Template template = cfg.getTemplate("scope.ftl"); //四、顯示生成的數據
        Writer out = new OutputStreamWriter(System.out); template.process(root, out); out.flush(); out.close(); } }

相似咱們原來的servlet中畫視圖的作法,freemarker進行了視圖的使用模板與填充參數獲得字符串操做。dom

  語法與使用文檔:jsp

    連接: https://pan.baidu.com/s/1jbHpy7QIBjBwjppxXfrZWw 提取碼: 3d7v 

 

輸出if else 和遍歷集合例子:

<#if user=="老高">你是老師</#if>
<#if random gte 18>
成年
<#else>
未成年
</#if>
<#if random gte 90>
優秀
<#elseif random gte 80>
良好
<#elseif random gte 60>
及格
<#else>
不及格
</#if>

<#list addressList as address>
${address_index}->${address.country}->${address.city}
</#list>

輸出字符串:

你好,${user},今天你的精神不錯!

include:

<#include "included.text"/>

宏指令(相似函數):

<#macro m1>
<b>測試宏指令</b>
</#macro>

<#macro add a b>
帶參的宏add: ${a + b}
</#macro>

<#macro welcome>
&lt;#nested&gt;引用標籤體的內容
<#nested>
</#macro>

使用前面定義的函數:

<@m1/>

<@add 1, 2/>

<@welcome>
歡迎guodaxa!
</@welcome>

當引入了2個ftl有一樣的函數或者變量時,scope:

a.ftl

<#macro copyRight date>
<p>Copyright (C) ${date} 北京尚學堂.</p>
</#macro>
<#-- assign指令是定義變量的意思 -->
<#assign mail="1580909730@qq.com">

b.ftl

<#macro copyRight date>
<p>Copyright (C) ${date} 北京尚學堂1.</p>
</#macro>
<#-- assign指令是定義變量的意思 -->
<#assign mail="3291984010@qq.com">

scope

<#import "a.ftl" as a>
<#import "b.ftl" as b>

<@a.copyRight "2018-12-24"></@a.copyRight>
<@b.copyRight "2018-12-24"></@b.copyRight>

${a.mail}
${b.mail}

<#assign mail = "13700215420@11.com" in a>

${a.mail}

 

項目代碼:

連接: https://pan.baidu.com/s/1_v3ymqHAYMnxnIHQleUBxQ 提取碼: ytuk

struts2整合freemarker:

  一、項目導入strtus2jar包,freemarkerjar包

  二、將freemarker的配置加到web.xml:  

<servlet>
        <servlet-name>freemarker</servlet-name>
        <servlet-class> freemarker.ext.servlet.FreemarkerServlet </servlet-class>
        <!--下面的配置freemarke的ftl文件的位置 -->
        <init-param>
            <param-name>TemplatePath</param-name>
            <param-value>/WEB-INF/template</param-value>
        </init-param>
        <!-- 是否和服務器(tommcat)一塊兒啓動。-->
        <load-on-startup>1</load-on-startup>
    </servlet>

    <servlet-mapping>
        <servlet-name>freemarker</servlet-name>
        <url-pattern>*.ftl</url-pattern>
    </servlet-mapping>

  三、struts.xml中的result中的type設置成爲freemarker:

<action name="userAction" class="com.zhen.struts2freemarker.action.UserAction">
            <result name="success"  type="freemarker">/WEB-INF/template/user_show.ftl</result>
        </action>

  四、注意:

一、Struts2標籤在JSP 頁面中的寫法與在Freemarker模板文件中的寫法不一樣。
Freemarker模板文件是以<@s.tag>開始,以</@s.tag>結束
二、Freemarker模板文件的處理,經過Web容器是沒法直接處理的,所以不要讓用戶直接訪問模板 文件。在開發過程當中,咱們能夠將Freemarker文件直接放到Web工程的 WEB-INF目錄或其子目錄下(用戶沒法訪問WEB-INF目錄下文件),並在相應的struts-*.xml文件中配置type="freemarker" 來輸出模板

項目代碼:連接: https://pan.baidu.com/s/1GhBSOTGcAUH9BwVfXvx5fA 提取碼: ttd1 

 

SpringMVC+freemarker:

  一、引入springMvc有關jar,引入freemarker有關jar

    注意spring的freemarker支持在context-support模塊

  二、springMvc配置中自定義視圖解析器,定義freemarker配置Bean

 @Bean public FreeMarkerConfigurer freeMarkerConfigurer(){ FreeMarkerConfigurer freeMarkerConfigurer = new FreeMarkerConfigurer(); freeMarkerConfigurer.setDefaultEncoding("UTF-8"); freeMarkerConfigurer.setTemplateLoaderPath("/"); return freeMarkerConfigurer; } @Override public void configureViewResolvers(ViewResolverRegistry registry) { //spring4 默認不是freemarker,而是Thymeleaf
        FreeMarkerViewResolver freeMarkerViewResolver = new FreeMarkerViewResolver(); freeMarkerViewResolver.setPrefix("/WEB-INF/view"); freeMarkerViewResolver.setSuffix(".ftl"); freeMarkerViewResolver.setCache(false);//cache最好配置爲false,不然再次去緩存若是與request有關則gg //這行必定要配置,否則容易中文亂碼,默認的charset是ISO-8859-1
        freeMarkerViewResolver.setContentType("text/html;charset=UTF-8"); registry.viewResolver(freeMarkerViewResolver); registry.freeMarker(); }

項目代碼:連接: https://pan.baidu.com/s/19MSg7kq5QSZEy8PaaMv5TA 提取碼: x7rn 

springMvc+ freemarker時遇到的問題以及解決:

 

1、java.lang.ClassNotFoundException: org.springframework.ui.freemarker.FreeMarkerConfigurationFactory 首先懷疑是freemarker少了什麼支持包 freemarker版本更換試試無效 打開freemarker包源文件,沒發現對應支持spring的類與包,則判斷支持類由spring提供,則依次打開spring-webmvc、web、context,發現只有context裏面有ui這個文件夾,且裏面沒有freemarker文件夾,則知道是缺乏了context-support這個補充包 2、org.springframework.beans.factory.BeanInitializationException: In addition to a FreeMarker view resolver there must also be a single FreeMarkerConfig bean in this web application context (or its parent): FreeMarkerConfigurer is the usual implementation. This bean may be given any name. at org.springframework.web.servlet.config.annotation.ViewResolverRegistry.freeMarker(ViewResolverRegistry.java:183) 這個首先本身理解: 覺得是freemarker解析器沒給名字,因而瞎setViewName了一下,無效,記得mvc的setViewName是設置一些默認的頁面連接 把錯誤翻譯一下: 是freemarker的解析器必須須要一個freemarker的配置器,配置器的Bean我沒有提供,由於freemarker不是mvc的默認支持部分,因此配置默認沒有 補充一下freemarker配置便可: @Bean public FreeMarkerConfigurer freeMarkerConfigurer(){ FreeMarkerConfigurer freeMarkerConfigurer = new FreeMarkerConfigurer(); freeMarkerConfigurer.setDefaultEncoding("UTF-8"); return freeMarkerConfigurer; } 3、No mapping found for HTTP request with URI [/springMVC_freemarker/base/testFreemarker] in DispatcherServlet with name 'servletDispatcher' 初步懷疑是springmvc沒掃描到controller 解決方案: @ComponentScan("com.zhen.springmvc_freemarker") 4、Servlet.service() for servlet [servletDispatcher] in context with path [/springMVC_freemarker] threw exception [Could not resolve view with name 'test_freemarker' in servlet with name 'servletDispatcher'] with root cause javax.servlet.ServletException: Could not resolve view with name 'test_freemarker' in servlet with name 'servletDispatcher' at org.springframework.web.servlet.DispatcherServlet.render(DispatcherServlet.java:1237) at org.springframework.web.servlet.DispatcherServlet.processDispatchResult(DispatcherServlet.java:1037) at org.springframework.web.servlet.DispatcherServlet.doDispatch(DispatcherServlet.java:980) at org.springframework.web.servlet.DispatcherServlet.doService(DispatcherServlet.java:897) at org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:970) at org.springframework.web.servlet.FrameworkServlet.doGet(FrameworkServlet.java:861) 初步懷疑是配置的解析器的先後綴無效 往return地址的地方寫全依舊無效 懷疑是解析器配置得有問題,沒有將對應文件當成freemarker處理,則增長freemarkerConfigurer的baseTemplatePath解決 freeMarkerConfigurer.setTemplateLoaderPath("/WEB-INF/view"); 5、freemarker出現中文亂碼 1、是不是對應的html裏面沒有設置 <meta http-equiv="Content-Type" content="text/html; charset=utf-8" /> 加上這句,沒啥用 2、百度得知freemarkerViewResource還要配置一下contentType設置下response的類型和編碼,因而增長: registry.freeMarker()獲得的對象沒有設置contentType方法,所以自定義進去,改成: @Override public void configureViewResolvers(ViewResolverRegistry registry) { //spring4 默認不是freemarker,而是Thymeleaf
                FreeMarkerViewResolver freeMarkerViewResolver = new FreeMarkerViewResolver(); freeMarkerViewResolver.setPrefix("/WEB-INF/view"); freeMarkerViewResolver.setSuffix(".ftl"); freeMarkerViewResolver.setCache(false);//cache最好配置爲false,不然再次去緩存若是與request有關則gg //這行必定要配置,否則容易中文亂碼,默認的charset是ISO-8859-1
                freeMarkerViewResolver.setContentType("text/html;charset=UTF-8"); registry.viewResolver(freeMarkerViewResolver); } 而後一直報錯找不到視圖:test_freemarker 懷疑是解析器沒有執行,沒有進行封裝view,因而解析器解析方法打斷點,發現成功封裝了view,那麼爲何找不到視圖呢? 斷點freemarker找視圖的方法,發現那裏傳入我認爲的正確的視圖url找不到,檢查class編譯後文件感受還沒錯 回退到亂碼前配置,斷點看下找視圖的地方,發現傳入的url不是/WEB-INF/view/test_freemarker.ftl而是test_freemarker.ftl,發現contentType中的編碼爲iso-8859-1 回到個人配置地方,認真一看: registry.freeMarker(); //這樣配置的視圖解析器
 @Bean public FreeMarkerConfigurer freeMarkerConfigurer(){ FreeMarkerConfigurer freeMarkerConfigurer = new FreeMarkerConfigurer(); freeMarkerConfigurer.setDefaultEncoding("UTF-8"); freeMarkerConfigurer.setTemplateLoaderPath("/WEB-INF/view"); return freeMarkerConfigurer; } 原來freemarker configure中設置的模板基礎路徑是/WEB-INF/view,因此我傳入/WEB-INF/view/test_freemarker.ftl找不到,因而更改成:freeMarkerConfigurer.setTemplateLoaderPath("/"); 問題解決
相關文章
相關標籤/搜索