首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> Java 程式設計 >> Java 程式設計入門

Ajax 與 Servlet 交互實戰:XML 回應、編碼處理、前端解析

     編輯:Java 程式設計入門

架構圖

前端 (JS) -- XMLHttpRequest --> Servlet -- JDBC --> MySQL
前端 (JS) <-- XML Document ---- Servlet

前端 JavaScript (原生 XMLHttpRequest)

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);
        }
    }
}

後端 Servlet (支援 UTF-8/GBK 雙模式)

@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-1server.xml `` 或手動 `new String(bytes, "ISO-8859-1", "UTF-8")`
回應 XML 中文未設定 Content-Type charset`resp.setContentType("text/xml;charset=UTF-8")`
前端 JS 檔案編碼.js 檔案非 UTF-8 導致 `encodeURIComponent` 錯誤IDE/建構工具統一輸出 UTF-8,HTML ``

現代替代:JSON + Fetch API

// 前端
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 體積更小、解析更快、原生支援複雜資料結構,建議新專案優先採用。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved