- PR -

AXIS DIMEによる添付ファイルの送信

投稿者投稿内容
タカチ
会議室デビュー日: 2004/08/04
投稿数: 12
投稿日時: 2004-08-09 23:38
お世話になります。
現在、SOAPでDIMEによる添付ファイルの送信テスト行っているのですが、
うまくいかず悩んでいます。

作成したテストモジュールを実行すると書きのエラーが出てしまいます。

##### エラー ######
- Mapping Exception to AxisFault
AxisFault
faultCode: {http://xml.apache.org/axis/}Server.userException
faultString: org.xml.sax.SAXException: No such operation 'PutData'
faultActor: null
faultDetail:

本エラーにつきまして、どなたかご存知な方いらっしゃいましたら
アドバイスを頂けないでしょうか。
また、DIMEによる添付ファイルの送信(受信)につきまして
よいサンプル等ありましたら、ご紹介頂けないでしょうか。
宜しくお願いいたします。

以下、環境とソースです。

クライアント:Apache Axis
サーバ:Apache Axis
OS:Windows XP

以下、ソースです。

##### サーバ側 ######
import java.io.FileOutputStream;
import java.io.IOException;
import javax.xml.soap.SOAPException;
import org.apache.axis.Message;
import org.apache.axis.MessageContext;
import org.apache.axis.attachments.AttachmentPart;

public class DimeService {
public String PutData(String originalName) throws SOAPException {
try {
MessageContext ctx = MessageContext.getCurrentContext();
Message msg = ctx.getRequestMessage();
AttachmentPart part = (AttachmentPart)msg.getAttachments().next();

FileOutputStream fs = new FileOutputStream("C:\\files\\" + originalName);
part.getDataHandler().writeTo(fs);
fs.close();

return "OK";
} catch (IOException ioex) {
ioex.printStackTrace();
throw new SOAPException("error", ioex);
}
}
}

##### クライアント側 ######
import org.apache.axis.client.Call;
import org.apache.axis.client.Service;
import org.apache.axis.encoding.ser.JAFDataHandlerDeserializerFactory;
import org.apache.axis.encoding.ser.JAFDataHandlerSerializerFactory;
import javax.activation.DataHandler;
import javax.activation.FileDataSource;
import javax.xml.rpc.ParameterMode;
import javax.xml.namespace.QName;
import java.net.URL;

public class DimeClientTest {

public static void main(String[] args) throws Exception {

String fileName = args[0];
DataHandler dhSource = new DataHandler(new FileDataSource(fileName));
Service service = new Service();

Call call = (Call)service.createCall();

call.setTargetEndpointAddress(new URL(args[1]));

call.setOperationStyle("wrapped");

call.setOperationName(new QName("DimeService", "PutData"));
// call.setReturnQName(new QName("http://tempuri.org/", "PutDataResult"));
call.setReturnType(new QName("http://www.w3.org/2001/XMLSchema", "string"), String.class);
call.setUseSOAPAction(true);
// call.setSOAPActionURI("http://tempuri.org/PutData");
call.setEncodingStyle(null);
call.setScopedProperty(org.apache.axis.client.Call.SEND_TYPE_ATTR, Boolean.FALSE);
call.setScopedProperty( org.apache.axis.AxisEngine.PROP_DOMULTIREFS, Boolean.FALSE);

QName att = new QName("DimeService", "DataHandler");

call.registerTypeMapping(dhSource.getClass(),
att, JAFDataHandlerSerializerFactory.class,
JAFDataHandlerDeserializerFactory.class);

call.addParameter(new QName("http://tempuri.org/", "originalName"),
new QName("http://www.w3.org/2001/XMLSchema", "string"),
String.class, ParameterMode.IN);

call.addParameter("data", att, ParameterMode.IN);

call.setProperty(Call.ATTACHMENT_ENCAPSULATION_FORMAT,
Call.ATTACHMENT_ENCAPSULATION_FORMAT_DIME);

Object ret = call.invoke(new Object[]
{ new java.io.File(fileName).getName(), dhSource } );
}
}

##### WSDDファイル ######
<deployment xmlns="http://xml.apache.org/axis/wsdd/"
xmlns:java="http://xml.apache.org/axis/wsdd/providers/java">
<service name="urn:DimeService" provider="java:RPC">
<parameter name="className" value="server.api.DimeService"/>
<parameter name="allowedMethods" value="*"/>
</service>
</deployment>


上記のソースをコンパイルして、

java DimeClientTest <ファイルパス> http://localhost:8080/axis/services/urn%3ADimeService
kan
ベテラン
会議室デビュー日: 2002/11/28
投稿数: 55
投稿日時: 2004-08-10 01:56
サーバ側でもDataHandlerを引数として受けるようにしてみてはどうでしょう?
WSDDにTypeMappingの設定も必要になります。

クライアント側でDataHandlerを使っているので、SOAPのパラメータとして
DataHandlerが追加されます。しかし、サーバ側にはDataHandlerのパラメータが
ないため、引数が合わず、そんなメソッドはないと言われているのかと思います。

DIMEのサンプルは、普通?のAttachmentのサンプルにDIMEのプロパティ設定を
加えるだけかと思います。
タカチ
会議室デビュー日: 2004/08/04
投稿数: 12
投稿日時: 2004-08-10 10:00
お世話になります。
kanさん、ご返信ありがとうございます。

>サーバ側でもDataHandlerを引数として受けるようにしてみてはどうでしょう?
>WSDDにTypeMappingの設定も必要になります。
⇒サーバ側のパラメータにDataHandlerを含めた場合、.NETとの相互運用という
 部分ではどうなのでしょうか?

 DataHandlerはJAVAに特化した型であり、そのような型をサーバのパラメータ
 に含めてしまうと.NETでクライアントが組めなくなるような気がします。
 (↑勘違い?)

 また、実はパラメータにDataHandlerを含めた場合のテストは既に済んでおり、
 正常に添付ファイルを送受信できることを確認しました。
 そこで、今回はあえて含まない方法を検証していました。
 もしかして、そんな事は不可能?なのでしょうか・・・。
kan
ベテラン
会議室デビュー日: 2002/11/28
投稿数: 55
投稿日時: 2004-08-11 09:13
私は.NETでAttachmentをやったことがないので、分からないのですが、
以下を見ると、.NETとは問題なく繋がりそうな気がします。
http://www.atmarkit.co.jp/fdotnet/special/wse04/wse04_04.html

JAX-RPCではなく、Message-StyleのAPIを使って、document/literalで
実装したらどうでしょう?
タカチ
会議室デビュー日: 2004/08/04
投稿数: 12
投稿日時: 2004-08-11 16:09
お世話になります。
ご返信ありがとうございます。

>JAX-RPCではなく、Message-StyleのAPIを使って、document/literalで
>実装したらどうでしょう?
⇒恥ずかしながら「Message-Style」に関してはあまり知識がありません。
  もう少し調べてみます。(*^.^*)

現状目指すところは.NETなど、他言語との相互運用と、WSDLからクライアント
プログラムの自動生成なので、流動的な技術であるAttachmentではなく、
Binary[](Bese64)で送受信ることも視野に入れています。
もちろんAttachmentについても同時に調査を進めていきたいと思っています。

また結果を報告させていただきます。


タカチ
会議室デビュー日: 2004/08/04
投稿数: 12
投稿日時: 2004-08-12 14:34
byte配列でファイルを送受信する方法を試してみました。
WSDLからクライアントプログラムの自動生成が簡単にできたので
「これはいいぞ!」と思ったのですが・・・

4Mのファイルまでは送受信できるのですが、5MになるとSOAPサーバ側の OutOfMemoryError で落ちてしまいました・・・。

そこで、TomcatのVMヒープメモリを256Mに増設したら10Mのファイルを送れるように
なりました。
しかし、5クライアントから同時にアクセスしたら、5クライアント中
3クライアントがやはり OutOfMemoryError で落ちました。ヒープメモリ
のチューニングは根本的な対策にはなりませんね。

結局ファイル添付には Attachment しかないということの確認になって
しまいました。

とほほ・・・
kan
ベテラン
会議室デビュー日: 2002/11/28
投稿数: 55
投稿日時: 2004-08-12 23:37
AttachmentPart ap = new AttachmentPart(new DataHandler(new FileDataSource(args[0])));
ap.setContentType("image");
call.addAttachmentPart(ap);

RPC-Styleでは試してないのですが、この方法はどうでしょう?
これだとDataHandlerがパラメータにならないかも、
タカチ
会議室デビュー日: 2004/08/04
投稿数: 12
投稿日時: 2004-08-16 22:03
お世話になります。
kanさん、ご返信ありがとうございます。

試してみます!
結果をまた報告させて頂きます。

スキルアップ/キャリアアップ(JOB@IT)