转载

使用Freemarker 实现JSP页面的静态化

使用Freemarker 静态化网页

一、原理

Freemarker 生成静态页面,首先需要使用自己定义的模板页面,这个模板页面可以是最最普通的 html ,也可以是嵌套 freemarker 中的 取值表达式, 标签或者自定义标签等等,然后后台读取这个模板页面,解析其中的标签完成相对应的操作, 然后采用键值对的方式传递参数替换模板中的的取值表达式,做完之后 根据配置的路径生成一个新的 html 页面, 以达到静态化访问的目的。

二、Freemaker 提供的标签

Freemarker 提供了很多有用 常用的标签, 具体可以分为三个部分:Freemarker 标签都是 类似 Html 标签 , 不同的是它是为了与 HTML 标记区分,用 # 开始。例如 <# 标签名称 > ;${value}  表示输出变量名的内容   ;注释:包含在 <#-- --> (而不是 <!-- --> )之间;

三、Freemaker 实现网页静态化 DEMO

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

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

 Body.ftl  <!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:8082/JspToHtml/DelUser.do?id=${user.id}">删除</a></td>            </tr>        </#list>              </table>    <hr/>      <#include "footer.ftl" parse=true encoding="utf-8">      </body>    </html>    Footer.ftl  ${f.des}<br/>   Header.ftl  company:${h.companyName}<br/>    address:${h.address}<br/>    它们对于的实体类分别是:  User.java  package com.cys.jsptohtml.schema;     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();        }                    }    Header.java  package com.cys.jsptohtml.schema;        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;        }          }    Footer.java  package com.cys.jsptohtml.schema;        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;        }     }    对应的Service有(在Service中模仿了数据库操作):  UserService.java:  package com.cys.jsptohtml.service;     import java.util.ArrayList;  import java.util.Date;  import java.util.List;     import com.cys.jsptohtml.schema.User;     public class UserService {            private static List<User> users = new ArrayList<User>();                static{            for(int i=0;i<10;i++){                User u = new User(i,"cys"+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);                }            }        }    }     HeaderService.java  package com.cys.jsptohtml.service;     import com.cys.jsptohtml.schema.Header;     public class HeaderService {            private static Header h = new Header();                static{            h.setAddress("中关村东路");            h.setCompanyName("中科软");        }                public static void update(String address,String companyName){            h.setAddress(address);            h.setCompanyName(companyName);        }                public static Header getHeader(){            return h;        }    }    FooterService.java  package com.cys.jsptohtml.service;     import com.cys.jsptohtml.schema.Footer;           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;        }    }    Servlet操作:  DelUser.java  package com.cys.jsptohtml.servlet;     import java.io.File;  import java.io.FileOutputStream;  import java.io.FilenameFilter;  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.cys.jsptohtml.service.UserService;  import com.cys.jsptohtml.util.ProcessClient;      /**    * @author cys    **/    @SuppressWarnings("serial")  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 {             System.out.println("Del dopost");          String id = request.getParameter("id");            UserService.delete(Integer.valueOf(id));                        //生成html的位置            String dirPath = request.getSession().getServletContext().getRealPath("/templateDir/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, "body.ftl");          response.sendRedirect("templateDir/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 FilenameFilter(){     public boolean accept(File dir, String name) {  return name.endsWith(".html");  }                    });            if(indexfileList.length>0){                for(String f:indexfileList){                    File delf = new File(htmlDir+"/"+f);                    delf.delete();                }            }        }        }  JspToHtmlServlet.java  package com.cys.jsptohtml.servlet;     import java.io.File;  import java.io.FileOutputStream;  import java.io.FilenameFilter;  import java.io.IOException;  import java.io.OutputStreamWriter;  import java.io.Writer;     import javax.servlet.ServletException;  import javax.servlet.http.HttpServlet;  import javax.servlet.http.HttpServletRequest;  import javax.servlet.http.HttpServletResponse;     import com.cys.jsptohtml.util.ProcessClient;     public class JspToHtmlServlet extends HttpServlet{     private static final long serialVersionUID = 1L;     public JspToHtmlServlet() {            super();        }           public void doGet(HttpServletRequest request,HttpServletResponse response)                throws ServletException, IOException {         System.out.println("doget");          this.doPost(request, response);        }                public void doPost(HttpServletRequest request,   HttpServletResponse response)                throws ServletException, IOException {         System.out.println("doPost");          // html生成之后存放的路径          String dirPath = request.getSession().getServletContext().getRealPath("/templateDir/html");            File path = new File(dirPath);            // 生成的文件的名字          String indexFileName = "index.html";            /**   * 判断是否已经存在该html文件,存在了就直接访问html ,不存在生成html文件   */            String[] indexfileList = path.list(new FilenameFilter(){     public boolean accept(File dir, String name) {  return name.endsWith(".html");  }          });          System.out.println(indexfileList);          if(indexfileList.length<=0){                Writer out = new OutputStreamWriter(new FileOutputStream(dirPath+"/"+indexFileName),"UTF-8");               // 生成html文件              ProcessClient.processBody(out,"body.ftl");                request.getRequestDispatcher("/templateDir/html/index.html").forward(request, response);             }else{                request.getRequestDispatcher("/templateDir/html/"+indexfileList[0]).forward(request, response);             }          }  }  Login.java(该类用于测试环境,与静态化无关)  package com.cys.jsptohtml.servlet;     import java.io.IOException;     import javax.servlet.ServletException;  import javax.servlet.http.HttpServlet;  import javax.servlet.http.HttpServletRequest;  import javax.servlet.http.HttpServletResponse;     public class Login extends HttpServlet{      private static final long serialVersionUID = 7474850489594438527L;    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {          doPost(request, response);      }         protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {          request.setCharacterEncoding("UTF-8");            response.setContentType("text/html;charset=utf-8");                    String action = request.getParameter("action");            if("login_input".equals(action)) {                request.getRequestDispatcher("login.jsp").forward(request , response);            } else if("login".equals(action)) {                String name = request.getParameter("name");                String password = request.getParameter("password");                                System.out.println("name->" + name + ",password->" + password);          }      }     }  Jsp页面:  Index.jsp  <%@ page language="java" contentType="text/html; charset=UTF-8"      pageEncoding="UTF-8"%>  <!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">  <html>  <head>  <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">  <title>Insert title here</title>  </head>  <body>      <p>用Maven创建web项目,测试Servlet</p>      <a href="demo?action=login_input">登录(demo?action=login_input)</a>      <a href="index?action=login_input">静态化</a>  </body>  </html>  Login.jsp  <%@ page language="java" contentType="text/html; charset=UTF-8"      pageEncoding="UTF-8"%>  <!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">  <html>  <head>  <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">  <title>Insert title here</title>  </head>  <body>      <form action="demo?action=login" method="post">            Name:<input type="text" name="name" />            Password:<input type="password" name="password" />                            <input type="submit" value="登录" />        </form>    </body>  </html>  Web.xml  <?xml version="1.0" encoding="UTF-8"?>  <web-app xmlns:javaee="http://java.sun.com/xml/ns/javaee" xmlns:web="http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd">    <javaee:display-name>Archetype Created Web Application</javaee:display-name>    <servlet>      <javaee:description></javaee:description>      <javaee:display-name>ServletDemo</javaee:display-name>      <servlet-name>ServletDemo</servlet-name>      <servlet-class>com.cys.jsptohtml.servlet.Login</servlet-class>    </servlet>    <servlet-mapping>      <servlet-name>ServletDemo</servlet-name>      <url-pattern>/demo</url-pattern>    </servlet-mapping>        <servlet>       <servlet-name>Index</servlet-name>       <servlet-class>com.cys.jsptohtml.servlet.JspToHtmlServlet</servlet-class>       <load-on-startup>3</load-on-startup>   </servlet>         <servlet-mapping>       <servlet-name>Index</servlet-name>       <url-pattern>/index</url-pattern>     </servlet-mapping>        <servlet>       <servlet-name>DelUser</servlet-name>       <servlet-class>com.cys.jsptohtml.servlet.DelUser</servlet-class>       <load-on-startup>3</load-on-startup>   </servlet>         <servlet-mapping>       <servlet-name>DelUser</servlet-name>       <url-pattern>/DelUser.do</url-pattern>     </servlet-mapping>   </web-app>  Util类:  FreeMarkertUtil .java  package com.cys.jsptohtml.util;  import java.io.IOException;  import java.io.Writer;  import java.util.Map;     import freemarker.template.Configuration;  import freemarker.template.Template;  import freemarker.template.TemplateException;     public class FreeMarkertUtil {     public Template getTemplate(String name) {          try {              // 通过Freemaker的Configuration读取相应的ftl              Configuration cfg = new Configuration();              // 设定去哪里读取相应的ftl模板文件              cfg.setClassForTemplateLoading(this.getClass(), "ftl");              // 在模板文件目录中找到名称为name的文件              Template temp = cfg.getTemplate(name);              System.out.println(temp.getName());              return temp;          } catch (IOException e) {              e.printStackTrace();          }          return null;      }      /**        * @param templateName 模板名字        * @param root 模板根 用于在模板内输出结果集        * @param out 输出对象 具体输出到哪里        */        public  void processTemplate(Template template,Map<?,?> root, Writer out){            try{             System.out.println("processTemplate");              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();                }            }        }    }  在该类中加载模板的方式有多种:  void setDirectoryForTemplateLoading(File dir);// 根据全路径加载 void setClassForTemplateLoading(Class cl, String prefix);//根据类的路径加载,prefix为模板前缀  void setServletContextForTemplateLoading(Object servletContext, String path); //根据web上下文  从多地址加载模板  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 目录下加载,如果还是没有发现请求的模板,那么它就会使用类加载器来加载模板。     ProcessClient .java     package com.cys.jsptohtml.util;     import java.io.Writer;  import java.util.HashMap;  import java.util.List;  import java.util.Map;     import com.cys.jsptohtml.schema.Footer;  import com.cys.jsptohtml.schema.Header;  import com.cys.jsptohtml.schema.User;  import com.cys.jsptohtml.service.FooterService;  import com.cys.jsptohtml.service.HeaderService;  import com.cys.jsptohtml.service.UserService;     import freemarker.template.Template;             /**    * @author cys     **/    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,String filename){            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 freeMarkertUtil = new FreeMarkertUtil();          Template template = freeMarkertUtil.getTemplate(filename);          freeMarkertUtil.processTemplate(template, root, out);      }    }     Pom.xml(对应的jar包,以及插件):     <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"    xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">    <modelVersion>4.0.0</modelVersion>    <groupId>com.cys</groupId>    <artifactId>JspToHtml</artifactId>    <packaging>war</packaging>    <version>0.0.1-SNAPSHOT</version>    <name>JspToHtml Maven Webapp</name>    <url>http://maven.apache.org</url>    <dependencies>      <dependency>        <groupId>junit</groupId>        <artifactId>junit</artifactId>        <version>3.8.1</version>        <scope>test</scope>      </dependency>     <dependency>           <groupId>javax.servlet</groupId>           <artifactId>servlet-api</artifactId>           <version>2.5</version>           <scope>provided</scope>          </dependency>      <dependency>      <groupId>javax.servlet.jsp</groupId>      <artifactId>jsp-api</artifactId>      <version>2.1</version>      <scope>provided</scope>  </dependency>  <dependency>    <groupId>org.freemarker</groupId>    <artifactId>freemarker</artifactId>    <version>2.3.23</version>  </dependency>    </dependencies>     <build>      <finalName>codingdream</finalName>      <plugins>        <plugin>  <groupId>org.codehaus.mojo</groupId>  <artifactId>tomcat-maven-plugin</artifactId>  <version>1.1</version>  <configuration>      <path></path>      <port>8082</port>      <uriEncoding>UTF-8</uriEncoding>      <url>http://localhost:8087/codingdream</url>      <server>tomcat6</server>  </configuration>  </plugin>      </plugins>    </build>  </project> 

四、运行结果

使用Freemarker 实现JSP页面的静态化

使用Freemarker 实现JSP页面的静态化 使用Freemarker 实现JSP页面的静态化

参考:http://freemarker.incubator.apache.org/

http://blog.csdn.net/ajun_studio/article/details/6932185/

原文  http://www.cnblogs.com/caoyusongnet/p/5150850.html
正文到此结束
Loading...