頁面動態增減行(如多店鋪信息、多擔保人信息),提交時後端需綁定 List<Entity> 或逐行獲取參數。
public class BusLoanInfoShop {
private Integer id, bid;
private String shopName, platformName, shopLevel, operatingPeriod;
private String shopOwner, subAccount, sbuPassword, businessOpera;
private String businessAddress, warehouseAddress, salesIncome;
private String totalLiability, bankLiabilities, netProfit;
// getter/setter 省略
}
public class ShopListForm {
private List<BusLoanInfoShop> shop;
// getter/setter
}
@RequestMapping("/save")
public void save(ShopListForm shopForm, HttpServletResponse response) {
for (BusLoanInfoShop shop : shopForm.getShop()) {
System.out.println("shopName=" + shop.getShopName());
}
// 業務保存...
}
shop[索引].屬性名<tr id="tShopRow0">
<td><input name="shop[0].shopName" ...></td>
<td><input name="shop[0].platformName" ...></td>
...
</tr>
<!-- JS 動態添加行時,將 name 更新為 shop[1].xxx, shop[2].xxx ... -->
var rowCount = 0; // 隱藏域存儲當前行數
function addShopRow() {
rowCount++;
var $newRow = $("#tShopRow0").clone(true).attr("id", "tShopRow" + rowCount);
$newRow.find("input").val(""); // 清空值
$newRow.find("input").each(function() {
var name = $(this).attr("name"); // shop[0].shopName
name = name.replace(/\[0\]/, "[" + rowCount + "]");
$(this).attr("name", name).attr("id", name.replace(".", "_"));
});
$newRow.appendTo("#tblShopData");
$("#rowCount").val(rowCount);
}
function delShopRow() {
if (rowCount > 0) {
$("#tShopRow" + rowCount).remove();
rowCount--;
$("#rowCount").val(rowCount);
}
}
@RequestMapping("/save")
public void save(HttpServletRequest request, HttpServletResponse response) {
BusLoanInfoGuaranter g = new BusLoanInfoGuaranter();
g.setBid(busLoanInfo.getId());
// 遍歷行數,按 guaranterName0, guaranterName1... 獲取
for (int i = 0; i <= maxRow; i++) {
g.setGuaranterName(request.getParameter("guaranterName" + i));
g.setGuaranterCard(request.getParameter("guaranterCard" + i));
// ... 其他字段
if (StringUtils.isBlank(g.getGuaranterName())) continue; // 跳過空行
guaranteeService.save(g);
}
}
字段名 + 索引<input name="guaranterName0" id="guaranterName0">
<input name="guaranterCard0" id="guaranterCard0">
<!-- JS 動態行同樣更新 name/id 為 guaranterName1, guaranterCard1... -->
| 維度 | 方式一:List 表單對象 | 方式二:原生 Request |
|---|---|---|
| 代碼結構 | OOP,類型安全,IDE 提示 | 過程式,字符串拼接,易寫錯 |
| 參數綁定 | Spring 自動綁定,零代碼 | 手動 getParameter,樣板代碼多 |
| 校驗支援 | JSR-303 @Valid 直接生效 | 需手動校驗 |
| 靈活度 | 固定結構 | 極其靈活,適配非標準名 |
| 適用場景 | 標準業務、長期維護 | 快速原型、臨時接口、第三方回調 |
data-index 屬性而非依賴 DOM 順序,避免刪除中間行導致索引錯亂。.clone(true) 保留事件綁定,但需注意 id 唯一性(建議移除 id 或重命名)。首選方式一:定義 ListForm + 實體類,JSP 按 list[索引].屬性 命名,Spring 自動綁定,代碼乾淨、類型安全、支援校驗。
方式二作為備選:當參數名無法控制(如對接第三方固定格式)或極簡單臨時接口時使用。