java 做頁面靜態化

凱子王導發表於2015-01-27

JSP的靜態化  

什麼是靜態化?靜態化就是將動態的jsp轉換為靜態的html

為什麼要靜態化?提高效能加快訪問速度,靜態化的頁面html不需要訪問資料庫等操作所以要比動態的jsp快很多。
怎樣實現靜態化
實現靜態化的方法很多,本文章要說明的是通過過濾器實現jsp的靜態化。
1、我們先了解下jsp頁面的請求流程

JSP的靜態化 - 程式民工 - suntengjiao1的部落格
 
通過上圖我們可以知道servlet物件的響應是html,如果我們在servlet物件之後增加個攔截htm響應的功能將html響應儲存到伺服器,下次訪問時直接返回這個靜態頁面,也就實現了靜態化功能。
2、新的請求流程如下圖
JSP的靜態化 - 程式民工 - suntengjiao1的部落格
 
 實現上圖攔截servlet響應、判斷是否已經靜態化功能最好的方法就是攔截器filter。

3、具體實現包括,兩個類一個配置,兩個類分別是FileCaptureFilter(過濾器)和FileCaptureResponseWrapper(靜態化)。
FileCaptureFilter(過濾器):負責判斷是否已經靜態化,呼叫FileCaptureResponseWrapper(靜態化)實現靜態化,載入靜態化html生成html響應。
FileCaptureResponseWrapper(靜態化):繼承 HttpServletResponseWrapper,覆寫PrintWriter getWriter()方法獲得servlet響應內容,負責生成靜態化的html、負責將響應返回給客戶。
FileCaptureFilter 具體程式碼如下:
package cn.ce.sale.customer.filter;

import java.io.File;
import java.io.IOException;

import javax.servlet.Filter;
import javax.servlet.FilterChain;
import javax.servlet.FilterConfig;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import cn.ce.framework.exception.api.NoLoginException;
import cn.ce.framework.security.api.LoginConstant;
import cn.ce.framework.security.api.LoginUser;

public class FileCaptureFilter implements Filter{

private String protDirPath;
private FilterConfig filterConfig;
@Override
public void destroy() {
// TODO Auto-generated method stub
}

@Override
public void doFilter(ServletRequest request,ServletResponse response,FilterChain
chain) throws IOException, ServletException {
//
LoginUser loginUser = (LoginUser) ((HttpServletRequest)request).getSession().getAttribute(LoginConstant.USER);
        if (loginUser == null)
            throw new NoLoginException();
String fileName = "/forum/userId_"+loginUser.getUserId()+".html";
 File file = new File(filterConfig.getServletContext().getRealPath(fileName));
 // 判斷快取檔案是否存在或者是否重新設定了快取內容
if (!file.exists()) {// 如果快取檔案不存在
fileName=protDirPath+fileName;
FileCaptureResponseWrapper responseWrapper = new
FileCaptureResponseWrapper((HttpServletResponse)response);
chain.doFilter(request, responseWrapper);
//得到的html 頁面結果字串
//String html = responseWrapper.toString();
// 寫成html 檔案
responseWrapper.writeFile(fileName);
// back to browser
responseWrapper.writeResponse();
}else{
// 轉發至快取檔案
request.getRequestDispatcher(fileName).forward(request, response);

}
}

@Override
public void init(FilterConfig arg0) throws ServletException {
this.filterConfig=arg0;
protDirPath = arg0.getServletContext().getRealPath("/");
}
}

  FileCaptureResponseWrapper  具體程式碼如下:
package cn.ce.sale.customer.filter;

import java.io.CharArrayWriter;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.OutputStreamWriter;
import java.io.PrintWriter;

import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpServletResponseWrapper;

public class FileCaptureResponseWrapper extends HttpServletResponseWrapper {
private CharArrayWriter output;
private HttpServletResponse response;
public String toString()
{
return output.toString();
}
public FileCaptureResponseWrapper(HttpServletResponse response)
{
super(response);
this.response=response;
output =new CharArrayWriter();
}
//覆寫getWriter()
public PrintWriter getWriter()
{
return new PrintWriter(output);
}
public void writeFile(String fileName)throws IOException
{
// FileWriter fw = new FileWriter(fileName,"utf-8");
// fw.write( output.toCharArray(),"utf-8" );
// PrintWriter writer = new PrintWriter(new OutputStreamWriter(new FileOutputStream(fileName),"utf-8"));
FileOutputStream fos=new FileOutputStream(fileName);
OutputStreamWriter osw=new OutputStreamWriter(fos,"UTF-8");
osw.write(output.toCharArray());
osw.close();
}
public void writeResponse() throws IOException
{
PrintWriter out = response.getWriter();
// 重置響應輸出的內容長度
response.setContentLength(-1);
out.print( output.toCharArray() );
out.flush();
out.close();
}
}

web.xml過濾器配置如下:
<filter>
<filter-name>FileCaptureFilter</filter-name>
<filter-class>
cn.ce.sale.customer.filter.FileCaptureFilter
</filter-class>
</filter>
    <filter-mapping>
<filter-name>FileCaptureFilter</filter-name>
<url-pattern>/order/customer/addCust/*</url-pattern>
</filter-mapping>

相關文章