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

基於 jQuery AJAX 與 Struts 2 實現依據 ID 動態填充表單欄位完整範例

     編輯:Java 程式設計入門

前言

在傳統 Java Web 開發 (JSP + Struts 2 + jQuery) 中,「根據下拉選單選擇的 ID,異步獲取後端數據並自動填充表單多個輸入框」是極常見的需求。本文提供一個完整的前後端分離式實作範例,涵蓋前端事件綁定、JSON 交互、後端 Action 處理、常見坑點與優化建議。

完整程式碼實作

1. 前端頁面 (JSP + jQuery)

<%@ page contentType="text/html;charset=UTF-8" %>
<%@ taglib prefix="s" uri="/struts-tags" %>
<html>
<head>
    <title>SR 備註自動填充示例</title>
    <script src="https://cdn.jsdelivr.net/npm/jquery@3.6.0/dist/jquery.min.js"></script>
</head>
<body>
    <h3>SR 單據備註查詢</h3>
    
    <!-- 查詢條件:SR ID 下拉選單 -->
    <label>SR ID: </label>
    <s:select name="srid" id="srid" list="srIdList" listKey="id" listValue="name" headerKey="0" headerValue="-- 請選擇 --" />
    <button type="button" id="btnLoad">載入備註</button>
    <button type="button" id="btnClear">清空</button>

    <hr/>
    <!-- 目標表單欄位 -->
    <div>
        <label>BPA 備註:</label> <input type="text" id="bparemark" name="bpa_remark" readonly/>
    </div>
    <div>
        <label>ITD 備註:</label> <input type="text" id="itdremark" name="itd_remark" readonly/>
    </div>
    <div>
        <label>BUG 備註:</label> <input type="text" id="bugremark" name="bu_remark" readonly/>
    </div>
    <div>
        <label>ITO 備註:</label> <input type="text" id="itoremark" name="ito_remark" readonly/>
    </div>

    <script>
        $(function() {
            // 1. 綁定下拉選單 change 事件 (比按鈕點擊更自然)
            $('#srid').on('change', loadSrRemark);
            
            // 2. 也可綁定按鈕點擊
            $('#btnLoad').on('click', loadSrRemark);
            $('#btnClear').on('click', clearFields);
        });

        function loadSrRemark() {
            var srId = $('#srid').val();
            
            // 前端驗證
            if (!srId || srId === '0') {
                clearFields();
                alert('請選擇有效的 SR ID!');
                $('#srid').focus();
                return;
            }

            // 3. 發送 AJAX 請求 (GET,附帶時間戳防快取)
            $.getJSON('loadSrRemark.do', { 
                srid: srId,
                _: new Date().getTime()  // 防止 IE 緩存
            })
            .done(function(data) {
                // 4. 成功回調:填充欄位
                // 後端返回 JSON: { "bpa_remark": "...", "itd_remark": "...", ... }
                $('#bparemark').val(data.bpa_remark || '');
                $('#itdremark').val(data.itd_remark || '');
                $('#bugremark').val(data.bu_remark || '');
                $('#itoremark').val(data.ito_remark || '');
                console.log('備註載入成功', data);
            })
            .fail(function(jqXHR, textStatus, errorThrown) {
                // 5. 錯誤處理
                console.error('載入失敗:', textStatus, errorThrown);
                alert('獲取備註失敗,請稍後重試或聯繫管理員。');
                clearFields();
            });
        }

        function clearFields() {
            $('#bparemark, #itdremark, #bugremark, #itoremark').val('');
        }
    </script>
</body>
</html>

2. 後端 Action (Struts 2)

package com.aegon_cnooc.oa.admin.action;

import com.aegon_cnooc.framework.base.action.BaseAction;
import com.aegon_cnooc.oa.admin.service.UserService;
import com.aegon_cnooc.oa.ibatis.to.TuOafSrMainTO;
import com.opensymphony.xwork2.ActionSupport;
import org.apache.struts2.convention.annotation.Action;
import org.apache.struts2.convention.annotation.Result;
import org.apache.struts2.convention.annotation.Results;
import org.springframework.beans.factory.annotation.Autowired;

@Action(value = "loadSrRemark")
@Results({
    @Result(name = "success", type = "json", params = { "root", "srMain" })
})
public class LoadSrRemarkAction extends BaseAction {

    @Autowired
    private UserService userService; // 注入 Service

    private String srid; // 接收前端參數 (Struts 2 自動注入)
    private TuOafSrMainTO srMain; // 返回給前端的對象 (getter 供 JSON 序列化)

    @Override
    public String execute() throws Exception {
        if (srid == null || srid.trim().isEmpty()) {
            return SUCCESS; // 返回空對象
        }

        // 業務查詢
        srMain = userService.getRemarkBySrId(srid.trim());
        
        // 若查無資料,srMain 為 null,JSON 序列化為 null,前端 .done 會收到 null
        // 建議 Service 層返回空對象而非 null,避免前端報錯
        return SUCCESS;
    }

    // Getter/Setter (Struts 2 JSON 插件需要 getter 序列化)
    public String getSrid() { return srid; }
    public void setSrid(String srid) { this.srid = srid; }
    public TuOafSrMainTO getSrMain() { return srMain; }
    public void setSrMain(TuOafSrMainTO srMain) { this.srMain = srMain; }
}

3. Struts 2 配置 (struts.xml 或約定優於配置)

若使用約定插件 (`struts2-convention-plugin`),上方註解即可生效。若用傳統 `struts.xml`:

<action name="loadSrRemark" class="com.aegon_cnooc.oa.admin.action.LoadSrRemarkAction">
    <result type="json">
        <param name="root">srMain</param> <!-- 指定序列化的根對象 -->
    </result>
</action>

4. Service 與 TO (傳輸對象) 參考

// Service 接口
public interface UserService {
    TuOafSrMainTO getRemarkBySrId(String srid);
}

// TO 類 (對應資料表字段,需實現 Serializable)
public class TuOafSrMainTO implements Serializable {
    private String bpa_remark;
    private String itd_remark;
    private String bu_remark;
    private String ito_remark;
    // Getter/Setter 省略...
}

關鍵技術點與避坑指南

1. JSON 交互:Struts 2 JSON 插件原理

  • 引入依賴:`struts2-json-plugin` (版本需與 Struts 核心一致)。
  • Result type="json" 會自動將 Action 中指定 `root` 對象 (或整個 Action) 序列化為 JSON。
  • 預設排除 null 屬性,前端收到 `undefined` 需用 `|| ''` 兼容。

2. 編碼問題:中文亂碼終極解決

原始碼中 `response.setCharacterEncoding("gbk")` 易致亂碼。全站統一 UTF-8:

  • JSP 頁面:`<%@ page pageEncoding="UTF-8" %>`
  • web.xml 配置 `CharacterEncodingFilter` (Spring) 或 Struts `filterDispatcher` 設定 encoding。
  • JSON 結果類型預設 UTF-8,無需手動設定 GBK。

3. 防快取策略

前端 `$.getJSON` 附帶 `_: timestamp` 參數,或後端在 Action 中設定回應頭:

response.setHeader("Cache-Control", "no-cache, no-store, must-revalidate");
response.setHeader("Pragma", "no-cache");
response.setDateHeader("Expires", 0);

4. 異常處理與用戶體驗

  • 前端 `.fail()` 統一捕獲網路/HTTP 錯誤 (404, 500, timeout)。
  • 後端業務異常拋出,由 Struts 全局異常攔截器捕獲,返回統一錯誤 JSON:`{ "error": "msg", "code": 500 }`,前端解析顯示友好提示。

5. 安全性:輸入驗證與 XSS 防護

  • 後端 `srid` 參數需校驗格式 (如正則 `^\d+$`),防 SQL 注入 (iBatis/MyBatis `#{}` 參數化已防禦)。
  • 前端填充時用 `.val()` 而非 `.html()`,天然防 XSS。若需顯示 HTML 內容,務必轉義。

現代化改造建議

  1. 前後端分離:後端改為 Spring MVC / Spring Boot `@RestController` 返回 `ResponseEntity`,前端用 Vue/React/Axios 調用。
  2. 統一回應格式:定義 `Result { code, message, data }`,替代裸露實體對象。
  3. 參數校驗:使用 JSR-303 `@NotBlank @Pattern` 註解替代手動 if 判斷。
  4. 移除 jQuery 依賴:原生 `fetch API` 或 Axios 更輕量。

總結

本範例展示了經典 Struts 2 + jQuery 實現「ID 聯動填充表單」的標準模式:前端事件驅動 → AJAX 異步請求 → 後端 Action 查詢 Service → JSON 序列化返回 → 前端 DOM 更新。掌握編碼統一、快取控制、異常處理、安全防護四大要素,即可構建穩健可維護的交互功能。

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