1.为了使其对DataHandler的支持。除了配置好axis环境之外,还要在sun的网站上下载jaf 1-0-2.jar包,并把它注册到CLASS_PATH中。
2.编写服务程序(.java),既支持文本文件,也支持二进制文件。
package test.gaolong;
import java.io.*;
import javax.activation.*;
public class FileService{
public static String Repository="./files/";
public String putFile(DataHandler dh,String name){
if(name==null)
name="test.tmp";
System.out.println("test");
try{
File dir=new File(Repository);
if(!dir.exists()){
dir.mkdir(); System.out.println("makedir"+"test");
}
InputStream input=dh.getInputStream();
FileOutputStream fos=new FileOutputStream(new File(dir,name));
System.out.println("test");
byte[] buffer=new byte[1024*4];
int n=0;
while((n=input.read(buffer))!=-1){
fos.write(buffer,0,n);
System.out.println(buffer);
}
System.out.println("test");
input.close();
fos.close();
}catch(IOException e){
e.printStackTrace();
}
return name+"send OK";
}
public DataHandler getFile(String name){
File dir=new File(Repository);
if(!dir.exists())
dir.mkdir();
File data=new File(dir,name);
if(data.exists())
return new DataHandler(new FileDataSource(data));
else
return null;
}
}
3。写deploy.wsdd部署描述文件如下:
<deployment xmlns="http://xml.apache.org/axis/wsdd/" xmlns:java="http://xml.apache.org/axis/wsdd/providers/java" xmlns:ns1="http://localhost:7001/axis/services/FileService" >
<service name="FileService" provider="java:RPC">
<parameter name="className" value="test.gaolong.FileService"/>
<parameter name="allowedMethods" value="*"/>
<parameter name="allowedRoles" value="user"/>
<operation name="getFile" returnQName="returnqname" returnType="ns1:DataHandler" xmlns:SchemaNS="http://www.w3.org/2001/XMlSchema">
<parameter name="name" type="SchemaNS:string"/>
</operation>
<operation name="putFile" returnQName="returnqname" returnType="ns1:DataHandler" xmlns:SchemaNS="http://www.w3.org/2001/XMlSchema">
<parameter name="dh" type="ns1:DataHandler"/>
<parameter name="name" type="SchemaNS:string"/>
</operation>
<typeMapping deserializer="org.apache.axis.encoding.ser.JAFDataHandlerDeserializerFactory" type="java:javax.activation.DataHandler" qname="ns1:DataHandler" serializer="org.apache.axis.encoding.ser.JAFDataHandlerSerializerFactory" encodingStyle="http://schemas.xmlsoap.org/soap/encoding/"/>//注意见下面的。
</service>
</deployment>
注:对于soap1.2而言,要使用上面的<typeMaping>,而对于soap1.1而言,则有一点区别如下:
<typeMapping deserializer="org.apache.axis.encoding.ser.JAFDataHandlerDeserializerFactory" lanuageSpecificType="java:javax.activation.DataHandler" qname="ns1:DataHandler" serializer="org.apache.axis.encoding.ser.JAFDataHandlerSerializerFactory" encodingStyle="http://schemas.xmlsoap.org/soap/encoding/"/>
4。启动服务器,用java org.apache.axis.client.AdminClient -p 7001 deploy.wsdd部署webservices即可访问。
5。编写客户端应用访问程序如下:
import javax.xml.rpc.ParameterMode;
import org.apache.axis.client.Call;
import org.apache.axis.client.Service;
import org.apache.axis.encoding.XMLType;
import javax.xml.namespace.QName;
import org.apache.axis.soap.SOAP11Constants;
import java.net.URL;
import javax.activation.DataHandler;
import javax.activation.FileDataSource;
import org.apache.axis.encoding.ser.*;
public class ServiceClient{
public static void main(String[] args) throws Exception{
String filename="HelloWorld.java";
DataHandler dh=new DataHandler(new FileDataSource(filename));
String endpoint="http://127.0.0.1:7003/axis/services/FileService";
String name="gaolong1";
Service service=new Service();
Call call=(Call) service.createCall();
call.setTargetEndpointAddress(new java.net.URL(endpoint));
call.setOperationName(new QName("http://127.0.0.1:7001/axis/services/FileService", "putFile"));//指定方法的命名空间
QName qnameattachment=new QName("FileService","DataHandler");
call.registerTypeMapping(dh.getClass(),qnameattachment,JAFDataHandlerSerializerFactory.class,JAFDataHandlerDeserializerFactory.class);
call.addParameter("s1",qnameattachment,ParameterMode.IN);
call.addParameter("s2",XMLType.XSD_STRING,ParameterMode.IN);
call.setReturnType(XMLType.XSD_STRING);//XMLType.XSD_STRING);//用Class.forName("java.lang.String")来获取java类型
String ret=(String)call.invoke(new Object[] {dh,"HelloWorld.java"});
System.out.println(ret);
}
}
6。成功执行客户端应用程序,可以找到上传文件。
请求的soap消息:
POST /axis/services/FileService HTTP/1.0
Content-Type: multipart/related; type="text/xml"; start="<3165C8664597DC7EF29D5BFAC8972562>"; boundary="----=_Part_0_21866740.1141202759484"
Accept: application/soap+xml, application/dime, multipart/related, text/*
User-Agent: Axis/1.2.1
Host: localhost:7003
Cache-Control: no-cache
Pragma: no-cache
SOAPAction: ""
Content-Length: 1050
------=_Part_0_21866740.1141202759484
Content-Type: text/xml; charset=UTF-8
Content-Transfer-Encoding: binary
Content-Id: <3165C8664597DC7EF29D5BFAC8972562>
<?xml version="1.0" encoding="UTF-8"?><soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"><soapenv:Body><ns1:putFile soapenv:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/" xmlns:ns1="http://127.0.0.1:7001/axis/services/FileService"><s1 href="cid:03D9C1D3A9E0788D274934C3ABD52811" _fcksavedurl=""cid:03D9C1D3A9E0788D274934C3ABD52811"" _fcksavedurl=""cid:03D9C1D3A9E0788D274934C3ABD52811"" _fcksavedurl=""cid:03D9C1D3A9E0788D274934C3ABD52811"" xsi:type="ns2:DataHandler" xmlns:ns2="FileService"/><s2 xsi:type="xsd:string">HelloWorld.java</s2></ns1:putFile></soapenv:Body></soapenv:Envelope>
------=_Part_0_21866740.1141202759484
Content-Type: application/octet-stream
Content-Transfer-Encoding: binary
Content-Id: <03D9C1D3A9E0788D274934C3ABD52811>
public class HelloWorld{
public String sayHello(String name){
return "Hello"+name;
}
}
------=_Part_0_21866740.1141202759484--
上传后的文件的位置:/*在该目录下创建文件夹:D:/bea/user_projects/domains/mydomain/files,并把相应的文件存入该目录下*/
7.另一种基于java mail的带附件的传输,是基于xmlDOM+servlet可以来实现,只是比较底层而已
作者Blog:http://blog.csdn.net/gaolongbiti/
==================================
使用 Web Services Enhancements 发送带有附件的 SOAP 消息:
http://dev.csdn.net/article/17/17956.shtm
Building Interoperable Web Services With Attachment Support Using JAXRPC 1.1.2:
https://jax-rpc.dev.java.net/whitepaper/1.1.2/attachments-howto.html
Understanding Web Services Attachments:
http://dev2dev.bea.com/pub/a/2004/05/websvcs_nottingham.html
==================================================
作为一个准则,Web服务常常按照XML格式来传递数据。它的格式很简单,但是复杂类型的数据,例如幻灯片或者一幅图片,该如何处理?现在,让我们看看如何用Apache SOAP向你的Web服务传输文件。
简单的应用:文件归档服务
在这种情况下,我的Web服务是一个归档系统,它用来在服务器上保存文件。如果作为一个简单的例子,它的作用是足够的了,但是在实际应用中,你也许需要实现某些功能如FTP。在我的例子里,我创建了一个服务类用来接收一个输入文件并把它保存到服务器上。我还创建了一个客户类可以用它来调用Web服务。
归档服务在一个名为ArchiveService的类中实现。该类只有一个称之为StoreFile的方法,该方法带有两个参数:filename和DataHandle对象。参数filename显然是被传输文件的名字,而DataHandler负责文件内容的传输。清单A给出了创建该类的ArchiveService.java文件。
当StoreFile方法被调用时,保存在DataHandler对象中的输入文件写到服务器上一个特定位置上(本例为C:wsfiles目录)。然后,向客户端发送一个消息说明服务器已经接收到该文件了。
ArchiveClient类
ArchiveClient类比文件归档服务要复杂一些,你可以从清单B中找到它的实现代码。这个类用到了常态的SOAP客户设置(setup)(基于Call对象)。主要的区别在于,我用一个DataHandler来保存文件数据。该文件的内容实际上载入到一个DataSource对象中,该DataSource对象用来建立新的DataHandler。然后,我把DataHandler作为一个参数传递到ArchiveService的StoreFile方法。
DataHandler
由于Java Activation Framework提供了对数据的串行化(serialization)和解串行化(deserialization)的功能并自动将它附加到SOAP消息中去,所以在本例中,DataHandler实现主要的功能。你的文件数据并没有直接用SOAP包装后用XML传递,而是作为对附件的一个引用。整个SOAP请求按照MIME编码方式分成多个部分来发送。第一部分为SOAP封套(envelope),第二部分为附件。基本上它们的格式是相同的,这就使得你可以在电子邮件消息中发送附件。当服务器接收到上述多部分请求时,它会自动找到引用的附件并使其可以用到SOAP服务上。
从我给出的例子中,你可以看出Apache SOAP使得发送文件到Web服务器和从Web服务器中接收文件是多么的容易。尽管我给出的例子可能没有很高的参考价值,但我仍相信你可以在其它更有趣的应用程序中轻松使用这个技术。