目前我們使用 jax-ws 來創建和使用 SOAP Web 服務,通過 wsimport 目標生成 java 類。
然后,我們創建一個 Service 類來呼叫這個 Web 服務。Service 類中的代碼是這樣的:
public WebServiceRS webServiceCall() {
Security security = SecurityFactory.getTokenSecurity();
MessageHeader header = MessageHeaderFactory.getMessageHeader(SERVICE_ACTION);
LOGGER.info("Calling CreatePassengerNameRecordRQ webService ...");
Holder<Security> securityHolder = new Holder<>(security);
Holder<MessageHeader> headerHolder = new Holder<>(header);
addHandlers(port);
WebServiceRS webServiceRS = port.webServiceRQ(
headerHolder,
securityHolder,
getRequestBody()
);
...
return webServiceRS
}
因此,我們注意到并且可能存在問題的是,此 Service 類依賴于 .wsdl 生成的檔案,例如 Security、MessageHeader、WebServiceRS 等。因此,當我們將 .wsdl 檔案更新到較新版本時,代碼最終會因為這種依賴關系而中斷。
那么,我們想要實作的是一種反轉這種依賴關系的方法,這樣我們就可以更新 Web 服務(即 .wsdl 生成的類)而不改變我們的 Service 類。我們遇到了問題,因為我們還沒有找到解決這個問題的模式。主要的困難似乎來自于我們不能改變這些生成的類來實作一個介面作為例子。
我們對可以松散這種耦合的模式或最佳實踐感興趣。
uj5u.com熱心網友回復:
解決方案 1. 使用配接器模式
在您的情況下,服務合同將發生變化,您需要同步兩個不同的物件。配接器將為其主題提供不同的介面。
- 為您的客戶端模型創建介面
public interface ClientModel {
String getValue();
}
- 創建將轉換
DTO為的配接器ClientModel
public class ClientModelAdapter implements ClientModel {
private DTO dto;
public ClientModelAdapter(DTO dto) {
this.dto = dto;
}
@Override
public String getValue() {
return dto.getValue();
}
}
public class DTO {
private String value;
public String getValue() {
return value;
}
}
配接器和代理模式之間的確切區別是什么?
解決方案 2. 使用映射器模式
DTO您可以簡單地在和之間創建一個映射器ClientModel
public class ClientModelMapper {
ClientModel map(DTO dto) {
ClientModel clientModel = new ClientModel();
clientModel.setValue(dto.getValue());
return clientModel;
}
}
傳輸資料的映射器組件,確保 DTO 和客戶端模型不需要相互了解。
在這種情況下,您可以使用MapStruct框架來避免手工映射。
解決方案 3. 使服務 API 向后兼容
也許您可以避免破壞 SOAP 服務的更改并使 API 向后兼容。向后兼容性和 Web 服務
uj5u.com熱心網友回復:
你可以放在代理類后面。這樣,您唯一需要適應 .wsdl 檔案更改的就是代理類。
轉載請註明出處,本文鏈接:https://www.uj5u.com/caozuo/434675.html
