大型 Web 專案常由多地團隊並行開發,介面契約 (WSDL/JSON) 確立後,後端服務往往尚未就緒。本文提出基於 Spring 2.0 的模擬器框架,讓前端團隊獨立開發測試,並支援功能/效能/負面測試、SLA 延遲模擬、服務儀表板監控。
| 維度 | Stub (本地存根) | 模擬器 (遠端模擬) |
|---|---|---|
| 程式碼路徑 | 繞過網路層,直接呼叫本地方法 | 完整走網路棧 (HTTP/SOAP/JSON),真實驗證編組/解組 |
| 應用程式感知 | 需知曉「Stub 模式」切換邏輯 | 僅改端點 URL,應用程式零感知 |
| 測試深度 | 單元/整合測試 | 端到端功能、效能、負面測試 |
| 部署彈性 | 編譯期綁定 | 執行期動態切換 (真實/模擬) |
結論:模擬器雖較重,但能盡早暴露介面整合、序列化、效能等真實問題。
Spring XmlBeanFactory 讀取 XML → 轉換 POJO、注入延遲 (模擬 SLA)、預設值回退。spring-beans-2.0.xsd),每個測試場景一檔。
<servlet>
<servlet-name>RPCAdapter</servlet-name>
<servlet-class>com.ibm.websphere.rpcadapter.RPCAdapter</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>RPCAdapter</servlet-name>
<url-pattern>/RPCAdapter/*</url-pattern>
</servlet-mapping>
<services>
<pojo>
<name>AccountSearchImpl</name>
<description>com.simulator.service.AccountSearchImpl</description>
<methods filter="whitelisting">
<method>
<name>getAccountsByEquipment</name>
<parameters>
<parameter><name>request</name>...</parameter>
<parameter><name>equipId</name>...</parameter>
</parameters>
</method>
</methods>
</pojo>
</services>
public ESIGetAccountsByEquipmentResponseType getAccountByEquipment(
HttpServletRequest req, String endPoint, String equipId) {
ESIGetAccountsByEquipmentRequestType request = new ...();
request.setEquipment(new Equipment(equipId));
AccountSearch service = (AccountSearch) new InitialContext()
.lookup("java:comp/env/service/AccountSearch");
AccountSearchPort port = service.getPort(AccountSearchPort.class);
((Stub)port)._setProperty(Stub.ENDPOINT_ADDRESS_PROPERTY, endPoint);
return port.getAccountsByEquipment(request);
}
public ESIGetAccountsByEquipmentResponseType getAccountsByEquipment(
ESIGetAccountsByEquipmentRequestType input) {
String simKey = input.getEquipment().getSim(); // 提取鍵值
try {
return (ResponseType) DataGenerator.getDataByBeanId(
"ESIGetAccountsByEquipmentResponseType",
ACTION_KEY_EQUIPMENT, simKey);
} catch (BeanDefinitionStoreException e) {
// 找不到對應 XML → 回退預設場景
return (ResponseType) DataGenerator.getDataByDefault(
"ESIGetAccountsByEquipmentResponseType",
ACTION_KEY_EQUIPMENT, DEFAULT_EQUIPMENT_CODE);
}
}
public static Object getDataByBeanId(String beanId, String action, String key) {
String xmlFile = resolveXmlFile(action, key); // 如 simulator/xml/Account/ACT123.xml
XmlBeanFactory factory = new XmlBeanFactory(new FileSystemResource(xmlFile));
Object pojo = factory.getBean(beanId);
// 延遲注入 (模擬 SLA 響應時間)
String latency = getEnvProperty("AccountSearch.Latency"); // 如 "500" ms
if (latency != null) Thread.sleep(Integer.parseInt(latency));
return pojo;
}
<beans xmlns="https://www.springframework.org/schema/beans" ...>
<bean name="ESIGetAccountsByEquipmentResponseType"
class="com.simulator.eo.account.ESIGetAccountsByEquipmentResponseType">
<property name="accountSummary">
<bean class="com.simulator.eo.account.AccountSummaryType">
<property name="ssn" value="123-45-6789"/>
</bean>
</property>
</bean>
</beans>
將環境相關參數 (端點 URL、XML 目錄、延遲、啟用旗標) 存於 WAS 管理主控台,而非屬性檔,支援叢集同步與熱更新:
| 屬性名 | 範例值 | 用途 |
|---|---|---|
| AccountSearch.Endpoint | https://localhost:10000/Simulator/services/AccountSearch | 模擬器端點 |
| Simulator.Directory | C:\simulator\xml\ | XML 資料根目錄 |
| AccountSearch.Latency | 500 | 模擬延遲 (ms) |
| AccountSearch.Enabled | true | 總開關 |
JSP/Java 透過 EnvironmentProviderUtility.getWebServiceEnvironmentAttribute("AccountSearch.Endpoint") 讀取。
框架初期投入較大,但跨專案生命週期 ROI 極高,已成電信/金融大型 SOA 專案標準基建。