32.2.4 ストリーミングされた添付ファイルの操作
ストリーミングを使用しているときに添付ファイルを含むMIME Multipart/Related構造のSOAPメッセージを受信すると,JAX-WSでは受信した添付ファイルをjavax.activation.DataHandlerクラスではなく,com.sun.xml.ws.developer.StreamingDataHandlerクラスにマッピングし,ストリーミングされた添付ファイルとして操作できます。
com.sun.xml.ws.developer.StreamingDataHandlerクラスについては,「19.2.4(2) com.sun.xml.ws.developer.StreamingDataHandlerクラス」を参照してください。
ストリーミングされた添付ファイルを操作する例を次に示します。この例では,ストリーミングされた添付ファイルを"C:/portrait.png"として別名で出力します。
package com.sample; ・・・・・・ @MTOM @StreamingAttachment(dir="C:/TMP", parseEagerly=true, memoryThreshold=50000L) @BindingType(・・・) public class UserInfoImpl implements UserInfo { public DataHandler getUserInfo(DataHandler dataHandler) throws UserDefinedException { if (dataHandler instanceof StreamingDataHandler) { File file = new File("C:/portrait.png"); StreamingDataHandler sdh = null; try { sdh = (StreamingDataHandler)dataHandler; sdh.moveTo(file); ・・・・・・ } finally { try { if (sdh != null) { sdh.close(); } } catch(Exception ex) { ・・・・・・ } } } } }
- 〈この項の構成〉
(1) ストリーミングされた添付ファイルの操作時の注意事項
ストリーミングされた添付ファイルを操作する場合の注意事項を次に示します。
-
ストリーミングを使用する場合,instanceof演算子を用いてcom.sun.xml.ws.developer.StreamingDataHandlerクラスを判別する必要があります。
-
一時ファイルに出力した添付ファイルは使用有無に関係なく,必ずcom.sun.xml.ws.developer.StreamingDataHandler#close()メソッドでクローズする必要があります。クローズしない場合,JAX-WSは一時ファイルを消去しません。
-
com.sun.xml.ws.developer.StreamingDataHandler#readOnce()メソッドおよびcom.sun.xml.ws.developer.StreamingDataHandler#moveTo(File)メソッドを呼び出したあとは,com.sun.xml.ws.developer.StreamingDataHandler#close()メソッドだけ呼び出すことができます。com.sun.xml.ws.developer.StreamingDataHandler#close()メソッド以外のメソッドを呼び出した場合,動作は保証されません。
-
com.sun.xml.ws.developer.StreamingDataHandler#readOnce()メソッドを呼び出した場合,添付ファイルが必要なくなった時点で取得した入力ストリームからデータをすべて読み読み込んだあとに入力ストリームをクローズし,com.sun.xml.ws.developer.StreamingDataHandler#close()メソッドを呼び出す必要があります。
com.sun.xml.ws.developer.StreamingDataHandler#readOnce()メソッドを呼び出した場合の例を次に示します。
package com.sample; ... @MTOM @StreamingAttachment(...) ... public class UserInfoImpl implements UserInfo { public @XmlMimeType("application/octet-stream") DataHandler getUserInfo( @XmlMimeType("application/octet-stream") DataHandler dataHandler) throws ... { if (dataHandler instanceof StreamingDataHandler) { StreamingDataHandler sdh = null; try { sdh = (StreamingDataHandler)dataHandler; ... InputStream inputStream = sdh.readOnce(); ... // 入力ストリームから添付ファイルのデータをすべて // 読み込む while ((inputStream.read()) != -1); // 入力ストリームをクローズする inputStream.close(); } finally { try { if (sdh != null) { // StreamingDataHandlerクラスのclose() // メソッドを呼び出す sdh.close(); } } catch(Exception ex) { ... } } } ... } }
-
com.sun.xml.ws.developer.StreamingDataHandler#moveTo(File)メソッドを呼び出した場合,添付ファイルが必要なくなった時点でcom.sun.xml.ws.developer.StreamingDataHandler#close()メソッドを呼び出す必要があります。
-
com.sun.xml.ws.developer.StreamingDataHandler#moveTo(File)メソッドを呼び出したときに例外が発生した場合,com.sun.xml.ws.developer.StreamingDataHandler#readOnce()メソッドを呼び出して入力ストリームを取得し,その入力ストリームからデータをすべて読み込んだあとに入力ストリームのクローズを行い,com.sun.xml.ws.developer.StreamingDataHandler#close()メソッドを呼び出す必要があります。
com.sun.xml.ws.developer.StreamingDataHandler#moveTo(File)メソッドを呼び出した場合の例を次に示します。
package com.sample; ... @MTOM @StreamingAttachment(...) ... public class UserInfoImpl implements UserInfo { public @XmlMimeType("application/octet-stream") DataHandler getUserInfo( @XmlMimeType("application/octet-stream") DataHandler dataHandler) throws ... { if (dataHandler instanceof StreamingDataHandler) { StreamingDataHandler sdh = null; try { File file = new File(...); sdh = (StreamingDataHandler)dataHandler; ... sdh.moveTo(file); } catch(Exception e) try { if (sdh != null) { InputStream inputStream = sdh.readOnce(); // 入力ストリームから添付ファイルのデータをすべて // 読み込む while ((inputStream.read()) != -1); // 入力ストリームをクローズする inputStream.close(); } } catch(Exception ex) { ... } } finally { try { if (sdh != null) { // StreamingDataHandlerクラスのclose() // メソッドを呼び出す sdh.close(); } } catch(Exception ex) { ... } } } ... } }
-
com.sun.xml.ws.developer.StreamingDataHandler#readOnce()メソッドを呼び出していない,かつcom.sun.xml.ws.developer.StreamingDataHandler#moveTo(File)メソッドを呼び出していない場合,添付ファイルが必要なくなった時点でcom.sun.xml.ws.developer.StreamingDataHandler#readOnce()メソッドを呼び出して入力ストリームを取得し,その入力ストリームからデータをすべて読み込んだあとに入力ストリームをクローズし,com.sun.xml.ws.developer.StreamingDataHandler#close()メソッドを呼び出す必要があります。
-
com.sun.xml.ws.developer.StreamingDataHandlerクラスはjavax.activation.DataHandlerクラスのメソッドのうち,getContentType()メソッドだけ呼び出すことができます。それ以外のメソッドを呼び出した場合,動作は保証されません。
-
WebサービスクライアントまたはWebサービス実装クラスで,受信したjavax.activation.DataHandlerクラスまたはjavax.xml.ws.Holder <DataHandler>クラスのストリーミングされた添付ファイルをそのまま使用して送信しないでください。送信する場合,新たにjavax.activation.DataHandlerオブジェクトを生成して送信してください。