利用freemarker 静态化网页

xiaoxiao2021-02-28  82

1、介绍-FreeMarker是什么

     模板引擎:一种基于模板的、用来生成输出文本的通用工具

     基于Java的开发包和类库

    

2、介绍-FreeMarker能做什么

     MVC框架中的View层组件

     Html页面静态化

    代码生成工具

    CMS模板引擎

  页面栏目动态定制

3、介绍-为什么要用FreeMarker

      程序逻辑(Java 程序)和页面设计(FreeMarker模板)分离

      分层清晰,利于分工合作

      主流Web框架良好的集成(struts2,springmvc)

      简单易学、功能强大

      免费开源

4、FreeMarker优点

     FreeMarker不依赖于Servlet,网络或Web 环境

     FreeMarker一开始就是为MVC设计的,它仅仅专注于展示

     你可以从任意位置加载模板;从类路径下,从数据库中等

     易于定义特设的宏和函数

5、上面简单介绍一下Freemarker,下面主要是利用Freemarker实习网页静态化的功能。

通过上面的介绍知道Freemarker是一种基于模板的、用来生成输出文本的通用工具,所以我们必须要定制符合自己业务的模板出来,然后生成的我们得html页面

Freemarker是通过freemarker.template.Configuration这个对象对模板进行加载的(它也处理创建和缓存预解析模板的工作),然后我们通过getTemplate方法获得你想要的模板,有一点要记住freemarker.template.Configuration在你整个应用必须保证唯一实例。

5.1、在Configuration 中可以使用下面的方法来方便建立三种模板加载

[java] view plain copy print ? void setDirectoryForTemplateLoading(File dir);   void setDirectoryForTemplateLoading(File dir); [java] view plain copy print ? void setClassForTemplateLoading(Class cl, String prefix);   void setClassForTemplateLoading(Class cl, String prefix); [java] view plain copy print ? void setServletContextForTemplateLoading(Object servletContext, String path);   void setServletContextForTemplateLoading(Object servletContext, String path);上述的第一种方法在磁盘的文件系统上设置了一个明确的目录,它确定了从哪里加载模板。不要说可能,File 参数肯定是一个存在的目录。否则,将会抛出异常。 第二种调用方法使用了一个Class 类型的参数和一个前缀。这是让你来指定什么时候通过相同的机制来加载模板,不过是用Java 的ClassLoader 来加载类。这就意味着传 入的Class 参数会被用来调用Class.getResource()方法来找到模板。参数prefix是给模板的名称来加前缀的。在实际运行的环境中,类加载机制是首选用来加载模板的方法,因为通常情况下,从类路径下加载文件的这种机制,要比从文件系统的特定目录位置加载安全而且简单。在最终的应用程序中,所有代码都使用.jar 文件打包也是不错的,这样用户就可以直接执行包含所有资源的.jar 文件了。 第三种调用方式需要Web 应用的上下文和一个基路径作为参数,这个基路径是Web 应用根路径(WEB-INF 目录的上级目录)的相对路径。那么加载器将会从Web 应用目录开 始加载模板。尽管加载方法对没有打包的.war 文件起作用, 因为它使用了ServletContext.getResource()方法来访问模板,注意这里我们指的是“目录”。如果忽略了第二个参数(或使用了””),那么就可以混合存储静态文件(.html,.jpg 等)和.ftl 文件,只是.ftl 文件可以被送到客户端执行。当然必须在WEB-INF/web.xml中配置一个Servlet 来处理URI 格式为*.ftl 的用户请求,否则客户端无法获取到模板,因此你将会看到Web 服务器给出的秘密提示内容。在站点中不能使用空路径,这将成为一个问题,你应该在WEB-INF 目录下的某个位置存储模板文件,这样模板源文件就不会偶然 void setDirectoryForTemplateLoading(File dir); void setClassForTemplateLoading(Class cl, String prefix); void setServletContextForTemplateLoading(Object servletContext, String path); 地被执行到,这种机制对servlet 应用程序来加载模板来说,是非常好用的方式,而且模板可以自动更新而不需重启Web 应用程序,但是对于类加载机制,这样就行不通了。

5.2、从多个位置加载模板

[java] view plain copy print ? import freemarker.cache.*; // 模板加载器在这个包下  ...  FileTemplateLoader ftl1 = new FileTemplateLoader(new File("/tmp/templates"));  FileTemplateLoader ftl2 = new FileTemplateLoader(new File("/usr/data/templates"));  ClassTemplateLoader ctl = new ClassTemplateLoader(getClass(),"");  TemplateLoader[] loaders = new TemplateLoader[] { ftl1, ftl2,ctl };  MultiTemplateLoader mtl = new MultiTemplateLoader(loaders);  cfg.setTemplateLoader(mtl);   import freemarker.cache.*; // 模板加载器在这个包下 ... FileTemplateLoader ftl1 = new FileTemplateLoader(new File("/tmp/templates")); FileTemplateLoader ftl2 = new FileTemplateLoader(new File("/usr/data/templates")); ClassTemplateLoader ctl = new ClassTemplateLoader(getClass(),""); TemplateLoader[] loaders = new TemplateLoader[] { ftl1, ftl2,ctl }; MultiTemplateLoader mtl = new MultiTemplateLoader(loaders); cfg.setTemplateLoader(mtl);现在,FreeMarker 将会尝试从/tmp/templates 目录加载模板,如果在这个目录下没有发现请求的模板,它就会继续尝试从/usr/data/templates 目录下加载,如果还是没有发现请求的模板,那么它就会使用类加载器来加载模板。

5.3、封装freemarker用于创建模板和加载模板

[java] view plain copy print ? package com.ajun.template.utils;    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;    /**  * @author ajun  * @http://blog.csdn.net/ajun_studio    **/  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());      }  }   package com.ajun.template.utils; 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; /** * @author ajun * @http://blog.csdn.net/ajun_studio **/ 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()); } }

5.4、例子介绍

会用freemarker.jar自己google下载吧。

这个例子中我们会Freemarker生成一个html文件 包括html的头部和尾部,已经body,这三个部分会分别对应三个模板文件,如下:

在模板内要想输出结果集 可以用类似于EL表达式输出${}

header.ftl

[plain] view plain copy print ? companyName==>${h.companyName}<br/>  address==>${h.address}<br/>   companyName==>${h.companyName}<br/> address==>${h.address}<br/>footer.ftl

[plain] view plain copy print ? des==>${f.des}<br/>    <a href="http://localhost/htmlpage/UpdateFooter.do"> 更新Footer </a>   des==>${f.des}<br/> <a href="http://localhost/htmlpage/UpdateFooter.do"> 更新Footer </a> body.ftl,这个模板include以上两个模板文件

[plain] view plain copy print ? <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">  <html>    <head>      <title>用户列表</title>            <meta http-equiv="pragma" content="no-cache">      <meta http-equiv="cache-control" content="no-cache">      <meta http-equiv="expires" content="0">          <meta http-equiv="keywords" content="keyword1,keyword2,keyword3">      <meta http-equiv="description" content="This is my page">      <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />      <!--      <link rel="stylesheet" type="text/css" href="styles.css">      -->       </head>        <body>    <#include "header.ftl" parse=true encoding="utf-8">    <hr/>    <a href="#">用户列表</a><br/>    <table border="1">      <tr>          <td>用户名</td>          <td>年龄</td>          <td>生日</td>          <td>id</td>          <td>操作</td>      </tr>      <#list users as user>          <tr>              <td>${user.name}</td>              <td>${user.age}</td>              <td>              ${user.birthday?string("yyyy-MM-dd HH:mm:ss")}              </td>              <td>${user.id}</td>              <td><a href="http://localhost/htmlpage/DelUser.do?id=${user.id}">删除</a></td>          </tr>      </#list>          </table>  <hr/>    <#include "footer.ftl" parse=true encoding="utf-8">    </body>  </html>   <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"> <html> <head> <title>用户列表</title> <meta http-equiv="pragma" content="no-cache"> <meta http-equiv="cache-control" content="no-cache"> <meta http-equiv="expires" content="0"> <meta http-equiv="keywords" content="keyword1,keyword2,keyword3"> <meta http-equiv="description" content="This is my page"> <meta http-equiv="Content-Type" content="text/html; charset=utf-8" /> <!-- <link rel="stylesheet" type="text/css" href="styles.css"> --> </head> <body> <#include "header.ftl" parse=true encoding="utf-8"> <hr/> <a href="#">用户列表</a><br/> <table border="1"> <tr> <td>用户名</td> <td>年龄</td> <td>生日</td> <td>id</td> <td>操作</td> </tr> <#list users as user> <tr> <td>${user.name}</td> <td>${user.age}</td> <td> ${user.birthday?string("yyyy-MM-dd HH:mm:ss")} </td> <td>${user.id}</td> <td><a href="http://localhost/htmlpage/DelUser.do?id=${user.id}">删除</a></td> </tr> </#list> </table> <hr/> <#include "footer.ftl" parse=true encoding="utf-8"> </body> </html> 这三个模板对应的三个实体类

Footer.java

[java] view plain copy print ? package com.ajun.template.bean;    /**  * @author ajun  * @http://blog.csdn.net/ajun_studio    **/  public class Footer {        private String des;        public String getDes() {          return des;      }        public void setDes(String des) {          this.des = des;      }              }   package com.ajun.template.bean; /** * @author ajun * @http://blog.csdn.net/ajun_studio **/ public class Footer { private String des; public String getDes() { return des; } public void setDes(String des) { this.des = des; } } Header.java

[java] view plain copy print ? package com.ajun.template.bean;  /**  * @author ajun  * @http://blog.csdn.net/ajun_studio    **/  public class Header {        private String companyName;            private String address;        public String getCompanyName() {          return companyName;      }        public void setCompanyName(String companyName) {          this.companyName = companyName;      }        public String getAddress() {          return address;      }        public void setAddress(String address) {          this.address = address;      }                    }   package com.ajun.template.bean; /** * @author ajun * @http://blog.csdn.net/ajun_studio **/ public class Header { private String companyName; private String address; public String getCompanyName() { return companyName; } public void setCompanyName(String companyName) { this.companyName = companyName; } public String getAddress() { return address; } public void setAddress(String address) { this.address = address; } } User.java

[java] view plain copy print ? package com.ajun.template.bean;    import java.util.Date;    public class User {            private Integer id;        private String name ;            private int age;            private Date birthday;        public String getName() {          return name;      }        public void setName(String name) {          this.name = name;      }        public int getAge() {          return age;      }        public void setAge(int age) {          this.age = age;      }        public Date getBirthday() {          return birthday;      }        public void setBirthday(Date birthday) {          this.birthday = birthday;      }              public Integer getId() {          return id;      }        public void setId(Integer id) {          this.id = id;      }        public User(Integer id,String name, int age, Date birthday) {          super();          this.name = name;          this.age = age;          this.birthday = birthday;          this.id = id;      }        public User() {          super();      }              }   package com.ajun.template.bean; import java.util.Date; public class User { private Integer id; private String name ; private int age; private Date birthday; public String getName() { return name; } public void setName(String name) { this.name = name; } public int getAge() { return age; } public void setAge(int age) { this.age = age; } public Date getBirthday() { return birthday; } public void setBirthday(Date birthday) { this.birthday = birthday; } public Integer getId() { return id; } public void setId(Integer id) { this.id = id; } public User(Integer id,String name, int age, Date birthday) { super(); this.name = name; this.age = age; this.birthday = birthday; this.id = id; } public User() { super(); } } 下面模板一些业务逻辑操作,对这三个实体类

[java] view plain copy print ? package com.ajun.template.service;    import com.ajun.template.bean.Footer;  /**  * @author ajun  * @http://blog.csdn.net/ajun_studio    **/  public class FooterService {        private static Footer f = new Footer();      static{          f.setDes("北京-廊坊-好公司呢!!!!哇哈哈!!!");      }            public static void update(String des){          f.setDes(des);      }            public static Footer gerFooter(){          return f;      }  }   package com.ajun.template.service; import com.ajun.template.bean.Footer; /** * @author ajun * @http://blog.csdn.net/ajun_studio **/ public class FooterService { private static Footer f = new Footer(); static{ f.setDes("北京-廊坊-好公司呢!!!!哇哈哈!!!"); } public static void update(String des){ f.setDes(des); } public static Footer gerFooter(){ return f; } } [java] view plain copy print ? package com.ajun.template.service;    import com.ajun.template.bean.Header;  /**  * @author ajun  * @http://blog.csdn.net/ajun_studio    **/  public class HeaderService {        private static Header h = new Header();            static{          h.setAddress("北京朝阳CBD");          h.setCompanyName("上海唐秀!!!");      }            public static void update(String address,String companyName){          h.setAddress(address);          h.setCompanyName(companyName);      }            public static Header getHeader(){          return h;      }  }   package com.ajun.template.service; import com.ajun.template.bean.Header; /** * @author ajun * @http://blog.csdn.net/ajun_studio **/ public class HeaderService { private static Header h = new Header(); static{ h.setAddress("北京朝阳CBD"); h.setCompanyName("上海唐秀!!!"); } public static void update(String address,String companyName){ h.setAddress(address); h.setCompanyName(companyName); } public static Header getHeader(){ return h; } } [java] view plain copy print ? package com.ajun.template.service;    import java.util.ArrayList;  import java.util.Date;  import java.util.List;    import com.ajun.template.bean.User;  /**  * @author ajun  * @http://blog.csdn.net/ajun_studio    **/  public class UserService {        private static List<User> users = new ArrayList<User>();            static{          for(int i=0;i<10;i++){              User u = new User(i,"ajun"+i,i+10,new Date());              users.add(u);          }      }            public static List<User> getUsers(){          return users;      }            public static void delete(int index){          for(int i=0 ;i<users.size();i++){              User u = users.get(i);              if(u.getId()==index){                  users.remove(u);                  //users.remove(index);              }          }      }  }   package com.ajun.template.service; import java.util.ArrayList; import java.util.Date; import java.util.List; import com.ajun.template.bean.User; /** * @author ajun * @http://blog.csdn.net/ajun_studio **/ public class UserService { private static List<User> users = new ArrayList<User>(); static{ for(int i=0;i<10;i++){ User u = new User(i,"ajun"+i,i+10,new Date()); users.add(u); } } public static List<User> getUsers(){ return users; } public static void delete(int index){ for(int i=0 ;i<users.size();i++){ User u = users.get(i); if(u.getId()==index){ users.remove(u); //users.remove(index); } } } } 上面主要是模板你的一些业务和dao层得操作,因此没有涉及数据库的操作,主要是为实验。

生成html对外调用的方法,会用到FreeMarkertUtil这个类 这个类得代码上面已经给出。

[java] view plain copy print ? package com.ajun.template.client;    import java.io.Writer;  import java.util.HashMap;  import java.util.List;  import java.util.Map;    import com.ajun.template.bean.Footer;  import com.ajun.template.bean.Header;  import com.ajun.template.bean.User;  import com.ajun.template.service.FooterService;  import com.ajun.template.service.HeaderService;  import com.ajun.template.service.UserService;  import com.ajun.template.utils.FreeMarkertUtil;    /**  * @author ajun  * @http://blog.csdn.net/ajun_studio    **/  public class ProcessClient {        private static Map<String,Object> root = new HashMap<String,Object>();        /**      * 调用FreeMarkertUtil.java      * FreeMarkertUtil.processTemplate("body.ftl", root, out);      * 来生成html文件      * @param out      */      public static void processBody(Writer out){          Header h = HeaderService.getHeader();          root.put("h", h);          Footer f = FooterService.gerFooter();          root.put("f", f);          List<User> users = UserService.getUsers();          root.put("users", users);          FreeMarkertUtil.processTemplate("body.ftl", root, out);      }        }   package com.ajun.template.client; import java.io.Writer; import java.util.HashMap; import java.util.List; import java.util.Map; import com.ajun.template.bean.Footer; import com.ajun.template.bean.Header; import com.ajun.template.bean.User; import com.ajun.template.service.FooterService; import com.ajun.template.service.HeaderService; import com.ajun.template.service.UserService; import com.ajun.template.utils.FreeMarkertUtil; /** * @author ajun * @http://blog.csdn.net/ajun_studio **/ public class ProcessClient { private static Map<String,Object> root = new HashMap<String,Object>(); /** * 调用FreeMarkertUtil.java * FreeMarkertUtil.processTemplate("body.ftl", root, out); * 来生成html文件 * @param out */ public static void processBody(Writer out){ Header h = HeaderService.getHeader(); root.put("h", h); Footer f = FooterService.gerFooter(); root.put("f", f); List<User> users = UserService.getUsers(); root.put("users", users); FreeMarkertUtil.processTemplate("body.ftl", root, out); } } 此时我会提供一个servlet在客户端进行第一次请求的时候 我会调用这个ProcessClient来生成html页面,之后每次访问就可以直接访问html,来做到真正的静态化了

[java] view plain copy print ? package com.ajun.template.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.ajun.template.client.ProcessClient;  import com.ajun.template.utils.DirectoryFilter;  import com.ajun.template.utils.FreeMarkertUtil;    /**  * @author ajun  * @http://blog.csdn.net/ajun_studio    **/  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);          //生成的文件的名字          String indexFileName = "index.html";          /**          * 判断是否已经存在该html文件,存在了就直接访问html ,不存在生成html文件          */          String[] indexfileList = path.list(new DirectoryFilter(indexFileName));          if(indexfileList.length<=0){              Writer out = new OutputStreamWriter(new FileOutputStream(dirPath+"/"+indexFileName),"UTF-8");              //生成html文件              ProcessClient.processBody(out);              request.getRequestDispatcher("/templates/html/index.html").forward(request, response);           }else{              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);      }          }   package com.ajun.template.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.ajun.template.client.ProcessClient; import com.ajun.template.utils.DirectoryFilter; import com.ajun.template.utils.FreeMarkertUtil; /** * @author ajun * @http://blog.csdn.net/ajun_studio **/ 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); //生成的文件的名字 String indexFileName = "index.html"; /** * 判断是否已经存在该html文件,存在了就直接访问html ,不存在生成html文件 */ String[] indexfileList = path.list(new DirectoryFilter(indexFileName)); if(indexfileList.length<=0){ Writer out = new OutputStreamWriter(new FileOutputStream(dirPath+"/"+indexFileName),"UTF-8"); //生成html文件 ProcessClient.processBody(out); request.getRequestDispatcher("/templates/html/index.html").forward(request, response); }else{ 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); } } web.xml配置

[html] view plain copy print ? <servlet>     <description>This is the description of my J2EE component</description>     <display-name>This is the display name of my J2EE component</display-name>     <servlet-name>Index</servlet-name>     <servlet-class>com.ajun.template.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>   <servlet> <description>This is the description of my J2EE component</description> <display-name>This is the display name of my J2EE component</display-name> <servlet-name>Index</servlet-name> <servlet-class>com.ajun.template.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> 部署到tomcat上,输入: http://localhost/htmlpage/Index.do

页面效果:

页面是做好了,但是内容变化了 ,更新怎么办呢,我这里是当列表内容变化之后 ,我是删除原来的html ,利用模板然后重新生成的符合新结果的html页面

当我删除一条的时候,我会重新生成html页面,但是由于浏览器缓存的原因,即是你删除了,重新生成了新html页面,可是浏览器还是保存原来的页面,不刷新两次是不行的,

这里我采用的没更新的时候,都会给这个html改个名字,让浏览器去加载最新的,就可以了

具体的删除操作如下:

[java] view plain copy print ? package com.ajun.template.servlet;    import java.io.File;  import java.io.FileOutputStream;  import java.io.IOException;  import java.io.OutputStreamWriter;  import java.io.Writer;  import java.util.UUID;    import javax.servlet.ServletException;  import javax.servlet.http.HttpServlet;  import javax.servlet.http.HttpServletRequest;  import javax.servlet.http.HttpServletResponse;    import com.ajun.template.client.ProcessClient;  import com.ajun.template.service.UserService;  import com.ajun.template.utils.DirectoryFilter;  /**  * @author ajun  * @http://blog.csdn.net/ajun_studio    **/  public class DelUser extends HttpServlet {              public void doGet(HttpServletRequest request, HttpServletResponse response)              throws ServletException, IOException {              this.doPost(request, response);      }        //删除用户      public void doPost(HttpServletRequest request, HttpServletResponse response)              throws ServletException, IOException {                    String id = request.getParameter("id");          UserService.delete(Integer.valueOf(id));                    //生成html的位置          String dirPath = request.getSession().getServletContext().getRealPath("/templates/html");          //文件名字          String indexFileName = "index.html";                    //删除原来的文件          delOldHtml(dirPath,indexFileName);                    //防止浏览器缓存,用于重新生成新的html          UUID uuid = UUID.randomUUID();          Writer out = new OutputStreamWriter(new FileOutputStream(dirPath+"/"+uuid+indexFileName),"UTF-8");          ProcessClient.processBody(out);          response.sendRedirect("templates/html/"+uuid+"index.html");      }            /**      * 删除原来的html文件      * @param htmlDir      * @param htmlName      */      private void delOldHtml(String htmlDir,String htmlName){          File path = new File(htmlDir);          String[] indexfileList = path.list(new DirectoryFilter(htmlName));          if(indexfileList.length>=0){              for(String f:indexfileList){                  File delf = new File(htmlDir+"/"+f);                  delf.delete();              }          }      }    }   package com.ajun.template.servlet; import java.io.File; import java.io.FileOutputStream; import java.io.IOException; import java.io.OutputStreamWriter; import java.io.Writer; import java.util.UUID; import javax.servlet.ServletException; import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import com.ajun.template.client.ProcessClient; import com.ajun.template.service.UserService; import com.ajun.template.utils.DirectoryFilter; /** * @author ajun * @http://blog.csdn.net/ajun_studio **/ public class DelUser extends HttpServlet { public void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { this.doPost(request, response); } //删除用户 public void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { String id = request.getParameter("id"); UserService.delete(Integer.valueOf(id)); //生成html的位置 String dirPath = request.getSession().getServletContext().getRealPath("/templates/html"); //文件名字 String indexFileName = "index.html"; //删除原来的文件 delOldHtml(dirPath,indexFileName); //防止浏览器缓存,用于重新生成新的html UUID uuid = UUID.randomUUID(); Writer out = new OutputStreamWriter(new FileOutputStream(dirPath+"/"+uuid+indexFileName),"UTF-8"); ProcessClient.processBody(out); response.sendRedirect("templates/html/"+uuid+"index.html"); } /** * 删除原来的html文件 * @param htmlDir * @param htmlName */ private void delOldHtml(String htmlDir,String htmlName){ File path = new File(htmlDir); String[] indexfileList = path.list(new DirectoryFilter(htmlName)); if(indexfileList.length>=0){ for(String f:indexfileList){ File delf = new File(htmlDir+"/"+f); delf.delete(); } } } } 通过以上操作,每次更新html,就可以不解决浏览器缓存的问题了。

还有一个工具类需要介绍,就是判断是否已经生成了特定的html文件的java类

[java] view plain copy print ? package com.ajun.template.utils;    import java.io.File;  import java.io.FilenameFilter;  /**  * @author ajun  * @http://blog.csdn.net/ajun_studio    **/  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;      }    }   package com.ajun.template.utils; import java.io.File; import java.io.FilenameFilter; /** * @author ajun * @http://blog.csdn.net/ajun_studio **/ 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; } }

到这里整个静态化就完成了,静态化更新机制,是根据你自己项目的业务进行定制的,可以定时生成html文件,也可以需要手动生成。

项目结构图如下:

记住:网站不是所有的页面都是需要静态化的,主要是一些实时性不是很高的数据页面进行静态化(来提高访问速度),其他都是通过伪静态来实现的,就是重写utl。 页面静态化不是提高网站性能的唯一途径,还可以利用一些缓存产品来实现。

常用FreeMarker资源

官网主页:http://www.freemarker.org/

Eclipse插件JbossTool:http://www.jboss.org/tools/download/

中文文档:https://sourceforge.net/projects/freemarker/files/chinese-manual/FreeMarker_Manual_zh_CN.pdf/download

转载请注明原文地址: https://www.6miu.com/read-76057.html

最新回复(0)