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列表文件來生成列表, 這個挺好的,不用去查詢數據庫, 文件的操作會更好 【推薦】

 

 

雖說靜態化有很多好處,但是也要結合實際情況,一天沒有幾個人訪問的網站我覺得就沒必要了, 主要適用於高並發,訪問量很大的網站。

 

 

 

歡迎大家給我意見及建議,相互探討 共同進步


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM