| 注册
请输入搜索内容

热门搜索

Java Linux MySQL PHP JavaScript Hibernate jQuery Nginx
DFRJasper
8年前发布

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

一、原理

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>

四、运行结果

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

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

来自: http://www.cnblogs.com/caoyusongnet/p/5150850.html

 本文由用户 DFRJasper 自行上传分享,仅供网友学习交流。所有权归原作者,若您的权利被侵害,请联系管理员。
 转载本站原创文章,请注明出处,并保留原始链接、图片水印。
 本站是一个以用户分享为主的开源技术平台,欢迎各类分享!
 本文地址:https://www.open-open.com/lib/view/open1453451157823.html
HTML JSP FreeMarker 模板引擎