什么是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.</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());
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="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:

  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></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时遇到的问题以及解决:

、java.lang.ClassNotFoundException: org.springframework.ui.freemarker.FreeMarkerConfigurationFactory
首先怀疑是freemarker少了什么支持包
freemarker版本更换试试无效
打开freemarker包源文件,没发现对应支持spring的类与包,则判断支持类由spring提供,则依次打开spring-webmvc、web、context,发现只有context里面有ui这个文件夹,且里面没有freemarker文件夹,则知道是缺少了context-support这个补充包 、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:)
这个首先自己理解:
以为是freemarker解析器没给名字,于是瞎setViewName了一下,无效,记得mvc的setViewName是设置一些默认的页面链接
把错误翻译一下:
是freemarker的解析器必须需要一个freemarker的配置器,配置器的Bean我没有提供,因为freemarker不是mvc的默认支持部分,所以配置默认没有
补充一下freemarker配置即可:
@Bean
public FreeMarkerConfigurer freeMarkerConfigurer(){
FreeMarkerConfigurer freeMarkerConfigurer = new FreeMarkerConfigurer();
freeMarkerConfigurer.setDefaultEncoding("UTF-8");
return freeMarkerConfigurer;
} 、No mapping found for HTTP request with URI [/springMVC_freemarker/base/testFreemarker] in DispatcherServlet with name 'servletDispatcher'
初步怀疑是springmvc没扫描到controller
解决方案:
@ComponentScan("com.zhen.springmvc_freemarker")
、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:)
at org.springframework.web.servlet.DispatcherServlet.processDispatchResult(DispatcherServlet.java:)
at org.springframework.web.servlet.DispatcherServlet.doDispatch(DispatcherServlet.java:)
at org.springframework.web.servlet.DispatcherServlet.doService(DispatcherServlet.java:)
at org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:)
at org.springframework.web.servlet.FrameworkServlet.doGet(FrameworkServlet.java:)
初步怀疑是配置的解析器的前后缀无效
往return地址的地方写全依旧无效
怀疑是解析器配置得有问题,没有将对应文件当成freemarker处理,则增加freemarkerConfigurer的baseTemplatePath解决
freeMarkerConfigurer.setTemplateLoaderPath("/WEB-INF/view"); 、freemarker出现中文乱码
、是否是对应的html里面没有设置
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
加上这句,没啥用
、百度得知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--
回到我的配置地方,认真一看:
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("/"); 问题解决

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

  1. Servlet、Struts2、SpringMVC执行流程

    Servlet 有以下四个阶段: 1.加载和实例化 Servlet容器负责加载和实例化Servlet. 当Servlet容器启动时,或者在容器检测到需要这个Servlet来响应第一个请求时,创建Ser ...

  2. SpringMVC+Freemarker+JSTL支持

    前提: 网页编程中,我的思路是,通用的模块不仅仅只有后台代码,前端页面也可以独立为模块. 这个和asp.net中的UserController很像 比如有个人员基本信息的展示界面,需要在多个界面中嵌入 ...

  3. SpringMVC+FreeMarker

    前言: 最近在学习SpringMVC,模板引擎用的是FreeMarker,之前没有接触过.利用SpringMVC开发其实还有许多的步骤,比如控制层,服务层,持久化层,实体等等,先弄了一个小demo来总 ...

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

    今天的任务就是在spring+mybatis+springmvc的基础上,将freemarker整合进来. freemarker是什么? freemarker是一种模板引擎.它的目的是基于模板和数据, ...

  5. SpringMVC+FreeMarker实现静态资源文件自动添加版本号(md5)

    近日切换java开发,开始学习springframework.在实现静态资源文件自动计算版本号的实例时,因为不熟悉框架,走了不少弯路,好在最终解决了问题.这里写篇文章记录一下实现,也希望对大家有些用处 ...

  6. spring-mvc+freemarker整合(sonne_game网站开发03)

    今天的任务就是在spring+mybatis+springmvc的基础上,将freemarker整合进来. freemarker是什么? freemarker是一种模板引擎.它的目的是基于模板和数据, ...

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

    用到springMVC+freemarker,自己在做demo过程中报: 严重: Servlet.service() for servlet springmvc threw exception jav ...

  8. FreeMarker学习教程

    copy自http://demojava.iteye.com/blog/800204 以下内容全部是网上收集: FreeMarker的模板文件并不比HTML页面复杂多少,FreeMarker模板文件主 ...

  9. Maven+SpringMVC+Freemarker入门Demo

    1 参考http://blog.csdn.net/haishu_zheng/article/details/51490299,用第二种方法创建一个名为mavenspringmvcfreemarker的 ...

随机推荐

  1. Node.js 知识(教程)

    JavaScript on the Server JavaScript was originally built for web browsers, but with Node.js we can u ...

  2. ASP.Net MVC多语言

    .NET MVC 多语言网站 通过浏览器语言首选项改变MVC的语言,通过浏览器语言选项,修改脚本语言. 一.添加资源文件 1.添加App_GlobalResources文件夹. 2.添加默认的资源文件 ...

  3. android-------Android Studio使用MAT分析工具遇到的错误

    今天主要介绍一下我使用MAT工具分析文件时遇到的一个错误 Error opening heap dump 'a.hprof'. Check the error log for further deta ...

  4. fedora21 中lamp的搭建(测试没有问题)

    LAMP Stands for Linux,Apache,MySQL and PHP. Most of the websites works with the above combination. T ...

  5. 58Ajax

    Ajax 1 .客户端浏览器通过执行一段JS代码向服务器发送请求,服务器路由对应的视图函数返回一个json字符串作为响应,    浏览器接受响应后会触发该ajax请求的回调函数success,参数为响 ...

  6. Python 2.7.x 使用Requests发起https请求时报Warning的问题

    warning :如下 /usr/local/lib/python2.7/dist-packages/requests/packages/urllib3/connectionpool.py:852: ...

  7. hashCode会出现负数吗,答案是肯定的

    先来普及一下基本数据类型的长度: unsigned   int   0-4294967295   int   -2147483648-2147483647 unsigned long 0-429496 ...

  8. ArrayList详细

    (IList值的集合 索引访问 ArrayList类IDictionary:键/值对 HashTable类 可变的集合 长度自动增长) ICollection-----IEnumerable--- I ...

  9. UI界面按钮增强

    (我是菜鸟,知道的少) 1.有HTML页面代码的,可以编辑 <%@page language="abap" %> <%@extension name=" ...

  10. Tomcat指定JDK路径(Linux+Windows)

    当系统有多套JDK,不方便在系统配统一的JAVA_HOME时,我们可能想给tomcat指定JDK路径. 1.Linux下Tomcat指定JDK路径 找到$CATALINE_HOME/bin/catal ...