[WSDL2Java スタブを使う際に、どのようにしてヘッダを取得/設定するのですか?] [編集日時 2004年1月16日am8:37 版]
質問: WSDL2Java スタブを使う際に、どのようにしてヘッダを取得/設定するのですか?
回答: 2種類のヘッダがあります。明示的なものと暗示的なものです。明示的なヘッダはサービスの WSDL の中で定義されています。WSDL2Java 生成ツールはたいていの場合これらのヘッダを認識し、ヘッダをメソッドへの引数として含む、スタブクラスメソッドを出力します。
WSDL の中で明示的に呼び出されたくないヘッダを設定したい場合もあるかもしれません。例えば、ハンドラの中でいくつかのカスタム処理を行いたい場合や、セキュリティを追加したい場合です。この場合、スタブメソッドを呼び出す前に、リクエストにハンドラを追加することができます。
org.apache.axis.client.Stub クラスには2つの setHeader API があります。1つめは、名前空間、名前、ヘッダの値を引数に取ります。
setHeader(String namespace, String partName, Object headerValue)
2つめは、SOAPHeaderElement を引数に取ります。
setHeader(SOAPHeaderElement header)
ここに1つめの API を使った例を挙げます。
FooServiceLocator loc = new FooServiceLocator();
FooService binding = loc.getFooService();
org.apache.axis.client.Stub s = (Stub) binding;
s.setHeader("http://my.name.space/headers", "mysecurityheader", "This guy is OK");
result = binding.myOperation(...);
質問: FooService クラス (一般的には WSDL2Java によって生成される) がすでに org.apache.axis.client.Stub クラスを拡張しているのに、どうして (上記のコードに出てくる) "binding" 変数は Stub にキャストする必要があるのか説明してください。
回答: getFooService() はスタブを FooService オブジェクトとして返しますが、それはサービスの操作しか含んでいないインターフェースだからです。これを Stub オブジェクトにキャストすることで、JAX-RPC と Axis Stub API にアクセスすることができます。
質問: WSDL2Java スタブを使用する際に、どのようにしてレスポンスヘッダを受け取りますか?
回答: Axis Stub オブジェクトの中で getResponseHeader() API を使用します。
SOAPHeaderElement getResponseHeader(String namespace, String partName)
あるいはヘッダの完全なリストを受け取ります。
SOAPHeaderElement[] getResponseHeaders()
ここに、myOperation() から返ってきたヘッダを取得するコードの断片をのせます。
FooServiceLocator loc = new FooServiceLocator();
FooService binding = loc.getFooService();
// ヘッダを返すWebサービス操作を呼びます
result = binding.myOperation(...);
org.apache.axis.client.Stub s = (Stub) binding;
s.getResponseHeader("http://my.name.space/headers", "mysecurityheader");
質問: Stub オブジェクトの中で getHeader() API は何をしますか? なぜレスポンスヘッダを返さないのですか?
回答: これらの API は、操作リクエストの中で送られる/送られた Stub/Call? の中にあるヘッダを返します。これは Axis 1.1 で変更され、Stub からヘッダを取得する方法がなくなったのですが (依然として Call オブジェクトから取得することはできました)、この問題を解決するために 1.1 以降では getResponseHeader API が追加されました。
質問: Axis 1.1 を使用している場合、どのようにしてレスポンスヘッダを受け取ればいいのでしょうか?
回答: Service オブジェクトから利用可能な Call オブジェクトを使用して SOAPEnvelope を取得してください。このオブジェクトには多くのヘッダ関数があります。あるいは、SOAPEnvelope に対して getHeader() を呼び出すことで JAX-RPC の javax.xml.soap.SOAPHeader オブジェクトを取得することができます。SOAPEnvelope クラスは一般的に Iterator を返すので、ヘッダを自分で列挙する必要があります。
ここに SOAPEnvelope に対して Axis API を使用する方法の例を挙げます。
FooServiceLocator loc = new FooServiceLocator();
FooService binding = loc.getFooService();
// ヘッダを返すWebサービス操作を呼びます
result = binding.myOperation(...);
Call lastCall = ((org.apache.axis.client.Service)service).getCall();
org.apache.axis.message.SOAPEnvelope env = lastCall.getResponseMessage().getSOAPEnvelope;
SOAPHeaderElement h = env.getHeaderByName(("http://my.name.space/headers", "mysecurityheader");
[自分のWebサービスのコードの中で、どのようにしてヘッダを取得/設定するのですか?] [編集日時 2004年1月16日am8:36 版]
質問: 自分のWebサービスのコードの中で、どのようにしてヘッダを取得/設定するのですか?
回答: MessageContext オブジェクトを使用します。
ここにいくつかのサンプルコードを挙げます
// 現在の MessageContext を取得します
MessageContext ctx = org.apache.axis.MessageContext.getCurrentContext();
// リクエストの SOAP エンベロープを取得します
SOAPEnvelope env = ctx.getRequestMessage().getSOAPEnvelope();
// ヘッダを取得します
SOAPHeaderElement soapHeaderElement = env.getHeaderByName(headerNamespace, headerName);
// ヘッダの値を取得します。複雑な型である可能性もあります
Object value = soapHeaderElement.getObjectValue();
質問: クライアントへのレスポンスの中にどのようにしてヘッダを設定するのですか?
回答: SOAPHeaderElement を作成し、レスポンスメッセージの SOAPEnvelope に追加します。
// 現在の MessageContext を取得します
MessageContext ctx = org.apache.axis.MessageContext.getCurrentContext();
// リクエストの SOAP エンベロープを取得します
SOAPEnvelope env = ctx.getResponseMessage().getSOAPEnvelope();
// SOAP ヘッダオブジェクトを作成します
SOAPHeaderElement headerElement =
new org.apache.axis.message.SOAPHeaderElement(headerNamespace, headerName, headerValue);
headerElement.setMustUnderstand(mustUnderstand);
// ヘッダを設定します
env.addHeader(headerElement);