ApexでSOAP通信をしたときに’Failed to get next element’と表示されたとき

Apex

LWCのApexコントローラで外部WebサービスとSOAP通信を行う実装を行いました。このときWDSLが用意されていたため、このWDSLからAPEXを自動生成したクラスでSOAP通信の処理を実装しました。このとき、XMLのレスポンスを取得できたのですが、エラーメッセージ「Failed to get next element」が表示されてしまいました。ググったところ、Failed to get next element’ error in web service calloutsという記事がヒットしました。この記事によると、”応答内の <soap:Envelope> 要素の前に非 XML 要素がある場合、パーサーは「次の要素を取得できませんでした」という例外をスローします。”とのことです。

以下のような構造の応答を取得しているということですね。

00:00:00.000 (111111111)|CALLOUT_RESPONSE|[111]|
--uuid:aaaaaaa
Content-Type: application/xop+xml; charset=UTF-8; type="text/xml";
Content-Transfer-Encoding: binary
Content-ID: <root.message@cxf.apache.org>

<soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/"><soap:Body>...</soap:Body></soap:Envelope>
--uuid:aaaaaaa--

自動生成されたAPEXクラスでは、外部APIサービスのコールアウトをWebServiceCalloutクラスのinvokeメソッドで実施していました。しかし、invokeメソッドではXMLのみで構成された応答にしか対応していないので例外をスローします。invokeメソッドの内部処理を改変した処理を実装できれば良かったのですが、ブラックボックス化しており自分ではソースコードやドキュメントの解析できませんでした。

そのため、invokeメソッドを実行しない形にコードを変更する必要がありました。SOAPはHTTP通信を実行しているので、リクエストにXMLを送信するため、DOM を使用した XML の読み取りと書き込みを参考にhttpRequestのbody部にリクエスト内容をセットし、http通信を実行します。そして取得したレスポンス内容からXML部分を抽出します。

抽出したXMLレスポンスからXMLNodeクラスのgetChildrenメソッドやgetChildElementメソッドで必要な要素を取得することで、マルチパート応答でも’Failed to get next element’のエラーを回避してSOAP通信を実行し、値を取り扱うことができました。

コメント

タイトルとURLをコピーしました