zoukankan      html  css  js  c++  java
  • JSP页面静态化

     Ps:好久没写博客了,不是我太懒,是因为苦逼的我出差去上海了,天天加班 刚回成都....

    今天说说jsp页面静态化,知道静态化的朋友都不陌生,说白了就是访问后缀是html 而不是jsp。

    没听说过静态化的朋友会问为啥要这么做,jsp访问好好的 为啥多此一举

    好处:

        1. 效率方面,访问html页面时,服务器找到页面后直接返回,不会再进行后台处理,速度快很多很多,同时也是解决高并发,降低服务器资源占用最有效的方式。

    各大门户类网站大家都可以看看页面的后缀,几乎都是.html结尾的.

        2. seo方面,搜索引擎对html的收录较好,爬虫对html解析几乎是100%,而对动态页面则少之又少,静态化后页面收录会高N多倍。这也是有些程序在没有真正实现

    静态化的时候,提供了伪静态的访问方式,伪静态对服务器性能和访问速度没有提升,仅仅是在seo方向有一定作用。

    具体说说怎么处理, 这里以java web为例讲解,因为我对php,asp研究没有jsp深。

    1. 首先,我们需要写页面的模板,就是jsp页面,我们生成后的html是基于该模板的,说白了就是用查询好的数据去填充对应的地方,如下我写的一个简单模板jsp
    • <%@ page language="java" contentType="text/html; charset=UTF-8"
          pageEncoding="UTF-8"%>
      <%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c"%>
      <!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>文章标题——${id}</title>
      </head>
      <body>现在时间是${time},你访问的文章id为${id}
      </body>
      </html>

      这个jsp页面我命名为articleTemplate.jsp ,只简单的写了时间和id,你可以根据页面需要展示的内容,写出美观又好看的页面,然后填充数据,这里需要导入jstl包

         2. 编写对应的生成html的servlet或者controller,因为每个功能对应的模板和需要展示的数据都不一样,所以一般有多少个jsp页面就需要写多少个servlet

            首先创建一个 JspStatic,用于接收用户请求,如果html页面还未生成过,则生成并返回,如果已经生成过了,则直接返回html页面

            

    package com.xiaochangwei.html;
    
    import java.io.File;
    import java.io.IOException;
    import javax.servlet.ServletException;
    import javax.servlet.annotation.WebServlet;
    import javax.servlet.http.HttpServlet;
    import javax.servlet.http.HttpServletRequest;
    import javax.servlet.http.HttpServletResponse;
    
    /**
     * 
     * 接收用户请求,生成或者直接返回html
     * 
     * @author xiaochangwei
     *
     */
    @WebServlet("/JspStatic")
    public class JspStatic extends HttpServlet {
        private static final long serialVersionUID = 1L;
    
        public JspStatic() {
            super();
        }
    
        public void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
            if (request.getParameter("id") != null) {
                String fileName = "article_" + request.getParameter("id") + ".html";
                String filePath = getServletContext().getRealPath("/") + fileName;
                File chapterFile = new File(filePath);
                if (chapterFile.exists()) {
                    System.out.println("html页面存在,直接跳转");
                    response.sendRedirect(fileName);
                    return;
                }
                
                
                System.out.println("新生成html页面");
                //TODO 这里可调用service查询页面上需要的数据,然后封装到request里面
                request.setAttribute("time", new java.util.Date());
                request.setAttribute("id", request.getParameter("id"));
                new CreateStaticHTMLPage().create(request, response, getServletContext(), fileName, filePath,
                        "/articleTemplate.jsp");
            }
        }
    
        protected void doPost(HttpServletRequest request, HttpServletResponse response)
                throws ServletException, IOException {
            doGet(request, response);
        }
    
    }

     这里代码很简单了,为了测试效果,我在控制台打了对应的信息,以便区分。

     首先接收一个id参数,然后根据规则查找这个id对应的html页面是否存在,如果存在,就直接返回这个html页面

      如果没有,则生成html,在生成之前需要调用其他service等查询到页面需要展示的数据,并放到request里面  请注意TODO描述

      最后调用create方式生成页面,参数包括了封装了数据的request,需要生成的文件名和路径,以及需要使用的模板等

      具体生成html的代码如下:

      

    package com.xiaochangwei.html;
    
    import java.io.ByteArrayOutputStream;
    import java.io.FileOutputStream;
    import java.io.IOException;
    import java.io.OutputStreamWriter;
    import java.io.PrintWriter;
    import javax.servlet.RequestDispatcher;
    import javax.servlet.ServletContext;
    import javax.servlet.ServletException;
    import javax.servlet.ServletOutputStream;
    import javax.servlet.http.HttpServletRequest;
    import javax.servlet.http.HttpServletResponse;
    import javax.servlet.http.HttpServletResponseWrapper;
    
    /**
     * 创建HTML静态页面 
     * 
     * @author xiaochangwei
     * 
     */
    public class CreateStaticHTMLPage {
        /**
         * 生成静态HTML页面的方法
         * 
         * @param request
         *            请求对象
         * @param response
         *            响应对象
         * @param servletContext
         *            Servlet上下文
         * @param fileName
         *            文件名称
         * @param fileFullPath
         *            文件完整路径
         * @param jspPath
         *            需要生成静态文件的JSP路径(相对即可)
         * @throws IOException
         * @throws ServletException
         */
        public void create(HttpServletRequest request, HttpServletResponse response,
                ServletContext servletContext, String fileName, String fileFullPath, String jspPath)
                        throws ServletException, IOException {
            response.setContentType("text/html;charset=gb2312");// 设置HTML结果流编码(即HTML文件编码)
            RequestDispatcher rd = servletContext.getRequestDispatcher(jspPath);// 得到JSP资源
            final ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();// 用于从ServletOutputStream中接收资源
            final ServletOutputStream servletOuputStream = new ServletOutputStream() {// 用于从HttpServletResponse中接收资源
                public void write(byte[] b, int off, int len) {
                    byteArrayOutputStream.write(b, off, len);
                }
    
                public void write(int b) {
                    byteArrayOutputStream.write(b);
                }
            };
            final PrintWriter printWriter = new PrintWriter(new OutputStreamWriter(byteArrayOutputStream));// 把转换字节流转换成字符流
            HttpServletResponse httpServletResponse = new HttpServletResponseWrapper(response) {// 用于从response获取结果流资源(重写了两个方法)
                public ServletOutputStream getOutputStream() {
                    return servletOuputStream;
                }
    
                public PrintWriter getWriter() {
                    return printWriter;
                }
            };
            rd.include(request, httpServletResponse);// 发送结果流
            printWriter.flush();// 刷新缓冲区,把缓冲区的数据输出
            FileOutputStream fileOutputStream = new FileOutputStream(fileFullPath);
            byteArrayOutputStream.writeTo(fileOutputStream);// 把byteArrayOuputStream中的资源全部写入到fileOuputStream中
            fileOutputStream.close();// 关闭输出流,并释放相关资源
            response.sendRedirect(fileName);// 发送指定文件流到客户端
        }
    }

    下面我们测试下程序的执行情况:

    1.最开始控制台啥都没有

    2. 回车后,控制台打出了 新生成html页面 如下

    3. 在浏览器中输入 http://localhost:9990/Html/JspStatic?id=100 不是直接输入html对应路径,控制台打出 直接跳转

    证明没有再重新去生成,并且明显感觉速度要快很多, 如果生成页面时需要查找的数据更多,则效果更明显  并且上面的时间戳都一样,表示是同一个页面

    并且可以看到服务器对应路径下有一个生成了的html页面,且内容完全一样

    好了具体的内容就讲到这里了,这就是页面静态化。

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

    实际项目中使用静态化时需要注意的地方:

    1. 某条信息有修改时,为了及时反映到html页面,需要重新生成html页面,操作方式即删除现有html重新生成一个

    2.页面上的连接就直接写具体的html,不用再去后台请求一次,但是要注意页面的及时更新,一般用定时器执行

       比如CMS系统,一般管理端提供了多久更新一次,频率太高会加重服务器负担,但数据反映及时;频率太低,新信息又不能及时展示,所以结合实际折中考虑吧

    3.如CMS分类信息列表及门户首页数据,除了具体链接是html外,列表的生成方式也有讲究

        a. 直接通过读数据库列表,然后计算出对应的html页面生成链接,  每次生成列表对服务器也是一种消耗

        b. 直接读取生成的静态html列表文件来生成列表, 这个挺好的,不用去查询数据库, 文件的操作会更好 【推荐】

    虽说静态化有很多好处,但是也要结合实际情况,一天没有几个人访问的网站我觉得就没必要了, 主要适用于高并发,访问量很大的网站。

    欢迎大家给我意见及建议,相互探讨 共同进步

  • 相关阅读:
    Beta阶段DAY1
    Beta阶段DAY2
    Beta阶段冲刺前准备
    Beta阶段Scrum 冲刺博客合集
    alpha阶段项目复审
    网络15软工个人作业5——软件工程总结
    软工网络15个人作业4——alpha阶段个人总结
    软件工程网络15个人作业3 (201521123051 谢庆圆)
    软件工程网络15专业结对编程
    软工网络15个人阅读作业2 (201521123051 谢庆圆)
  • 原文地址:https://www.cnblogs.com/xiaochangwei/p/5025790.html
Copyright © 2011-2022 走看看