Spring MVC + freemarker实现半自动静态化
这里对freemarker的代码进行了修改,效果:
1,请求.do的URL时直接生成对应的.htm文件,并将请求转发到该htm文件
2,自由控制某个页面是否需要静态化
原理:对org.springframework.web.servlet.view.freemarker.FreeMarkerView类进行扩展
第一步:在web.xml中将*.do请求交给SpringMVC
<servlet>
<servlet-name>demo</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
<init-param>
<param-name>contextConfigLocation</param-name>
<param-value>/WEB-INF/demo-servlet.xml</param-value>
</init-param>
<load-on-startup>1</load-on-startup>
</servlet> <servlet-mapping>
<servlet-name>demo</servlet-name>
<url-pattern>*.do</url-pattern>
</servlet-mapping>
第二步:配置/WEB-INF/demo-servlet.xml
<!--freemarker页面解析器 -->
<bean id="viewResolver" class="org.springframework.web.servlet.view.freemarker.FreeMarkerViewResolver">
<property name="suffix" value=".ftl"></property>
<property name="contentType" value="text/html;charset=UTF-8" />
<!-- <property name="viewClass" value="org.springframework.web.servlet.view.freemarker.FreeMarkerView" /> -->
<!-- 将Spring的FreeMarkerView改成我们扩展的View -->
<property name="viewClass" value="com.myview.MyFreeMarkerView" />
<property name="exposeRequestAttributes" value="true" />
<property name="exposeSessionAttributes" value="true" />
<property name="exposeSpringMacroHelpers" value="true" />
</bean>
<bean id="fmXmlEscape" class="freemarker.template.utility.XmlEscape" /> <!--配置Freemarker -->
<bean id="freemarkerConfigurer" class="org.springframework.web.servlet.view.freemarker.FreeMarkerConfigurer">
<property name="templateLoaderPath" value="/WEB-INF/freemarker/"></property>
<property name="freemarkerVariables">
<map>
<entry key="xml_escape" value-ref="fmXmlEscape" />
</map>
</property>
<property name="freemarkerSettings">
<props>
<prop key="template_update_delay">1</prop>
<prop key="defaultEncoding">UTF-8</prop>
</props>
</property>
</bean>
第三步:新建package,com.myview,新建一个MyFreeMarkerView,继承自org.springframework.web.servlet.view.freemarker.FreeMarkerView,在这里对原类进行扩展
package com.myview; import java.io.BufferedWriter;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.OutputStreamWriter;
import java.io.Writer;
import java.util.Locale;
import java.util.Map; import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.springframework.web.servlet.support.RequestContextUtils;
import org.springframework.web.servlet.view.freemarker.FreeMarkerView;
import freemarker.template.SimpleHash;
import freemarker.template.Template;
import freemarker.template.TemplateException; public class MyFreeMarkerView extends FreeMarkerView{
@Override
protected void doRender(Map<String, Object> model,
HttpServletRequest request, HttpServletResponse response)
throws Exception {
// Expose model to JSP tags (as request attributes).
exposeModelAsRequestAttributes(model, request);
// Expose all standard FreeMarker hash models.
SimpleHash fmModel = buildTemplateModel(model, request, response); if (logger.isDebugEnabled()) {
logger.debug("Rendering FreeMarker template [" + getUrl() + "] in FreeMarkerView '" + getBeanName() + "'");
} // Grab the locale-specific version of the template.
Locale locale = RequestContextUtils.getLocale(request); /*
* 默认生成静态文件,除非在编写ModelAndView时指定CREATE_HTML = false,
* 这样对静态文件生成的粒度控制更细一点
* 例如:ModelAndView mav = new ModelAndView("search");
* mav.addObject("CREATE_HTML", false);
*/
if(Boolean.FALSE.equals(model.get("CREATE_HTML"))){
processTemplate(getTemplate(locale), fmModel, response);
}else{
createHTML(getTemplate(locale), fmModel, request, response);
}
} public void createHTML(Template template, SimpleHash model,HttpServletRequest request,
HttpServletResponse response) throws IOException, TemplateException, ServletException {
//站点根目录的绝对路径
String basePath = request.getSession().getServletContext().getRealPath("/");
String requestHTML = this.getRequestHTML(request);
//静态页面绝对路径
String htmlPath = basePath + requestHTML;
File htmlFile = new File(htmlPath);
if(!htmlFile.getParentFile().exists()){
htmlFile.getParentFile().mkdirs();
}
if(!htmlFile.exists()){
htmlFile.createNewFile();
}
Writer out = new BufferedWriter(new OutputStreamWriter(new FileOutputStream(htmlFile), "UTF-8"));
//处理模版
template.process(model, out);
out.flush();
out.close();
/*将请求转发到生成的htm文件*/ request.getRequestDispatcher(requestHTML).forward(request, response); } /**
* 计算要生成的静态文件相对路径
* 因为大家在调试的时候一般在Tomcat的webapps下面新建站点目录的,
* 但在实际应用时直接布署到ROOT目录里面,这里要保证路径的一致性。
* @param request HttpServletRequest
* @return /目录/*.htm
*/
private String getRequestHTML(HttpServletRequest request){
//web应用名称,部署在ROOT目录时为空
String contextPath = request.getContextPath();
//web应用/目录/文件.do
String requestURI = request.getRequestURI();
//basePath里面已经有了web应用名称,所以直接把它replace掉,以免重复
requestURI = requestURI.replaceFirst(contextPath, "");
//将.do改为.htm,稍后将请求转发到此htm文件
requestURI = requestURI.substring(0, requestURI.indexOf(".")) + ".htm";
return requestURI;
} }
到这里就基本完成了。
一个Controller类的例子:
Java code
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.servlet.ModelAndView; @Controller
public class IndexController {
@RequestMapping("/index.do")
public ModelAndView index(){
ModelAndView mav = new ModelAndView("index");
mav.addObject("title", "网站标题");
mav.addObject("origin", "freemarker");
//在这里可以控制不生成静态htm
mav.addObject("CREATE_HTML", false);
return mav;
} @RequestMapping("/abc/index.do")
public ModelAndView abcindex(){
ModelAndView mav = new ModelAndView("index");
mav.addObject("origin", "html");
//默认生成htm文件
mav.addObject("title", "网站标题");
return mav;
}
}
测试结果如下:


Spring MVC + freemarker实现半自动静态化的更多相关文章
- 二、freemarker.controller半自动静态化+Tomcat虚拟资源映射
描述:本内容主要是讲2个tomcat之间同时共享一个静态话页面,统一入口是springMVC的一个controller,静态化的更新只需要传false.true.把完成的web项目放入a.b服务器To ...
- 一、springMVC、freemarker页面半自动静态化
说明:刚刚接到公司的通知,实现(半自动化),即通过参数控制是否需要静态化页面(哪里我说错了,勿喷!谢谢) 1,请求.do的URL时直接生成对应的.htm文件,并将请求转发到该htm文件 2,自由控制某 ...
- Spring MVC freemarker使用
什么是 FreeMarker? FreeMarker 是一款 模板引擎: 即一种基于模板和要改变的数据, 并用来生成输出文本(HTML网页,电子邮件,配置文件,源代码等)的通用工具. 它不是面向最终用 ...
- 【转】使用Freemarker实现网页静态化
使用Freemarker实现网页静态化 2017年08月20日 20:45:51 阅读数:1981 1.1. 什么是freemarker FreeMarker是一个用Java语言编写的模板引擎,它基于 ...
- JAVAEE——宜立方商城10:使用freemarker实现网页静态化、ActiveMq同步生成静态网页、Sso单点登录系统分析
1. 学习计划 1.使用freemarker实现网页静态化 2.ActiveMq同步生成静态网页 2. 网页静态化 可以使用Freemarker实现网页静态化. 2.1. 什么是freemarker ...
- FreeMarker实现网页静态化
1.FreeMarker实现网页静态化. FreeMarker是一个用Java语言编写的模板引擎,它基于模板来生成文本输出.FreeMarker与Web容器无关,即在Web运行时,它并不知道Servl ...
- Freemarker 之 Java静态化 实例一
Freemarker是一种强大的web端模板技术,在当前Web开发中,SEO和客户端浏览速度尤为重要,其中将网页静态化是一个很好的解决方案.下面介绍Java中web开发结合Freemarker来实现静 ...
- Spring MVC程序中得到静态资源文件css,js,图片
转载自:http://www.blogjava.net/fiele/archive/2014/08/24/417283.html 用 Spring MVC 开发应用程序,对于初学者有一个很头疼的问题, ...
- Spring MVC程序中得到静态资源文件css,js,图片文件的路径问题总结
上一篇 | 下一篇 Spring MVC程序中得到静态资源文件css,js,图片 文件的路径 问题总结 作者:轻舞肥羊 日期:2012-11-26 http://www.blogjava.net/fi ...
随机推荐
- canvas与svg的区别
1.历史: canvas是html5提供的新元素. 而svg存在的历史要比canvas久远,已经有十几年了.svg并不是html5专有的标签,最初svg是用xml技术(超文本扩展语言,可以自定义标签或 ...
- Spring AOP 简介(三)
Spring AOP 简介 如果说 IoC 是 Spring 的核心,那么面向切面编程就是 Spring 最为重要的功能之一了,在数据库事务中切面编程被广泛使用. AOP 即 Aspect Orien ...
- 猴子补丁(Monkey Patching)
猴子补丁是我在面试的时候接触的一到题,学python的时候,我根本就没有听说这个概念!那接下来我们来分析一下: 1.什么是猴子补丁? 2.猴子补丁的功能? 3.猴子补丁的应用场景? 一.什么是猴子补丁 ...
- 用Python获取计算机网卡信息
目录 0. 前言 1. 测试环境及关键代码解释 1.1 测试环境 1.1.1 系统: 1.1.2 开发工具: 2. 模块介绍及演示 2.1 platform模块使用示例 2.2 netifaces模块 ...
- 十四、i2c子系统
由于之后的触摸屏驱动分析中使用到了GPIO子系统和i2c子系统,因此在分析触摸屏驱动之前我准备把这两个子系统进行简单分析. 在读者学习本章以及后续i2c相关章节之前,最好了解i2c通信方式,可以参考: ...
- 创客课堂——Scratch的操作界面
大家好,这里是蓝精灵创客公益课堂,我是蓝老师 上期我们了解了scratch软件进行了简单的了解,很多朋友都已经按照上期方法下载安装好了软件. 那么今天蓝老师就和大家一起认识下Scratch的操作界面及 ...
- c++学习(二)------this指针学习
在c++中,类的不同实例有自己的数据(储存在不同地方),有很多拷贝.而类的成员函数却只有一份备份. 而不同的类的实例却可以调用同一个函数,这是通过this指针来完成的. *this代表当前类本身,th ...
- C语言之反汇编揭秘
title: 'C语言之反汇编揭秘' tags: 汇编与反汇编 categories: 汇编与反汇编 copyright: true abbrlink: 'b1c9' date: 2019-09-07 ...
- Merkle树
在分布式系统.P2P应用中或者是区块链中,会经常使用一种数据结构Merkle tree(默克尔树),这里我们将详细讨论一下这个常用数据结构. Merkle tree Merkle树看起来非常像二叉树, ...
- Java Web 深入分析(9) Session 和 Cookie
前言: session 和cookie都是为了保持服务器和客户端之间交互状态.如果一天的PV有几亿,而一个cookie占200个字节但是也会占用很多带宽?所以大访问量就引用session,但是几百台服 ...