Spring MVC + freemarker实现半自动静态化

这里对freemarker的代码进行了修改,效果:
1,请求.do的URL时直接生成对应的.htm文件,并将请求转发到该htm文件
2,自由控制某个页面是否需要静态化
原理:对org.springframework.web.servlet.view.freemarker.FreeMarkerView类进行扩展
第一步:在web.xml中将*.do请求交给SpringMVC

XML code

<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

XML code

<!--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,在这里对原类进行扩展

Java code

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;
    }
}

测试结果如下:

时间: 2024-12-28 01:53:26

Spring MVC + freemarker实现半自动静态化的相关文章

FreeMarker实现网页静态化

1.FreeMarker实现网页静态化. FreeMarker是一个用Java语言编写的模板引擎,它基于模板来生成文本输出.FreeMarker与Web容器无关,即在Web运行时,它并不知道Servlet或HTTP.它不仅可以用作表现层的实现技术,而且还可以用于生成XML,JSP或Java 等.目前企业中:主要用Freemarker做静态页面或是页面展示. 2.使用freemarker需要的jar. a).把下载到的jar包(freemarker-2.3.23.jar)放到\webapp\WEB

Freemarker 之 Java静态化 实例一

Freemarker是一种强大的web端模板技术,在当前Web开发中,SEO和客户端浏览速度尤为重要,其中将网页静态化是一个很好的解决方案.下面介绍Java中web开发结合Freemarker来实现静态化. 主要分为三步 1 准备好模板文件,如Test.ftl <html> <head> <title>${title}</title> <style type="text/css" link="${rccontextPath

Spring mvc应用 加载静态资源的几种方式

总结几种Spring mvc应用加载静态资源的方式 1.使用服务器的默认Servlet处理 对于不同的服务器,处理静态资源的servlet-name不一样,需要去看服务器具体的配置文件 比如resin-3.1.12,通过查看app-default.xml可以看到默认处理jsp的servlet-name为>resin-jsp 所以可以通过在web.xml中添加静态资源的访问 <servlet-mapping>        <servlet-name>resin-jsp<

Spring MVC程序中得到静态资源文件css,js,图片文件的路径问题总结

上一篇 | 下一篇 Spring MVC程序中得到静态资源文件css,js,图片 文件的路径 用 Spring MVC 开发应用程序,对于初学者有一个很头疼的问题,那就是程序数据都已经查询出来了,但界面样式仍然十分丑陋,加载不了 css,js,图片等资源文件.当你在浏览器上直接输入某个css文件的路径时,直接得到404错误,而路径肯定没有错,其原因就在于在web.xml 中配置了类似如下的 spring servlet: 程序代码 <servlet>    <servlet-name&g

Spring MVC程序中得到静态资源文件css,js,图片

转载自:http://www.blogjava.net/fiele/archive/2014/08/24/417283.html 用 Spring MVC 开发应用程序,对于初学者有一个很头疼的问题,那就是程序数据都已经查询出来了,但界面样式仍然十分丑陋,加载不了 css,js,图片等资源文件.当你在浏览器上直接输入某个css文件的路径时,直接得到404错误,而路径肯定没有错,其原因就在于在web.xml 中配置了类似如下的 spring servlet: 程序代码 <servlet>    

Spring MVC+FreeMarker简介

最近做项目,刚接触到SpringMVC与FreeMarker框架,就简单介绍一下自己的理解,不正确的地方请大家指教!! 1.Spring MVC工作原理: 用户发送请求--->前端服务器去找相对应的Cotroller--->在Controller中调用相应的接口,并将请求结果存放到model中---->将model中的值取出来渲染到前端界面上---->这样就产生了用户可以看到的响应界面. 2.FreeMarker 转载地址:http://www.oschina.net/p/free

Spring mvc 统一异常处理和静态文件的配置

1.在spring mvc下实现统一异常处理很方便,只要在web.xml中配置异常时要显示的页面即可,如下: <error-page> <exception-type>java.lang.Exception</exception-type> <location>/html/500.htm</location> </error-page> <error-page> <error-code>404</erro

Spring MVC Restful构建中静态资源访问问题

在构建Spring MVC Restful风格的应用时,由于在web.xml中: <span style="font-family:Microsoft YaHei;font-size:18px;"><servlet> <servlet-name>story</servlet-name> <servlet-class>org.springframework.web.servlet.DispatcherServlet</se

spring MVC +freemarker + easyui 实现sql查询和执行小工具总结

项目中,有时候线下不能方便的连接项目中的数据源时刻,大部分的问题定位和处理都会存在难度,有时候,一个小工具就能实时的查询和执行当前对应的数据源的库.下面,就本人在项目中实际开发使用的小工具,实时的介绍开发使用过程.首先看图:大概的操作界面,基本使用easyui组件实现,欢迎大家吐槽: 界面包含了基本的sql查询 和 sql执行的小功能,把查询和执行分开,也是为了后台实现的需要,以及权限控制的考虑,毕竟执行的操作,会影响到系统的数据问题.查询和执行的菜单,是用easyui的手风琴式的菜单处理的.两