前端 (JS) -- XMLHttpRequest --> Servlet -- JDBC --> MySQL
前端 (JS) <-- XML Document ---- Servlet
var req;
function loadCategories() {
var sel = document.getElementById("categorySelect");
var key = sel.options[sel.selectedIndex].text; // 使用者選擇的分類名稱
req = new XMLHttpRequest(); // 現代瀏覽器
// 編碼參數:前端頁面為 UTF-8,Servlet 端統一用 UTF-8 解碼
var url = "ajaxServlet?action=" + encodeURIComponent(key);
req.open("GET", url, true);
req.setRequestHeader("Content-Type", "text/xml;charset=UTF-8"); // 告知 Servlet 回應類型
req.onreadystatechange = handleResponse;
req.send(null);
}
function handleResponse() {
if (req.readyState === 4 && req.status === 200) {
var xmlDoc = req.responseXML; // 自動解析為 Document 物件
var items = xmlDoc.getElementsByTagName("type_name");
var target = document.getElementById("subCategorySelect");
target.innerHTML = ""; // 清空舊選項
for (var i = 0; i < items.length; i++) {
var text = items[i].textContent || items[i].text; // 跨瀏覽器取文字
var opt = document.createElement("option");
opt.text = text;
target.add(opt);
}
}
}
@WebServlet("/ajaxServlet")
public class AjaxServlet extends HttpServlet {
protected void doGet(HttpServletRequest req, HttpServletResponse resp)
throws ServletException, IOException {
resp.setContentType("text/xml;charset=UTF-8");
resp.setHeader("Cache-Control", "no-cache");
resp.setHeader("Pragma", "no-cache");
String action = req.getParameter("action");
String encoding = req.getParameter("encoding"); // 前端可傳 encoding=UTF-8 或 gbk
// 統一轉為 UTF-8 內部處理
if ("gbk".equalsIgnoreCase(encoding)) {
action = new String(action.getBytes("ISO-8859-1"), "GBK");
} else {
// Tomcat 8+ 預設 GET 參數已為 UTF-8,若非則同理轉碼
action = new String(action.getBytes("ISO-8859-1"), "UTF-8");
}
StringBuilder xml = new StringBuilder();
xml.append("");
try (Connection conn = DataSourceUtil.getConnection();
PreparedStatement ps = conn.prepareStatement("SELECT sub_name FROM sub_category WHERE main_name = ?")) {
ps.setString(1, action);
try (ResultSet rs = ps.executeQuery()) {
while (rs.next()) {
xml.append("").append(escapeXml(rs.getString(1))).append(" ");
}
}
} catch (SQLException e) {
log("DB Error", e);
}
xml.append(" ");
resp.getWriter().write(xml.toString());
}
private String escapeXml(String s) {
return s.replace("&", "&").replace("<", "<").replace(">", ">")
.replace("\"", """).replace("'", "'");
}
}
| 場景 | 問題 | 解決 |
|---|---|---|
| GET 參數中文 | Tomcat 7 預設 ISO-8859-1 | server.xml ` |
| 回應 XML 中文 | 未設定 Content-Type charset | `resp.setContentType("text/xml;charset=UTF-8")` |
| 前端 JS 檔案編碼 | .js 檔案非 UTF-8 導致 `encodeURIComponent` 錯誤 | IDE/建構工具統一輸出 UTF-8,HTML `` |
// 前端
fetch("/api/subcategories?main=" + encodeURIComponent(key))
.then(r => r.json())
.then(list => { /* 填充 select */ });
// 後端 Spring Boot
@GetMapping("/api/subcategories", produces = MediaType.APPLICATION_JSON_VALUE)
public List getSub(@RequestParam String main) {
return service.findSubByMain(main);
}
JSON 體積更小、解析更快、原生支援複雜資料結構,建議新專案優先採用。