承接上篇環境建置,本篇將計數器資料從 application 域遷移至本地檔案,解決 Tomcat 重啟計數歸零問題,並修正檔案路徑、同步鎖、字元編碼等實戰細節。
<%@ page import="java.io.*" %>
<%! private static final Object lock = new Object();
private static final File file = new File("counter.dat"); %>
<%
Integer count = 0;
synchronized (lock) {
if (!file.exists()) { file.createNewFile(); count = 0; }
else {
FileReader reader = new FileReader(file);
count = reader.read(); // 僅讀取第一個字元!
reader.close();
}
count++;
FileWriter writer = new FileWriter(file);
writer.write(count); // 僅寫入低位元組!
writer.close();
}
%>
當前訪問次數:<%= count %>
FileReader.read() 僅讀取單一字元(0-65535),計數超過 65535 即錯誤。FileWriter.write(int) 僅寫入低 16 位,同理錯誤。counter.dat 相對路徑指向 tomcat/bin/,專案遷移不便。<%@ page import="java.io.*" %>
<%!
private static final Object lock = new Object();
private static File file = null; // 延遲初始化
%>
<%
Integer count = 0;
synchronized (lock) {
// 延遲取得專案絕對路徑:WebContent/WEB-INF/classes/counter.dat
if (file == null) {
file = new File(application.getRealPath(".") + "/WEB-INF/classes/counter.dat");
}
if (!file.exists()) { file.createNewFile(); count = 0; }
else {
try (BufferedReader br = new BufferedReader(new FileReader(file))) {
String line = br.readLine();
count = (line != null && !line.isEmpty()) ? Integer.parseInt(line.trim()) : 0;
}
}
count++;
try (PrintWriter pw = new PrintWriter(new FileWriter(file))) {
pw.println(count); // 完整整數文本寫入,支援任意大小
}
}
%>
當前訪問次數:<%= count %>
WEB-INF/classes 受容器保護區,外部無法直接下載。application 在 JSP 首次編譯時才可用,故在首次請求時初始化路徑。synchronized(lock) 保護。
12345
下一篇將實作JDBC 版,使用 MySQL 持久化,支援集群與高併發。