maven
<!-- freemarker -->
<dependency>
<groupId>org.freemarker</groupId>
<artifactId>freemarker</artifactId>
<version>2.3.23</version>
</dependency>
springmvc.xml
<!-- 定义跳转的文件的前后缀 ,视图模式配置 -->
<bean id ="htmlviewResolver"
class="org.springframework.web.servlet.view.InternalResourceViewResolver">
<property name="prefix" value="/" />
<property name="order" value="2"></property>
<property name="suffix" value=".html"/>
</bean>
<bean id ="jspviewResolver"
class="org.springframework.web.servlet.view.InternalResourceViewResolver">
<property name="prefix" value="/" />
<property name="suffix" value=".jsp"/>
<property name="order" value="1"></property>
</bean>
<!-- FreeMarker视图解析 -->
<!-- XmlEscape执行一个给定模板片段的XML转义 -->
<bean id="fmXmlEscape" class="freemarker.template.utility.XmlEscape" />
<bean id="viewResolver"
class="org.springframework.web.servlet.view.freemarker.FreeMarkerViewResolver">
<!-- 自定义解析器 -->
<property name="viewClass" value="com.leo.ows.util.FreeMarkerViewUtil" />
<!-- <property name="viewClass" value="org.springframework.web.servlet.view.freemarker.FreeMarkerView" /> -->
<property name="cache" value="true" />
<property name="suffix" value=".ftl" />
<property name="contentType" value="text/html;charset=UTF-8" />
<property name="exposeRequestAttributes" value="true" />
<!-- 请求和会话属性都被复制到模板的属性集中,可以使用FreeMarker的表达式语言来访问并显示。 -->
<property name="exposeSessionAttributes" value="true" />
<property name="exposeSpringMacroHelpers" value="true" />
<!-- 代表了第一个匹配的是freemarker的视图解析器 -->
<property name="order" value="0"></property>
<property name="allowSessionOverride" value="true" />
<property name="allowRequestOverride" value="true" />
</bean>
<!-- 配置freeMarker的模板路径 -->
<bean id="freemarkerConfig"
class="org.springframework.web.servlet.view.freemarker.FreeMarkerConfigurer">
<property name="templateLoaderPath" value="/WEB-INF/ftl/" />
<property name="defaultEncoding" value="UTF-8" />
<property name="freemarkerVariables">
<map>
<entry key="xml_escape" value-ref="fmXmlEscape" />
<entry key="webRoot" value="/pftows"></entry>
</map>
</property>
<property name="freemarkerSettings">
<props>
<!-- 避免每次请求都重新载入模版,即充分利用cached的模版 -->
<prop key="template_update_delay">1</prop>
<prop key="default_encoding">UTF-8</prop>
<prop key="number_format">0.##########</prop>
<prop key="datetime_format">yyyy-MM-dd HH:mm:ss</prop>
<prop key="classic_compatible">true</prop>
<prop key="template_exception_handler">ignore</prop>
</props>
</property>
</bean>
<!-- 对静态资源文件的访问,存html文件夹 -->
<mvc:resources location="/freemarker/" mapping="/freemarker/**" />
FreeMarkerViewUtil.java
package com.leo.ows.util;
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;
/**
* 自定义视图解析器
* @author leo
*
*/
public class FreeMarkerViewUtil 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 模版 [" + 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;
System.out.println("静态页面绝对路径===========>>:"+htmlPath);
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文件 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, "");
// 将請求改为.html,稍后将请求转发到此html文件
requestURI = requestURI+"1.html";
return requestURI;
}
}
FreeMarkerController.java
package com.leo.ows.action;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.servlet.ModelAndView;
import com.leo.ows.entity.Article;
@Controller
public class FreeMarkerController {
/**
* freemarke生成html的路径,可以修改 ,Article视图名不能跟跳转的html的名字相同
* @return
*/
@RequestMapping(value = "/freemarke/Article")
public ModelAndView Add() {
ModelAndView modelAndView=new ModelAndView();
System.out.println("Test... ...");
Article article = new Article();
article.setTitle("biaoti1");
modelAndView.addObject("article", article);
modelAndView.setViewName("Article");
return modelAndView;
}
}