缺省Servlet的緩存問題
l 場景:
在實際項目中,有些HTML文件是在程序運行時調用一個模版文檔來動態生成的,例如,一些站點的統計報表就是在用戶訪問某個Servlet時,由這個Servlet臨時調用報表生成模塊(例如,ireport)生成一個HTML文件,然後再將請求轉發這個HTML文件。
l 問題:
如果A部門的一個員工查看了A部門的統計信息後的一個較短時間範圍內,B部門的員工來查看B部門的統計信息,結果後者看到的是A部門的統計信息。
l 缺省Servlet緩存問題的模擬程序(1)
public class ReportServlet extends HttpServlet
{
private int count = 0;
public void service(HttpServletRequest request,
HttpServletResponse response) throws ServletException, IOException
{
response.setContentType("text/html;charset=UTF-8");
//禁止瀏覽器緩存
response.setDateHeader("Expires",0);
response.setHeader("Cache-Control","no-cache");
response.setHeader("Pragma","no-cache");
String department = request.getParameter("dept");
synchronized(this)
{
System.out.println(++count + ":" + department);
String path = getServletContext().getRealPath("/WEB-INF/report.html");
ReportTool rt = new ReportTool();
rt.setCount(count);
rt.setDepartment(department);
rt.createReportHTML(path);
RequestDispatcher rd = getServletContext().getRequestDispatcher(
"/WEB-INF/report.html");
rd.forward(request,response);
}
}
}
l 缺省Servlet緩存問題的模擬程序(2)
public class ReportTool
{
private int count = 0;
private String department = "";
public void setCount(int count)
{
this.count = count;
}
public void setDepartment(String department)
{
this.department = department;
}
public void createReportHTML(String path) throws IOException
{
FileOutputStream fos = new FileOutputStream(path);
OutputStreamWriter ops = new OutputStreamWriter(fos,"UTF-8");
ops.write(String.valueOf(count) + ":" + department + "的統計信息");
ops.close();
}
}
l 缺省Servlet緩存問題à實踐
l 文件清單:ReportTest.html
<a href="servlet/ReportServlet?dept=DEPT_A">查看部門A的統計信息</a>
<a href="servlet/ReportServlet?dept=DEPT_B">查看部門B的統計信息</a>
l 缺省Servlet緩存問題à解決方案
, 1,爲每一種統計方案都生成一個名稱不同的HTML報表文件,例如,不同部門使用不同名稱的報表文件。如果統計方案比較多,生成的HTML報表文件的個數也就會很多,所以,這個方案比較適合只有少數幾種固定的統計方案的情況,特別不適合要根據各種組合條件來生成報表的情況。
,2,修改Tomcat的缺省Servlet程序,讓它不要進行緩存,這種方案可能會嚴重影響系統的性能,一般不要採用。
,3,在ReportServlet程序中生成HTML報表文件後,按字節流的形式讀取該文件中的內容,然後以字節流的形式直接輸出到客戶端。這種方案可以生成實時的統計報表,也適合根據各種組合條件來生成報表的情況,所以,推薦採用這種方案。