當系統功能模塊眾多,將所有頁面代碼堆砌在單一 JSP 中會導致維護困難。採用模板化拆分,按功能模組劃分頁面片段,按需動態加載,可顯著提升代碼復用性與開發效率。本文基於傳統 SSH + MyBatis 技術棧,提供兩種成熟拆分方案。
後端 Action 查詢數據 → 存入域對象 → 轉發到功能 JSP → JSP 使用 EL 表達式渲染數據 → JS 通過 AJAX 請求 HTML 片段並彈窗展示。
<div class="col-12 b-b">
<table class="table table-form">
<tr>
<td class="m_c" width="180px">客戶名稱</td>
<td width="200px">${loanRiskBean.cusName}</td>
<td class="m_l" width="180px">存款金額</td>
<td>${loanRiskBean.dueBillAmount} 元</td>
</tr>
</table>
</div>
<action name="riskDetailItem" class="riskRecheckAction" method="detailItem">
<result name="success">/WEB-INF/jsp/riskrecheck/riskDetailItem.jsp</result>
</action>
private LoanRiskBean loanRiskBean;
public String detailItem() {
try {
loanRiskBean = riskRecheckServiceImpl.detailItem(riskId);
} catch (Exception e) {
throw new RuntimeException("檢查詳情異常");
}
return SUCCESS;
}
$(document).on('click', '.related', function() {
var loanid = $(this).attr("loanid");
var url = "/hbpost/riskRecheck/riskDetailItem.action?time=" + new Date() + "&loanid=" + loanid;
$.ajax({
url: url,
type: "get",
success: function(data) {
relatedDialog = $dialog({
id: 'relatedDialog',
width: 1000,
title: "相關信息",
content: data // 直接使用服務端渲染好的 HTML
}).showModal();
}
});
});
功能 JSP 不包含業務數據,僅定義表格結構。需 兩次 AJAX 請求:第一次獲取頁面模板,第二次獲取 JSON 數據並填充 DOM。解決「頁面未加載導致無法獲取 DOM 元素」的問題。
<div class="relatedInfo mainBusiness">
<div>
<h5>經營名稱不一致</h5>
<table class="grid table table-striped addtable">
<thead>
<tr><th>客戶名稱</th><th>借據金額</th></tr>
</thead>
<tbody></tbody> <!-- 數據由 JS 動態填充 -->
</table>
</div>
</div>
<!-- 數據查詢 Action,返回 JSON -->
<action name="riskRelatedItem" class="riskRecheckAction" method="relatedItem"></action>
<!-- 頁面跳轉 Action,返回 JSP 模板 -->
<action name="riskRelatedItemSwitch" class="riskRecheckAction" method="relatedItemSwitch">
<result name="success">/WEB-INF/jsp/riskrecheck/riskRelatedItem.jsp</result>
</action>
// 查詢數據,輸出 JSON
public void relatedItem() {
List<LoanRiskBean> list = riskRecheckServiceImpl.relatedItem(loanid);
this.outputStreamModelAndView(list); // 自定義 JSON 輸出方法
}
// 僅跳轉頁面
public String relatedItemSwitch() {
return SUCCESS;
}
$(document).on('click', '.related', function() {
var loanid = $(this).attr("loanid");
var urlSwitch = "/hbpost/riskRecheck/riskRelatedItemSwitch.action";
var urlData = "/hbpost/riskRecheck/riskRelatedItem.action?loanid=" + loanid;
// 先請求頁面模板
$.ajax({ url: urlSwitch, type: "get", success: function(templateHtml) {
// 再請求數據並填充
$.ajax({ url: urlData, type: 'get', dataType: 'json', success: function(data) {
var tmpArray = data.object;
for (var i = tmpArray.length - 1; i >= 0; i--) {
if (tmpArray[i].tipstr == "住址不一致") {
$(".sameAddress tbody").append(
"<tr><td>" + tmpArray[i].cusName + "</td><td>" + tmpArray[i].duebillNo + "</td></tr>"
);
$(".sameAddress").show();
}
}
}});
// 彈窗展示已填充數據的模板
relatedDialog = $dialog({ content: templateHtml, ... }).showModal();
}});
});
| 維度 | 方案一:服務端渲染 | 方案二:前端渲染 |
|---|---|---|
| 開發效率 | 高(JSP 直出 HTML) | 中(需編寫 JS 填充邏輯) |
| 前後端分離度 | 低 | 高(接口復用性強) |
| 首屏性能 | 好(無額外請求) | 稍弱(雙請求) |
| 適用場景 | 傳統項目、SEO 需求、團隊前端弱 | 漸進式重構、API 多端復用、前端能力強 |
兩種方案各有優勢,方案一適合快速交付的傳統項目;方案二為前後端分離鋪路。實際項目中可混用:核心高頻模塊用方案一,複雜交互模塊用方案二。關鍵在於 Struts Action 的職責劃分 與 JS 請求協調邏輯 的清晰設計。