透過 Servlet 捕獲 JSP 執行後的輸出流,寫入檔案系統,即可實現動態頁面靜態化。以下為完整實作類別 ToHtml:
package examples;
import java.io.*;
import javax.servlet.*;
import javax.servlet.http.*;
public class ToHtml extends HttpServlet {
private static final String CONTENT_TYPE = "text/html; charset=GBK";
public void init() throws ServletException { }
public void doGet(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
response.setContentType(CONTENT_TYPE);
service(request, response);
}
public void doPost(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
doGet(request, response);
}
public void destroy() { }
public void service(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
ServletContext sc = getServletContext();
String url = "/index.jsp";
String name = "index.htm"; // 產生的 HTML 檔名
String pName = "e:/Tomcat 5.5/webapps/jspTohtml/index.htm"; // 完整儲存路徑
RequestDispatcher rd = sc.getRequestDispatcher(url);
final ByteArrayOutputStream os = 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); // 執行 JSP 並捕獲輸出
pw.flush();
FileOutputStream fos = new FileOutputStream(pName);
os.writeTo(fos); // 寫入檔案
fos.close();
response.sendRedirect(name); // 導向靜態頁面
}
}
<servlet>
<servlet-name>Tohtml</servlet-name>
<servlet-class>examples.ToHtml</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>Tohtml</servlet-name>
<url-pattern>/Tohtml</url-pattern>
</servlet-mapping>
<%@ page contentType="text/html; charset=gb2312" %>
<html><head><title>Cache Filter Test</title>
<meta http-equiv="Content-Type" content="text/html; charset=gb2312"></head>
<body>簡單測試:s=<%
int s=0; // 模擬耗時運算
for (int i=0;i<1000;i++) for (int j=0;j<1000;j++) s=s+j;
out.print(s);
%></body></html>
RequestDispatcher.include() 執行目標 JSP。HttpServletResponseWrapper 包裝回應,將輸出導向 ByteArrayOutputStream 暫存。.htm 檔案。此技術常用於靜態化高流量頁面、減輕伺服器負載。