在傳統 Java Web 開發 (JSP + Struts 2 + jQuery) 中,「根據下拉選單選擇的 ID,異步獲取後端數據並自動填充表單多個輸入框」是極常見的需求。本文提供一個完整的前後端分離式實作範例,涵蓋前端事件綁定、JSON 交互、後端 Action 處理、常見坑點與優化建議。
<%@ 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>
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; }
}
若使用約定插件 (`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>
// 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 省略...
}
原始碼中 `response.setCharacterEncoding("gbk")` 易致亂碼。全站統一 UTF-8:
前端 `$.getJSON` 附帶 `_: timestamp` 參數,或後端在 Action 中設定回應頭:
response.setHeader("Cache-Control", "no-cache, no-store, must-revalidate");
response.setHeader("Pragma", "no-cache");
response.setDateHeader("Expires", 0);
本範例展示了經典 Struts 2 + jQuery 實現「ID 聯動填充表單」的標準模式:前端事件驅動 → AJAX 異步請求 → 後端 Action 查詢 Service → JSON 序列化返回 → 前端 DOM 更新。掌握編碼統一、快取控制、異常處理、安全防護四大要素,即可構建穩健可維護的交互功能。