JAX-RPC GenericHandlerがWebsphere Application Server v6.0.2.35で失敗する
-
05-07-2019 - |
質問
SOAPHeaderHandlerというGenericHandlerの拡張機能を作成しました。 log4jステートメントをハンドラーに配置すると、構築中のコンストラクターを確認できます。ただし、SOAPメッセージを生成すると、handleRequestメソッドに関連するメッセージが表示されません。次のようにスタブにハンドラーを登録しました:
if (service == null) {
super.service = new com.ibm.ws.webservices.engine.client.Service();
}
else {
super.service = service;
}
List handlerInfoList = new ArrayList();
QName[] headersArr = null;
HandlerInfo handlerInfo = new HandlerInfo(com.xxxxxx.hdhp.business.debitcard.cardservices.CardServiceSOAPHeaderHandler.class,
null, headersArr);
handlerInfoList.add(handlerInfo);
service.getHandlerRegistry().setHandlerChain(new QName("MetavanteDebitCard"), handlerInfoList);
ハンドラーは次のとおりです。
public class AccountManagementSOAPHeaderHandler extends GenericHandler {
private static Logger logger = Logger.getLogger (AccountManagementSOAPHeaderHandler.class);
private HandlerInfo handlerInfo = null;
public AccountManagementSOAPHeaderHandler () {
logger.info("Constructing AccountManagementSOAPHeaderHandler");
}
/* (non-Javadoc)
* @see javax.xml.rpc.handler.GenericHandler#getHeaders()
*/
public QName[] getHeaders() {
logger.info("calling getHeaders()");
return null;
}
public boolean handleFault(MessageContext arg0) {
logger.info("Fault in AccountManagementSOAPHeaderHandler");
return true;
}
public boolean handleResponse(MessageContext arg0) {
logger.info("Response in AccountManagementSOAPHeaderHandler");
return true;
}
public void init(HandlerInfo arg0) {
logger.info("init in AccountManagementSOAPHeaderHandler");
handlerInfo = arg0;
super.init(arg0);
}
public void destroy() {
logger.info("--- In AccountManagementSOAPHeaderHandler.destroy ()");
}
public boolean handleRequest(MessageContext ctx) {
logger.debug("BEGIN handleRequest()");
if (ctx instanceof SOAPMessageContext) {
SOAPMessageContext context = (SOAPMessageContext) ctx;
logger.debug("instance of SOAPMessageContext");
try {
SOAPHeader header = context.getMessage().getSOAPPart()
.getEnvelope().getHeader();
logger.debug("SOAP Header is " + ((header==null)?"NULL":"NOT NULL"));
Iterator headers = header
.extractHeaderElements("http://schemas.xmlsoap.org/soap/actor/next");
while (headers.hasNext()) {
SOAPHeaderElement he = (SOAPHeaderElement) headers.next();
logger.info("HEADER Qn " + he.getElementName().getQualifiedName());
}
} catch (SOAPException x) {
logger.error("SOAPException while handlingRequest for SOAP: '" + x.getMessage() + "'");
}
}
return true;
}
そして、web.xmlを次のように変更しました:
<service-ref>
<description>WSDL Service AccountManagerService</description>
<service-ref-name>service/AccountManagerService</service-ref-name>
<service-interface>com.medibank.www.AccountManagerService</service-interface>
<!-- <wsdl-file>WEB-INF/wsdl/AccountManagerService.asmx.wsdl</wsdl-file>-->
<jaxrpc-mapping-file>WEB-INF/AccountManagerService.asmx_mapping.xml</jaxrpc-mapping-file>
<service-qname xmlns:pfx="http://www.medibank.com/MBIWebServices/Access/Services/AccountManager/2004/06/">pfx:AccountManagerService</service-qname>
<port-component-ref>
<service-endpoint-interface>com.medibank.www.AccountManagerServiceSoap</service-endpoint-interface>
</port-component-ref>
<port-component-ref>
<service-endpoint-interface>com.medibank.www.AccountManagerServiceSoap</service-endpoint-interface>
</port-component-ref>
<handler>
<description>
</description>
<display-name></display-name>
<handler-name>AccountManagementSOAPHeaderHandler</handler-name>
<handler-class>com.xxxxx.hdhp.business.debitcard.accountmanagement.AccountManagementSOAPHeaderHandler</handler-class>
</handler>
</service-ref>
これは、Websphere Application Server v6.0.2.35にデプロイされます。問題が何であるか考えていますか?ハンドラー内のロガーステートメントが実行されないのはなぜですか?ハンドラーを正しく登録できませんでしたか?どのサービスメソッドが処理されるかを指定する必要がありますか?
解決
WAS 6.0で実行するJAX-RPC SOAPクライアントをいくつか作成し、メッセージを要求するためにカスタムSOAPヘッダーを追加するGenericHandlersを必要とします。また、(クライアントコードベースでの使いやすさの理由で)service-refを使用しないという要件があったため、クライアントクラスはハンドラーをプログラムで設定します。これは、構成の動作にはまったく当てはまらない場合がありますが、おそらく何か役に立つでしょう。
RAD 7.5のAntのWSDL2Javaツールで生成されたクライアントコードから始めましたが、「Webサービスクライアント」はウィザードも同様に使用します。すべてのビジネスオブジェクト、シリアライザ/デシリアライザ、ロケータ、SOAPバインディングクラスなどを作成しました。次に、所有しているものと同様のカスタムGenericHandlerを作成しました。
使用可能なservice-refがないため、そのようにクライアントにバインドできませんでした。そこで、プログラムでハンドラーを追加するために、クライアントクラス自体で次のコードを使用しました。
private AccountManager createAccountManagerStub() throws Exception {
AccountManagerServiceLocator locator = new AccountManagerServiceLocator();
// Set the JMS endpoint address
AccountManagerSOAPBindingStub accountManagerStub = (AccountManagerSOAPBindingStub) locator
.getAccountManagerSOAPPort(new URL(generateJMSEndpointAddress()));
// Set the Client Handler
HandlerRegistry registry = locator.getHandlerRegistry();
List chain = registry
.getHandlerChain((QName) locator.getPorts().next());
HandlerInfo handlerInfo = new HandlerInfo();
handlerInfo.setHandlerClass(AccountManagerClientHandler.class);
chain.add(handlerInfo);
return (AccountManager) accountManagerStub;
}
そのメソッドによって返されるオブジェクトは完全に設定され、そのクラスのクライアントメソッドの呼び出しは正しく機能します。 AccountManagerClientHandler.handleRequest(MessageContext msgContext)メソッドが呼び出され、messageContextが更新された後、メッセージは陽気な方法で送信されます。