freemark 页面静态化

来源:互联网 发布:淘宝秒杀技巧软件下载 编辑:程序博客网 时间:2024/05/16 11:55

1. 页面静态化是什么?
页面静态化有很多含义,在WEB开发中,静态网页一般理解为网站中大部分超级链接所引用的页面是单独的HTML静态页面文件(如.htm、.html等页面文件,html语言本身是静态的,不支持数据的传递,可以防止SQL注入
)。

2. 为什么都要把页面静态化呢?
对于现在的互联网应用(Web Application)来说,动态页面是占有绝对高的地位的,正因为有了动态化,才有了现在互联网的丰富多彩,但是如同所有别的事实一样,好处往往都是有代价的。为了产生出动态的效果,每一次对页面的请求都会要求服务器对页面进行编译或者执行,这些操作都很消耗系统资源。如果这期间还有和数据库的通讯,那么代价将会更大。

   如果一个页面在一定的时间内,其内容没有发生改变,那么就不必为每一次对它的访问进行一次“新”的编译或执行。我们可以把它在这段没有发生改变的时间内的 结果保存到一个静态的页面里面,然后每次访问这个页面时,就用刚才保存的静态页面进行回复。这样便能大大地减少系统资源的消耗,并且提高对客户的响应速度。而这个过程就称之为页面静态化。

3. 页面静态化方案?
目前主流的静态化主要有两种:一种是通过程序将动态页面抓取并保存为静态页面,这样的页面的实际存在于服务器的硬盘中,另外一种是通过WEB服务器的 URL Rewrite的方式,他的原理是通过web服务器内部模块按一定规则将外部的URL请求转化为内部的文件地址,一句话来说就是把外部请求的静态地址转化 为实际的动态页面地址,而静态页面实际是不存在的。这两种方法都达到了实现URL静态化的效果,但是也各有各自的特点(也叫伪静态)。
3.1. 它们的有什么区别?
将动态页面转化为实际存在的静态页面这种方法,由于静态页面的存在,少了动态解析过程,所以提高了页面的访问速度和稳定性,使得优化效果非常明显。所以这种方法被广泛采用。但是它的局限性同样存在。对于大型网站而言,这种方法将带来不可忽视的问题。

一、由于生成的文件数量较多,存储需要考虑文件、文件夹的数量问题和磁盘空间容量的问题;
二、页面维护的复杂性和大工作量,及带来的页面维护及时性问题,需要一整套站点更新制度。
而URL Rewrite方式特点同样鲜明,由于是服务器内部解析的地址,所以内容是实时更新的,也不存在文件管理和硬件问题,维护比较方便。在服务器级URL Rewrite重写技术并不影响页面的执行速度。但是URL Rewrite的门槛比较高,国内虚拟主机大多不支持,而且虚拟主机是目录级的URL Rewrite,通过遍历目录读物URL转发规则的方式将大大降低页面的执行速度。

4. 页面静态化怎么做?
先介绍上面的第一种的页面静态化,这个静态化实现了真正的静态化,做这个静态化可以用freemarker和httpclient.
Freemarker是一种基于模板的、用来生成输出文本的通用工具,所以我们必须要定制符合自己业务的模板出来,然后生成的我们得html页面
Freemarker是通过freemarker.template.Configuration这个对象对模板进行加载的(它也处理创建和缓存预解析模板的工作),然后我们通过getTemplate方法获得你想要的模板,有一点要记住freemarker.template.Configuration在你整个应用必须保证唯一实例。

Freemarker实现页面静态化主要步骤:

1.导入相关的jar包,我用servlet做的,只需要导入一个freemarker.jar

2.导入2个工具类DirectoryFilter和FreeMarkertUtil,DirectoryFilter(它实现了文件过滤器那个接口FilenameFilter)这个工具类主要是为了判断是否已经生成了特定的html文件的java类(用处不大),FreeMarkertUtil封装freemarker用于创建模板和加载模板。里面还包含了初始化模版的一个方法。

DirectoryFilter.java

package com.lyl.util;import java.io.File;import java.io.FilenameFilter;/** * 判断是否已经生成了特定的html文件的java类 * @author Administrator * */public class DirectoryFilter implements FilenameFilter {          String myString;          public DirectoryFilter(String myString)          {              this.myString = myString;          }          public boolean accept(File dir,String name)          {   //FilenameFilter.accept(File dir, String name)              // 测试指定文件是否应该包含在某一文件列表中。              String f= new File(name).getName();              if(f.contains(myString) || f.equals(myString)){                  return true;              }              return false;          }      }  

FreeMarkertUtil.java

package com.lyl.util;import java.io.IOException;import java.io.Writer;import java.util.Locale;import java.util.Map;import javax.servlet.ServletContext;import freemarker.template.Configuration;import freemarker.template.DefaultObjectWrapper;import freemarker.template.Template;import freemarker.template.TemplateException;/** * 封装freemarker用于创建模板和加载模板。里面还包含了初始化模版的一个方法 * @author Administrator * */public class FreeMarkertUtil {    private static Configuration config = new Configuration();    /**     * @param templateName     *            模板名字     * @param root     *            模板根 用于在模板内输出结果集     * @param out     *            输出对象 具体输出到哪里     */    public static void processTemplate(String templateName, Map<?, ?> root,            Writer out) {        try {            // 获得模板            Template template = config.getTemplate(templateName, "utf-8");            // 生成文件(这里是我们是生成html)            template.process(root, out);            out.flush();        } catch (IOException e) {            e.printStackTrace();        } catch (TemplateException e) {            e.printStackTrace();        } finally {            try {                out.close();                out = null;            } catch (IOException e) {                e.printStackTrace();            }        }    }    /**     * 初始化模板配置     *      * @param servletContext     *            javax.servlet.ServletContext     * @param templateDir     *            模板位置     */    public static void initConfig(ServletContext servletContext,            String templateDir) {        config.setLocale(Locale.CHINA);        config.setDefaultEncoding("utf-8");        config.setEncoding(Locale.CHINA, "utf-8");        config.setServletContextForTemplateLoading(servletContext, templateDir);        config.setObjectWrapper(new DefaultObjectWrapper());    }}

3、配置web.xml

<?xml version="1.0" encoding="UTF-8"?><web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"    xmlns="http://java.sun.com/xml/ns/javaee"    xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd"    id="WebApp_ID" version="2.5">    <display-name>freemarker_stat</display-name>    <welcome-file-list>        <welcome-file>index.html</welcome-file>        <welcome-file>index.htm</welcome-file>        <welcome-file>index.jsp</welcome-file>        <welcome-file>default.html</welcome-file>        <welcome-file>default.htm</welcome-file>        <welcome-file>default.jsp</welcome-file>    </welcome-file-list><servlet>     <servlet-name>Index</servlet-name>     <servlet-class>com.lyl.servlet.Index</servlet-class>     <init-param>      <param-name>templateDir</param-name><!-- 模板存放位置,是基于app的根目录的   -->    <param-value>/templates</param-value>     </init-param>     <load-on-startup>3</load-on-startup><!--  为了启动的时候初始化模板配置  --> </servlet>  <servlet-mapping>     <servlet-name>Index</servlet-name>     <url-pattern>/Index.do</url-pattern>   </servlet-mapping> </web-app>

4、新建jsp页面

<%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%><!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"><html><head><title>My JSP 'index.jsp' starting page</title><meta http-equiv="pragma" content="no-cache"><meta http-equiv="cache-control" content="no-cache"><meta http-equiv="Content-Type" content="text/html; charset=utf-8" />  <meta http-equiv="expires" content="0"></head><body>    <form action="Index.do" method="post">        <input type="submit" value="登录">    </form></body></html>

5、新建一个servlet 注意和web.xml中配置的跳转名称相同

package com.lyl.servlet;import java.io.File;import java.io.FileOutputStream;import java.io.IOException;import java.io.OutputStreamWriter;import java.io.Writer;import javax.servlet.ServletConfig;import javax.servlet.ServletException;import javax.servlet.http.HttpServlet;import javax.servlet.http.HttpServletRequest;import javax.servlet.http.HttpServletResponse;import com.lyl.client.ProcessClient;import com.lyl.util.DirectoryFilter;import com.lyl.util.FreeMarkertUtil;public class Index extends HttpServlet {          private static final long serialVersionUID = 7474850489594438527L;          public Index() {              super();          }          public void doGet(HttpServletRequest request, HttpServletResponse response)                  throws ServletException, IOException {              this.doPost(request, response);          }          public void doPost(HttpServletRequest request, HttpServletResponse response)                  throws ServletException, IOException {             //html生成之后存放的路径              String dirPath = request.getSession().getServletContext().getRealPath("/templates/html");              File path = new File(dirPath);            System.out.println(path);            //生成的文件的名字              String indexFileName = "index.html";              /**              * 判断是否已经存在该html文件,存在了就直接访问html ,不存在生成html文件              */              String[] indexfileList = path.list(new DirectoryFilter(indexFileName));             if(indexfileList==null||indexfileList.length<=0){                   Writer out =null;                 System.out.println("html文件不存在,创建一个HTML");                 // 字节流变为字符流  生成html文件                   out = new OutputStreamWriter(new FileOutputStream(dirPath+"/"+indexFileName),"UTF-8");                 //进去这里把动态JSP写入这个HTML                ProcessClient.processBody(out);                  request.getRequestDispatcher("/templates/html/index.html").forward(request, response);               }else{                   System.out.println("html已存在,直接访问");                request.getRequestDispatcher("/templates/html/"+indexfileList[0]).forward(request, response);               }          }          /**          * 初始化模板配置,供以后获得模板,在init里加载也主要是为保证Configuration实例唯一          */          public void init(ServletConfig config) throws ServletException {              String templateDir = config.getInitParameter("templateDir");              FreeMarkertUtil.initConfig(config.getServletContext(), templateDir);          }      }  

需要注意的几点
1 检查生成后的静态网页中图片、CSS及JS等的引用路径是否正确
2 放入Map中的数据的key必须与模版文件中接收数据的名字保持一致
3 设置的编码方式与你工程的编码方式保持一致
4 注意输出流的关闭
5 生成的静态网页文件名自定义

到这里freemark静态已经实现了 本demo下载地址下载

0 0
原创粉丝点击