freemarker学习 (servlet + freemarker -> Struts2+freemarker -> springMVC+freemarker)

什么是freemarker?

  freemarker类似于jsp,但不是jsp!怎么说呢?freemarker文件后缀是.ftl,它不像jsp本质是servlet,它将构建模板、解析模板、使用模板分离开来了。

  这个回答很好:源于:https://zhidao.baidu.com/question/489425455706898652.html

  运行机制就不大一样,jsp是编译成继承自servlet的class文件,运行jsp就是运行一个servlet
  而freemarker就是套模板,通过模板+内容直接生成HTML然后输出
  从开发角度来说
  freemarker 自带一套模板语言,语法实现更简单直观,而且可以通过marco宏编写控件,如果宏无法满足,freemarker也还提供了很多JAVA扩展接口。
  而JSP不管JSTL还是其他,都是靠taglib实现的,taglib的效率其实并不高,所以在复杂页面的渲染上 ,freemarker会明显高于jsp
  同时 ,freemarker也不仅仅局限于B/S应用,可以广泛应用到比如代码生成、票据打印模板等各个方面

  jsp的功能在freemarker基本上都提供了,有jsp经验的上手会比较简单

servlet + freemarker:

  导入freemarker jar包: 

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

如何使用模板技术:

  

public class TestFreemarker {
    public static void main(String[] args) throws Exception{

        //1、创建Freemark配置实例
        Configuration cfg = new Configuration();
        cfg.setDirectoryForTemplateLoading(new File("template"));

        //2、创建数据模型
        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);

        //3、加载模板文件
        Template template = cfg.getTemplate("scope.ftl");

        //4、显示生成的数据
        Writer out = new OutputStreamWriter(System.out);
        template.process(root, out);
        out.flush();
        out.close();
    }
}

类似我们原来的servlet中画视图的做法,freemarker进行了视图的使用模板与填充参数得到字符串操作。

  语法与使用文档:

    链接: 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="[email protected]">

b.ftl

<#macro copyRight date>    <p>Copyright (C) ${date} 北京尚学堂1.</p></#macro><#-- assign指令是定义变量的意思 --><#assign mail="[email protected]">

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 = "[email protected]" in a>

${a.mail}

项目代码:

链接: https://pan.baidu.com/s/1_v3ymqHAYMnxnIHQleUBxQ 提取码: ytuk

struts2整合freemarker:

  1、项目导入strtus2jar包,freemarkerjar包

  2、将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>

  3、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>

  4、注意:

      1、Struts2标签在JSP 页面中的写法与在Freemarker模板文件中的写法不同。          Freemarker模板文件是以<@s.tag>开始,以</@s.tag>结束      2、Freemarker模板文件的处理,通过Web容器是无法直接处理的,因此不要让用户直接访问模板 文件。在开发过程中,我们可以将Freemarker文件直接放到Web工程的 WEB-INF目录或其子目录下(用户无法访问WEB-INF目录下文件),并在相应的struts-*.xml文件中配置type="freemarker" 来输出模板

项目代码:链接: https://pan.baidu.com/s/1GhBSOTGcAUH9BwVfXvx5fA 提取码: ttd1

SpringMVC+freemarker:

  1、引入springMvc有关jar,引入freemarker有关jar

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

  2、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("/"); 问题解决

原文地址:https://www.cnblogs.com/aigeileshei/p/10331325.html

时间: 2024-09-29 15:21:45

freemarker学习 (servlet + freemarker -> Struts2+freemarker -> springMVC+freemarker)的相关文章

Servlet、Struts2、SpringMVC执行流程

Servlet 有以下四个阶段: 1.加载和实例化 Servlet容器负责加载和实例化Servlet. 当Servlet容器启动时,或者在容器检测到需要这个Servlet来响应第一个请求时,创建Servlet实例. 当Servlet容器启动后,它必须要知道所需的Servlet类在什么位置,Servlet容器可以从本地文件系统.远程文件系统或者其他的网络服务中通过类加载器加载Servlet类,成功加载后,容器创建Servlet的实例. 因为容器是通过Java的反射API来创建 Servlet实例,

sonne_game网站开发03 spring-mvc+freemarker整合

这是从零独立开发网站(名为sonne_game)系列的第三篇了. 先简单做个往期回顾~ 第一篇,是简明讲了些自己对这个网站的构思和计划.http://www.cnblogs.com/rixiang/p/6259097.html 第二篇,开始搭建框架,完成了spring+mybatis+springmvc框架搭建.http://www.cnblogs.com/rixiang/p/6260433.html 而今天的任务就是在spring+mybatis+springmvc的基础上,将freemark

Maven+SpringMVC+Freemarker入门Demo

1 参考http://blog.csdn.net/haishu_zheng/article/details/51490299,用第二种方法创建一个名为mavenspringmvcfreemarker的Maven工程. 2 文件目录结构如下图所示 3 在pom.xml中添加springmvc和freemarker的依赖包,添加完之后的完整内容为 [html] view plain copy <project xmlns="http://maven.apache.org/POM/4.0.0&q

基于注解SpringMVC+freemarker实例

基于注解的SpringMVC+freemarker demo实例 web项目图 web.xml文件 Xml代码   <?xml version="1.0" encoding="UTF-8"?> <web-app id="WebApp_ID" version="2.4" xmlns="http://java.sun.com/xml/ns/j2ee" xmlns:xsi="http:

项目记录:springmvc+freemarker 实现国际化

第一步,在SpringMVC的配置文件中,添加如下支持国际化的两段配置 <bean id="messageSource" class="org.springframework.context.support.ResourceBundleMessageSource"> <property name="useCodeAsDefaultMessage" value="true" /> <property

springMVC+freemarker中Could not resolve view with name... 问题解决

用到springMVC+freemarker,自己在做demo过程中报: 严重: Servlet.service() for servlet springmvc threw exception javax.servlet.ServletException: Could not resolve view with name 'userlist' in servlet with name 'springmvc' at org.springframework.web.servlet.Dispatche

SpringMVC+FreeMarker+Mybatis 整合

这个项目自己有时写写测试代码什么的, 代码比较简单,代码已放在 github : https://github.com/zhouyongtao/homeinns-web 目录结构: 贴一下Maven的POM <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation=&quo

FreeMarker学习

FreeMarker语言 FreeMarker语言概述 Aaaaa FreeMarker是一个模板引擎,一个基于模板生成文本输出的通用工具,使用纯Java编写. FreeMarker被设计用来生成HTML Web页面,特别是基于MVC模式的应用程序 虽然FreeMarker具有一些编程的能力,但通常由Java程序准备要显示的数据,由FreeMarker生成页面,通过模板显示准备的数据(如下图) FreeMarker不是一个Web应用框架,而适合作为Web应用框架一个组件. FreeMarker与

springmvc+freemarker的简单demo

原文:springmvc+freemarker的简单demo 源代码下载地址:http://www.zuidaima.com/share/1550463645682688.htm 简单演示如果在springmvc中通过ModelMap添加Map,List,Entity,Request参数,其中包括中文参数乱码的处理,暂时解决方案是 new String(a.getBytes("iso8859-1"), "utf-8") 有更好的方案大家可以提供下. 另外还有最新版本