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.</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>
<#nested>引用标签体的内容
<#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)的更多相关文章
- Servlet、Struts2、SpringMVC执行流程
Servlet 有以下四个阶段: 1.加载和实例化 Servlet容器负责加载和实例化Servlet. 当Servlet容器启动时,或者在容器检测到需要这个Servlet来响应第一个请求时,创建Ser ...
- SpringMVC+Freemarker+JSTL支持
前提: 网页编程中,我的思路是,通用的模块不仅仅只有后台代码,前端页面也可以独立为模块. 这个和asp.net中的UserController很像 比如有个人员基本信息的展示界面,需要在多个界面中嵌入 ...
- SpringMVC+FreeMarker
前言: 最近在学习SpringMVC,模板引擎用的是FreeMarker,之前没有接触过.利用SpringMVC开发其实还有许多的步骤,比如控制层,服务层,持久化层,实体等等,先弄了一个小demo来总 ...
- sonne_game网站开发03 spring-mvc+freemarker整合
今天的任务就是在spring+mybatis+springmvc的基础上,将freemarker整合进来. freemarker是什么? freemarker是一种模板引擎.它的目的是基于模板和数据, ...
- SpringMVC+FreeMarker实现静态资源文件自动添加版本号(md5)
近日切换java开发,开始学习springframework.在实现静态资源文件自动计算版本号的实例时,因为不熟悉框架,走了不少弯路,好在最终解决了问题.这里写篇文章记录一下实现,也希望对大家有些用处 ...
- spring-mvc+freemarker整合(sonne_game网站开发03)
今天的任务就是在spring+mybatis+springmvc的基础上,将freemarker整合进来. freemarker是什么? freemarker是一种模板引擎.它的目的是基于模板和数据, ...
- springMVC+freemarker中Could not resolve view with name... 问题解决
用到springMVC+freemarker,自己在做demo过程中报: 严重: Servlet.service() for servlet springmvc threw exception jav ...
- FreeMarker学习教程
copy自http://demojava.iteye.com/blog/800204 以下内容全部是网上收集: FreeMarker的模板文件并不比HTML页面复杂多少,FreeMarker模板文件主 ...
- Maven+SpringMVC+Freemarker入门Demo
1 参考http://blog.csdn.net/haishu_zheng/article/details/51490299,用第二种方法创建一个名为mavenspringmvcfreemarker的 ...
随机推荐
- es的mapping设置
自定义mapping的api PUT test_index { "mappings": { #mappings关键字 "doc": { #type " ...
- apiCloud 播放视频
api.openVideo({ url:'https://fabu.chenchaoweb.cn/./Uploads/5a3b72be2b102.mp4' (路径必须是完整路径) });
- jquery快速获得url 的get传值
<script> var res = location.search.substr(1).split("&"); var arr={}; for (var i ...
- Single Number leetcode java
问题描述: Given an array of integers, every element appears twice except for one. Find that single one. ...
- Codeforces Round #250 (Div. 1)E. The Child and Binary Tree
题意:有一个集合,求有多少形态不同的二叉树满足每个点的权值都属于这个集合并且总点权等于i 题解:先用生成函数搞出来\(f(x)=f(x)^2*c(x)+1\) 然后转化一下变成\(f(x)=\frac ...
- Spring boot(三)在Spring boot中Redis的使用
spring boot对常用的数据库支持外,对nosql 数据库也进行了封装自动化. redis介绍 Redis是目前业界使用最广泛的内存数据存储.相比memcached,Redis支持更丰富的数据结 ...
- 把springboot的项目打包运行指南
受到传统mvc模式的开发影响,多数人都会想到把springboot项目打成war包在服务器容器里运行,笔者试过很多种方法打成war包部署tomcat上运行.运行成功但是怎么也访问不了,一直报404的错 ...
- C++笔试题总结
1.C和C++的特点与区别? 答:(1)C语言特点:1.作为一种面向过程的结构化语言,易于调试和维护: 2.表现能力和处理能力极强,可以直接访问内存的物理地址: 3.C语言实现了对硬件的编程操作,也适 ...
- SAP 打开SAP物料帐期和财务账期
引http://blog.sina.com.cn/s/blog_494f9a6b0102e8zw.html 物料账期:Tcode MMPV和Tcode MMRV 财务账期:Tcode OKP1 和O ...
- Git Diff 格式分析
参考: http://stackoverflow.com/questions/2529441/how-to-read-the-output-from-git-diff https://www.git- ...