`
feijing
  • 浏览: 19723 次
  • 性别: Icon_minigender_1
最近访客 更多访客>>
社区版块
存档分类
最新评论

 jsp静态生成页面技术分析

阅读更多
  jsp静态生成页面技术分析

  Ajax + Struts + XML解决静态页面方案(原创)

  对于其他几位前辈提出的方案,我也是受益良深,所以方案中,最简单的就是将JSP输出为HTML,最麻烦的是利用IO将输出信息组成HTML文件,最难的对我来说应该是生成XML的方案。我没有学XSL,但据说比较难,远不如HTML那么容易。尽管如此,生成XML这种方案却是我最欣赏的,原因有四:

  第一是实现了表示与数据的分离;

  第二是易于操作,增删改都相当方便;

  第三是跨平台特性让它应用领域更广;

  第四XML本身就可以当数据库使用,使得它可以合理组织数据。

  OK,基于这些原因,小弟在推敲中想到一个解决方案:如果我们在服务器生成若干XML文档,由统一的HTML装载,然后客户端执行HTML时,通过AJAX异步载入XML文档数据,那么结果是否会达到达人心动的效果呢?

  实现此技术需要解决的问题:

  1. 从数据库取数据动态生成并写入XML文件

  2. 利用URL传入XML文档名

  3. 客户端使用JS解析URL取XML文档名然后使用AJAX载入文件,最后动态组织数据到页面中

例子源码如下

第一步,加入servlet.代码如下。


      public class ToHtml extends HttpServlet {

       public void service(HttpServletRequest request, HttpServletResponse response)
         throws ServletException, IOException {
        String url = "";
        String name = "";

        ServletContext sc = getServletContext();

        String file_name = request.getParameter("file_name");// 你要访问的jsp文件名,如index,不包括扩展名

        // 则你访问这个servlet时加参数.如

        url = "/" + file_name + ".jsf";// 你要生成的页面的文件名。我的扩展名为jsf .

        name = ConfConstants.CONTEXT_PATH+"//"+ file_name + ".htm";// 这是生成的html文件名,如index.htm.文件名字与源文件名相同。扩展名为htm

      //ConfConstants.CONTEXT_PATH为你的应用的上下文路径。

        RequestDispatcher rd = sc.getRequestDispatcher(url);

        final ByteArrayOutputStream ōs = new ByteArrayOutputStream();

        final ServletOutputStream stream = new ServletOutputStream() {
         public void write(byte[] data, int offset, int length) {
          os.write(data, offset, length);
         }

         public void write(int b) throws IOException {
          os.write(b);
         }
        };

        final PrintWriter pw = new PrintWriter(new OutputStreamWriter(os));

        HttpServletResponse rep = new HttpServletResponseWrapper(response) {
         public ServletOutputStream getOutputStream() {
          return stream;
         }

         public PrintWriter getWriter() {
          return pw;
         }
        };
        rd.include(request, rep);
        pw.flush();
        FileOutputStream fos = new FileOutputStream(name); // 把jsp输出的内容写到xxx.htm
        os.writeTo(fos);
        fos.close();
        PrintWriter ōut = response.getWriter();
        out
          .print("<p align=center><font size=3 color=red>页面已经成功生成!single<br>http://www.agilejava.org/space/? 233</font></p>");
       }
      }

      第二步、配置你的web.xml

       <servlet>
        <servlet-name>toHtml</servlet-name>
        <servlet-class>mj.util.html.ToHtml</servlet-class>//你的servlet的类。
       </servlet>
       <servlet-mapping>
        <servlet-name>toHtml</servlet-name>
        <url-pattern>/toHtml</url-pattern>
       </servlet-mapping>

      第三步、运行servlet。    

      OK,这就在你的test项目的根目录下,生成了一个index.htm的静态文件。 

    

      局限性:本文只能生成一个文件!访问一次,生成一个文件。并且生成的文件名也与原来的文件名相同。

      比较适合主页生成静态页面。

          本文假设一个新闻发布系统。希望后台发布的,前台显示的是静态的文档。这就涉及,主页要是静态的,同时二级列表也是静态的,新闻内容也是静态的。也就是说,在发布一篇新闻的时候,可能涉及到三个地方生成静态文档。并且,要生成一个网页,必须访问一个servlet。在大量生成静态网页的时候,

            以下方法,可以解决这些问题。

          一、加入一下servelet

          /**
           * @file_name 文件名及文件之后的参数.最好为a.jsf?fileId=aaaa
           * @path 文件所在的路径.相对于根目录而言的.
           * @realName文件要保存的名字
           * @realPath文件要保存的真实路径。默认与文件所在的目录相同。
           */
          public class ToHtmlPath extends HttpServlet {

           public void service(HttpServletRequest request, HttpServletResponse response)
             throws ServletException, IOException {
            String url = "";
            String name = "";

            ServletContext sc = getServletContext();

            String file_name = request.getParameter("file_name");// 你要访问的jsp文件,如news.jsf。
            // file_name如:fileDetail.jsf?fileId=56.要是有参数,只有一个参数。并且以参数名作为文件名。
            String realName = request.getParameter("realName");// 要保存的文件名。如aaa;注意可以没有这个参数。

            String path = request.getParameter("path");// 你要访问的jsp文件路径。如news。注意可以没有这个参数。

            String realPath = request.getParameter("realPath");// 你要保存的文件路径,如htmlNews.注意可以没有这个参数。
            // 下面确定要保存的文件名字。
            if (realName == null || realName == "") {
             int a = 0;
             a = file_name.indexOf("=") + 1;
             realName = file_name.substring(a);
             if (realName.indexOf(".")>0) {
              realName = file_name.substring(0, file_name.indexOf("."));
             }
            }
            // 下面构造要访问的页面。
            if (path == null || path == "") {
             url = "/" + file_name;// 这是你要生成HTML的jsp文件,如
            } else {
             url = "/" + path + "/" + file_name;// 这是你要生成HTML的jsp文件,如
            }
            // 下面构造要保存的文件名,及路径。
            // 1、如果有realPath,则保存在realPath下。
            // 2、如果有path则保存在path下。
            // 3、否则,保存在根目录下。
            if (realPath == null || realPath == "") {
             if (path == null || path == "") {
              name = ConfConstants.CONTEXT_PATH + "//" + realName + ".htm";// 这是生成的html文件名,如index.htm.说明: ConfConstants.CONTEXT_PATH为你的上下文路径。
             } else {
              name = ConfConstants.CONTEXT_PATH + "//" + path + "//"
                + realName + ".htm";// 这是生成的html文件名,如index.htm.
             }
            } else {
             name = ConfConstants.CONTEXT_PATH + "//" + realPath + "//"
               + realName + ".htm";// 这是生成的html文件名,如index.htm.
            }

            // 访问请求的页面,并生成指定的文件。
            RequestDispatcher rd = sc.getRequestDispatcher(url);

            final ByteArrayOutputStream ōs = new ByteArrayOutputStream();

            final ServletOutputStream stream = new ServletOutputStream() {
             public void write(byte[] data, int offset, int length) {
              os.write(data, offset, length);
             }

             public void write(int b) throws IOException {
              os.write(b);
             }
            };

            final PrintWriter pw = new PrintWriter(new OutputStreamWriter(os));

            HttpServletResponse rep = new HttpServletResponseWrapper(response) {
             public ServletOutputStream getOutputStream() {
              return stream;
             }

             public PrintWriter getWriter() {
              return pw;
             }
            };
            rd.include(request, rep);
            pw.flush();
            FileOutputStream fos = new FileOutputStream(name); // 把jsp输出的内容写到xxx.htm
            os.writeTo(fos);
            fos.close();
            PrintWriter ōut = response.getWriter();
            out.print("<p align=center><font size=3 color=red>success!</font></p>");
           }
          }

        

          二、在web.xml里面配置你的servlet

           <servlet>
            <servlet-name>toHtmlPath</servlet-name>
            <servlet-class>mj.util.html.ToHtmlPath</servlet-class>
           </servlet>
           <servlet-mapping>
            <servlet-name>toHtmlPath</servlet-name>
            <url-pattern>/toHtmlPath</url-pattern>
           </servlet-mapping>

          三、写一个通用的方法, 供调用。

          public class CallHtml {

           public static void callOnePage(String fileName, String path,
             String realName, String realPath) {
            try {
             String str =DataSourc.getPass()+ fileName + "&&path=" + path + "&&realName=" + realName
               + "&&realPath=" + realPath;
             int httpResult;
             URL url = new URL(str);
             URLConnection connection = url.openConnection();
             connection.connect();
             HttpURLConnection httpURLConnection = (HttpURLConnection) connection;
             httpResult = httpURLConnection.getResponseCode();
             if (httpResult != HttpURLConnection.HTTP_OK) {
              System.out.println("没有连接成功");
             } else {
              System.out.println("连接成功了 ");
             }
            } catch (Exception e) {
             // TODO: handle exception
            }
           }

          //这个方法适当重载,就可以省去一些参数传递。

          }

          四、在你的新闻发布save时,调用方法。

          1、CallHtml.callOnePage("info.jsf?file_id=aaa",news,"", "");//将在news目录下生成一个aaa.htm的静态文件

          2、CallHtml.callOnePage("newsList.jsf",news,"", "");//将在news目录下生成一个newsList.htm的静态文件,显示最新的新闻。

          3、CallHtml.callOnePage("index.jsf","","", "");//生成主页。

          好了,这就保持了,主页、列表、新闻内容都是最新的静态页面了。

----------------------------------------------------------------------------------------------------

一个实现将动态页面转为静态的方案

1.前言
为了能深入浅出的理解这个框架的由来,我们首先来了解一下JSP解析器将我们写的JSP代码转换成的JAVA文件的内容。
下面是一个JSP文件test.jsp
经过TOMCAT转换出的JAVA文件test$jsp.java内容如下:
package org.apache.jsp;
import javax.servlet.*;
import javax.servlet.http.*;
import javax.servlet.jsp.*;
import org.apache.jasper.runtime.*;

public class test$jsp extends HttpJspBase {

    static {
    }
    public testOutRedir$jsp( ) {
    }

    private static boolean _jspx_inited = false;

    public final void _jspx_init() throws org.apache.jasper.runtime.JspException {
    }

    public void _jspService(HttpServletRequest request, HttpServletResponse response)
        throws java.io.IOException, ServletException {

        JspFactory _jspxFactory = null;
        PageContext pageContext = null;
        HttpSession session = null;
        ServletContext application = null;
        ServletConfig config = null;
        JspWriter out = null;
        Object page = this;
        String _value = null;
        try {

            if (_jspx_inited == false) {
                synchronized (this) {
                    if (_jspx_inited == false) {
                        _jspx_init();
                        _jspx_inited = true;
                    }
                }
            }
            _jspxFactory = JspFactory.getDefaultFactory();
            response.setContentType(text/html;charset=GB2312);
            pageContext = _jspxFactory.getPageContext(this, request, response,
                            , true, 10241024, true);

            application = pageContext.getServletContext();
            config = pageContext.getServletConfig();
            session = pageContext.getSession();
            out = pageContext.getOut();
                //为了节省篇幅,我删除了解释器添加的注释
                out.write(/r/n);
//上一句是由于后面的换行产生的
                out.write();
                out.write(/r/n/r/n/r/n/r/n);
                    } catch (Throwable t) {
            if (out != null && out.getBufferSize() != 0)
                out.clearBuffer();
            if (pageContext != null) pageContext.handlePageException(t);
        } finally {
            if (_jspxFactory != null) _jspxFactory.releasePageContext(pageContext);
        }
    }
}
从上面的代码中可以清晰的看到JSP内建的几个对象(out、request、response、session、pageContext、application、config、page)是怎么产生的,懂servlet的朋友一看就能明白。
下面重点理解一下out对象,它被声明为JspWriter类型,JspWriter是一个抽象类,在包javax.servlet.jsp中可以找到它的定义。
abstract public class javax.servlet.jsp.JspWriter extends java.io.Writer{
       final public static int NO_BUFFER = 0;
       final public static int DEFAULT_BUFFER = -1;
       final public static int UNBOUNDED_BUFFER = -2;
       protected int bufferSize;
       protected Boolean autoFlush;
       protected javax.servlet.jsp.JspWriter(int arg1, boolean arg2);
     
    abstract public void newLine() throws IOException ;
    abstract public void print(boolean arg0) throws IOException ;
    abstract public void print(char arg0) throws IOException ;
    abstract public void print(int arg0) throws IOException ;
    abstract public void print(long arg0) throws IOException ;
    abstract public void print(float arg0) throws IOException ;
    abstract public void print(double arg0) throws IOException ;
    abstract public void print(char[] arg0) throws IOException ;
    abstract public void print(String arg0) throws IOException ;
    abstract public void print(Object arg0) throws IOException ;
    abstract public void println() throws IOException ;
    abstract public void println(boolean arg0) throws IOException ;
    abstract public void println(char arg0) throws IOException ;
    abstract public void println(int arg0) throws IOException ;
    abstract public void println(long arg0) throws IOException ;
    abstract public void println(float arg0) throws IOException ;
    abstract public void println(double arg0) throws IOException ;
    abstract public void println(char[] arg0) throws IOException ;
    abstract public void println(String arg0) throws IOException ;
    abtract public void println(Object arg0) throws IOException ;
    abstract public void clear() throws IOException ;
    abstract public void clearBuffer() throws IOException ;
    abstract public void flush() throws IOException ;
    abstract public void close() throws IOException ;
    public int getBufferSize() ;
    abstract public int getRemaining() ;
    public boolean isAutoFlush() ;
}
我相信当我写到这里你可能已经知道我想怎么做了。是的,来个偷天换日,继承JspWriter类,然后实现其定义的虚函数,然后把out变量替换成你自己实现的类的实例就ok了。
2.实现替换
假设
3.更新问题
下面就讨论一下如何更新生成静态文件,其实从上面实现中你可以看到,很简单的就是将生成的静态文件删除即可,至于什么时候删除,要看你的需求了。我能想到的几种情况如下
当用来生成页面的数据更新时
如果不需要很提供时时的数据可以定时更新
永远不更新
----------------------------------------------------------------------------------------------------

JSP生成静态HTML页面范例

先建立一个模本页面:template.htm

<Html>
<head>
<title>###title###</title>
<meta http-equiv="Content-Type" content="text/html; charset=gb2312">
<LINK href="../Css.css" rel=stylesheet type=text/css>
</head>
<body>
<table width="500" border="0" align="center" cellpadding="0" cellspacing="2">
<tr>
<td align="center">###title###</td>
</tr>
<tr>
<td align="center">作者:###author###&nbsp;&nbsp;</td>
</tr>
<tr>
<td>###content###
</td>
</tr>
</table>
</body>
</html>

=========================================
再写一个jsp页面: buildhtml.jsp

<%@ page contentType="text/html; charset=gb2312" import="Java.util.*,java.io.*"%>
<%
try{
String title="小样,破碎的心,http://www.fdpsj.com/Product/";
String content="小样,还搞不定你?";
String editer="webjxcom";
String filePath = "";
filePath = request.getRealPath("/")+"?exit.htm";
out.print(filePath);
String templateContent="";
FileInputStream fileinputstream = new FileInputStream(filePath);//读取模块文件
int lenght = fileinputstream.available();
byte bytes[] = new byte[lenght];
fileinputstream.read(bytes);
fileinputstream.close();
templateContent = new String(bytes);
out.print(templateContent);
templateContent=templateContent.replaceAll("###title###",title);
templateContent=templateContent.replaceAll("###content###",content);
templateContent=templateContent.replaceAll("###author###",editer);//替换掉模块中相应的地方
out.print(templateContent);
// 根据时间得文件名
Calendar calendar = Calendar.getInstance();
String fileame = String.valueOf(calendar.getTimeInMillis()) +".html";
fileame = request.getRealPath("/")+fileame;//生成的html文件保存路径
FileOutputStream fileoutputstream = new FileOutputStream(fileame);//建立文件输出流
out.print("文件输出路径:<br>");
out.print(fileame);
byte tag_bytes[] = templateContent.getBytes();
fileoutputstream.write(tag_bytes);
fileoutputstream.close();
}
catch(Exception e){
out.print(e.toString());
}
%>
分享到:
评论

相关推荐

    JSP动态网站开发基础教程与实验指导(从基础到应用)光盘

    练习3-1 在JSP页面中静态包含文件 312 练习3-2 统计访问页面数量 312 练习3-3 求圆的面积和周长 313 练习3-4 动态加载页面并传递参数 314 第4单元 315 练习4-1 简单地验证用户登录 315 练习4-2 猜数字 316 练习4-3 ...

    jsp452网络故障报修系统 java程序源码论文.zip

    本系统是在Windows平台下,用Jsp、网络编程等技术,结合MYSQL数据库管理系统开发出的B/S结构的网络故障报修系统。动态网页与静态网页相结合的方法制作此系统,动态网页一般以数据库技术为基础,可以大大降低系统维护...

    Jspxcms网站内容管理系统 源码包 v9.0.0.zip

    Jspxcms是基于Java、JSP技术开发的国产开源CMS,是制作、维护网站的利器。国内CMS主要以PHP技术为主,基于Java、Jsp的CMS数量不多,功能和易用性也有一定差距。Jspxcms致力于做最好的Java CMS,依托Java的开源精神和...

    Web HML5实战合集

    3. JSP生成静态HTML页面的几种方法 4. 网页优化meta标签使用方法及规则 5. 使用-HTML5-canvas-进行-Web-绘图 6. 基于-HTML5-的-Dojo-Widget-开发 7. 浅析HTML5在移动应用开发中的使用 8. 深度分析HTML5在移动开发...

    JAVA程序开发大全---上半部分

    20.6.3 分页显示系统中销售的所有宠物信息的页面newPet.jsp 366 20.6.4 显示销售的每个宠物详细信息的页面petInfo.jsp 368 20.7 显示宠物商品模块的实现 370 20.7.1 显示商品页面 370 20.7.2 定义对宠物商品信息进行...

    基于J2EE框架的个人博客系统项目毕业设计论文(源码和论文)

    1、将业务层与表示层分离:使用JSP技术,网络开发人员可充分使用HTML来设计页面显示部分(如字体颜色等),并使用JSP指令或者JAVA程序片段来生成网页上的动态内容; 2、能够跨平台:JSP支持绝大部分平台,包括现在...

    CMS4J 专业的jjava/jsp版网站内容管理系统

    最新消息,CMS4J 现已推出 基于java / jsp技术开发的网站管理系统 CMS4J 2008 免费版 ,并且又推出了一套同样基于java / jsp技术开发的博客系统! CMS4J 2008 革新了原有的系统架构,开发了更为专业、便捷的后台...

    基于J2EE框架的个人博客系统项目毕业设计论...

    1、将业务层与表示层分离:使用JSP技术,网络开发人员可充分使用HTML来设计页面显示部分(如字体颜色等),并使用JSP指令或者JAVA程序片段来生成网页上的动态内容; 2、能够跨平台:JSP支持绝大部分平台,包括现在...

    J2EE中文版指南 CHM格式 带全文检索

    生成静态内容 181 生成动态内容 181 在JSP中使用对象 181 隐式对象 181 特定应用程序对象 181 共享对象 182 JSP scripting 元素 182 声明 182 脚本(scriptlets) 183 表达式 184 在JSP页面中包含内容 185 转换控制...

    Lerx 网站内容管理系统 v5.5.zip

    支持信息分析、相似性检索技术,支持关键字检索、全文检索、组合检索等,并使关键字在搜索结果中进行高亮显示。文章发布后即生成相应的文件索件,避免过多查询数据库,引起服务器堵塞。 Lerx 网站内容管理系统截图 ...

    基于J2EE的博客系统的设计与实现毕业设计.doc

    基于J2EE的博客系统的设计与实现毕业设计 目 录 前 言 1 第1章 技术背景 3 1.1 方案分析 3 1.2 开发工具 3 1.2.1 JSP简介 3 1.2.2 MySQL简介 4 1.2.3 Tomcat简介 4 1.2.4 MyEclipse简介 4 1.2.5 MVC简介 5 1.2.6 ...

    超级有影响力霸气的Java面试题大全文档

     动态INCLUDE用jsp:include动作实现 &lt;jsp:include page="included.jsp" flush="true" /&gt;它总是会检查所含文件中的变化,适合用于包含动态页面,并且可以带参数。 静态INCLUDE用include伪码实现,定不会检查所含文件...

    java 面试题 总结

    动态INCLUDE用jsp:include动作实现 &lt;jsp:include page="included.jsp" flush="true" /&gt;它总是会检查所含文件中的变化,适合用于包含动态页面,并且可以带参数。 静态INCLUDE用include伪码实现,定不会检查所含文件的...

    Formula One e.SpreadSheet Engine v10.0--功能众多的报表

    摘要 Formula One e.Spreadsheet Engine 具有广泛的API和丰富的GUI设计器,可用以访问多种数据源,过滤和格式化数据,并能动态生成并传送真实的Excel文件(不仅仅是格式化静态数据),并带有各种公式,图表,略图,...

    Java数据编程指南

    使用JSP进行数据访问 访问数据 范例应用程序 深入性主题 小结 第17章 分析和生成XML 文档和数据 XML概述 Java XML技术 生成XML 读取XML 小结 第18章 WAP客户机 WAP概览 ...

    音乐网站的设计与实现毕业设计ASP开题报告.doc.doc

    1. 选题的背景 随着Internet的快速...使用Dreamweaver制作静态站点的流程:新建站点 站点文件命名 定义页面属性 插入表格 定义页面大小 转换到布局视图 添加内容 插入 导航条 转换到标准视图工作 添加链接 使用代码片

    系统分析师考试复习资料

    .........................................................................7 XML 与JSP 技术联合的优越性:.............................................................................7 XML 的特点:...

    详细设计说明书

    最终展现,通过JAVA、JSP、HTML、GIS,视频监控等编程技术完成代码开发,并部署到WEB应用服务器(WebSphere等),主题采用BRIO工具结合WEB页面,地图技术,视频技术进行多维展现。 3 模块设计 按照需求进行模块分析...

    02408仿天涯论坛模板的免费论坛系统(php在线问答系统源码)v2.0.zip

    虽然这是一个用PHP MySQL语言编写的论坛系统,但是管理员可以在后台一键切换成.shtml、.html、.htm、.asp、.aspx、.cgi、.php、.jsp、.cgi、/ 等任何一种网址后缀,如果利用伪静态规则,去掉URL中的index.php/,它就...

    软件工程-理论与实践(许家珆)习题答案

    还有知识工程方法,例如,场记分析法、卡片分类法、分类表格技术和基于模型的知识获取等 。 (2) 模拟和分析需求 需求分析和模拟又包含三个层次的工作。首先是需求建模。需求模型的表现形式有自然语言、半形式化(如...

Global site tag (gtag.js) - Google Analytics