本文匯總 JSP 開發中高頻復用的 4 個核心工具類/片段:用戶登錄驗證 (JDBC)、Application 全局變量線程安全操作、防瀏覽器緩存響應頭、HTML 特殊字符轉義 (防 XSS)。代碼可直接落地項目。
public String validateUser(String inputUserid, String inputPwd) throws SQLException {
String returnString = null;
// 數據庫連接信息 (生產環境請用連接池 + JNDI)
String dbUser = "userid";
String dbPwd = "password";
// 1. 加載驅動 (JDBC 4.0+ 可省略)
Class.forName("sun.jdbc.odbc.JdbcOdbcDriver");
// 2. 獲取連接
Connection con = DriverManager.getConnection("jdbc:odbc:myDriver", dbUser, dbPwd);
// 3. 預編譯防注入 (關鍵!)
String sql = "SELECT USERID FROM USERTABLE WHERE USERID = ? AND PASSWORD = ?";
PreparedStatement ps = con.prepareStatement(sql);
ps.setString(1, inputUserid);
ps.setString(2, inputPwd);
// 4. 執行查詢
ResultSet rs = ps.executeQuery();
if (rs.next()) {
returnString = rs.getString("USERID");
}
// 5. 關閉資源 (JDK 7+ 建議 try-with-resources)
rs.close();
ps.close();
con.close();
return returnString; // null 表示驗證失敗
}
安全升級點:
BCrypt/SCrypt/Argon2 哈希值。DataSource,不要在方法裡創建連接。<%-- JSP 頁面中直接使用 application 隱含對象 --%>
<%
// 寫入:同步塊 + 雙重檢查
Integer count = null;
synchronized (application) {
count = (Integer) application.getAttribute("visitCount");
if (count == null) count = 0;
count++;
application.setAttribute("visitCount", count);
}
%>
<h1>歡迎訪問,您是第 <%= count %> 位訪客</h1>
<%-- Servlet 中獲取 ServletContext --%>
<%
ServletContext application = getServletContext();
// 同樣用 synchronized (application) 保護讀寫
%>
要點:
application = ServletContext,全局單例,生命週期 = Web 應用。ConcurrentHashMap 存儲復雜對象)。com.myapp.visitCount。<%
response.setHeader("Cache-Control", "no-store, no-cache, must-revalidate, max-age=0");
response.setHeader("Pragma", "no-cache"); // HTTP 1.0 兼容
response.setDateHeader("Expires", 0); // 過期時間設為過去
%>
<head>
<meta http-equiv="Cache-Control" content="no-store, no-cache, must-revalidate" />
<meta http-equiv="Pragma" content="no-cache" />
<meta http-equiv="Expires" content="0" />
</head>
差異:Java 代碼設置 **HTTP 響應頭**,瀏覽器/代理/網關均生效;Meta 標籤僅瀏覽器解析 HTML 時生效,**代理服務器不識別**。動態頁**必須用 Java 方式**。
public class HtmlUtils {
/**
* 將字符串中的特殊字符轉為 HTML 實體,防止 XSS 注入。
* 處理字符:& < > " ' / (可按需擴展)
*/
public static String htmlEncode(String text) {
if (text == null) return "";
StringBuilder result = new StringBuilder(text.length() + 16);
for (int i = 0; i < text.length(); i++) {
char c = text.charAt(i);
switch (c) {
case '&': result.append("&"); break;
case '<': result.append("<"); break;
case '>': result.append(">"); break;
case '"': result.append("""); break;
case '\'': result.append("'"); break;
case '/': result.append("/"); break; // 防標簽閉合繞過
default: result.append(c);
}
}
return result.toString();
}
// 可選:解碼 (僅用於受信內容還原顯示)
public static String htmlDecode(String text) {
if (text == null) return "";
return text.replace("&", "&")
.replace("<", "<")
.replace(">", ">")
.replace(""", "\"")
.replace("'", "'")
.replace("/", "/");
}
}
<%@ page import="com.utils.HtmlUtils" %>
<%
String userInput = request.getParameter("comment");
String safe = HtmlUtils.htmlEncode(userInput);
%>
<div class="comment"><%= safe %></div>
INCR 原子操作,跨集群共享。@ControllerAdvice 統一攔截設置頭部。OWASP Java Encoder / Apache Commons Text StringEscapeUtils / 模板引擎 (Thymeleaf/FreeMarker) **自動轉義**。