早期 JSP 開發常需自行撰寫字串處理函式。本文整理三個實用工具方法:中文編碼修正(ISO-8859-1 轉換)、HTML 特殊字元轉義、通用字串替換。現代開發建議使用 Apache Commons Lang (StringEscapeUtils, StringUtils) 或標準庫。
JSP/Servlet 早期預設用 ISO-8859-1 解碼請求參數,導致中文變亂碼。常見修正模式:
public String getStr(String str) {
try {
// 1. 以 ISO-8859-1 取得原始位元組(這是 Servlet 容器錯誤解碼後的結果)
byte[] bytes = str.getBytes("ISO-8859-1");
// 2. 以正確編碼重新解碼
return new String(bytes, "Big5"); // 或 GBK、UTF-8,視實際情況
} catch (UnsupportedEncodingException e) {
return "null";
}
}
在 web.xml 設定 Filter 統一處理,或 Tomcat server.xml 設定 URIEncoding="UTF-8",並在 JSP 頁面最早處呼叫 request.setCharacterEncoding("UTF-8")。
/**
* 將字串中所有 oldStr 替換為 newStr
*/
public String replace(String source, String oldStr, String newStr) {
if (source == null || oldStr == null || oldStr.isEmpty()) {
return source;
}
StringBuilder sb = new StringBuilder();
int index = 0;
int oldLen = oldStr.length();
while (true) {
int next = source.indexOf(oldStr, index);
if (next == -1) {
sb.append(source.substring(index));
break;
}
sb.append(source, index, next);
sb.append(newStr);
index = next + oldLen;
}
return sb.toString();
}
String content = request.getParameter("content");
String htmlContent = replace(content, "\r\n", "<br>")
.replace("\n", "<br>")
.replace("\r", "<br>");
// Java 1.5+ String.replace(CharSequence, CharSequence) - 替換所有
String result = source.replace(oldStr, newStr);
// Apache Commons Lang
StringUtils.replace(source, oldStr, newStr);
/**
* 將 HTML 特殊字元轉為實體參考,防止 XSS 與顯示錯誤
*/
public String escapeHtml(String input) {
if (input == null || input.isEmpty()) return input;
StringBuilder sb = new StringBuilder(input.length() + 16);
for (int i = 0; i < input.length(); i++) {
char c = input.charAt(i);
switch (c) {
case '&': sb.append("&"); break;
case '<': sb.append("<"); break;
case '>': sb.append(">"); break;
case '"': sb.append("""); break;
case '\'': sb.append("'"); break;
default: sb.append(c);
}
}
return sb.toString();
}
public String unescapeHtml(String input) {
if (input == null) return null;
return input.replace("<", "<")
.replace(">", ">")
.replace(""", "\"")
.replace("'", "'")
.replace("&", "&"); // 最後處理 &
}
// Java 标准库无内建 HTML escape,常用方案:
// 1. Apache Commons Text
StringEscapeUtils.escapeHtml4(input);
// 2. Spring Framework
HtmlUtils.htmlEscape(input);
// 3. OWASP Java Encoder (最安全)
Encode.forHtml(input);
public final class StringUtils {
private StringUtils() {}
// 中文編碼修正(舊專案相容)
public static String fixEncoding(String str, String fromEncoding, String toEncoding) {
if (str == null) return null;
try {
return new String(str.getBytes(fromEncoding), toEncoding);
} catch (UnsupportedEncodingException e) {
return str;
}
}
// 字串替換
public static String replaceAll(String source, String target, String replacement) {
if (source == null || target == null || target.isEmpty()) return source;
return source.replace(target, replacement); // Java 1.5+
}
// HTML 轉義
public static String escapeHtml(String input) {
if (input == null) return null;
return input.replace("&", "&")
.replace("<", "<")
.replace(">", ">")
.replace("\"", """)
.replace("'", "'");
}
// HTML 反轉義
public static String unescapeHtml(String input) {
if (input == null) return null;
return input.replace("<", "<")
.replace(">", ">")
.replace(""", "\"")
.replace("'", "'")
.replace("&", "&");
}
// 換行轉
public static String nl2br(String input) {
if (input == null) return null;
return input.replace("\r\n", "
")
.replace("\n", "
")
.replace("\r", "
");
}
}
所有使用者輸入輸出到 HTML 頁面前,必須經過 HTML 轉義。單純的
replace可能有疏漏(如事件處理器onload、JavaScript 協定javascript:),正式專案請使用成熟編碼庫(OWASP Java Encoder、Spring HtmlUtils)。
| 需求 | 舊版手工實作 | 現代標準做法 |
|---|---|---|
| 中文編碼修正 | getStr() 手動轉碼 | Filter + request.setCharacterEncoding + URIEncoding |
| 字串替換 | 迴圈 indexOf + StringBuilder | String.replace() / StringUtils.replace() |
| HTML 轉義 | 逐字元 switch 判斷 | OWASP Encoder / Spring HtmlUtils / Commons Text |
| 換行轉 br | 多次 replace | StringUtils.nl2br() / 手動 replace |