见:http://www.cnblogs.com/hoojo/archive/2010/12/20/1911385.html
WebService处理传递普通的信息,还可以传输文件,下面介绍WebService是怎么完成文件传输的。
1、 首先编写服务器端上传文件的WebService方法
package com.hoo.service; import java.io.File; import java.io.FileNotFoundException; import java.io.FileOutputStream; import java.io.InputStream; import javax.activation.DataHandler; /** * <b>function:</b>Axis WebService完成文件上传服务器端 * @author hoojo * @createDate Dec 18, 2010 1:16:16 PM * @file UploadFileService.java * @package com.hoo.service * @project AxisWebService * @blog http://blog.csdn.net/IBM_hoojo * @email hoojo_@126.com * @version 1.0 */ public class UploadFileService { /** * <b>function:</b>传递文件 * @author hoojo * @createDate Dec 18, 2010 1:27:58 PM * @param handler DataHandler这个参数必须 * @param fileName 文件名称 * @return upload Info */ public String upload(DataHandler handler, String fileName) { if (fileName != null && ! "" .equals(fileName)) { File file = new File(fileName); if (handler != null ) { InputStream is = null ; FileOutputStream fos = null ; try { is = handler.getInputStream(); fos = new FileOutputStream(file); byte [] buff = new byte [ 1024 * 8 ]; int len = 0 ; while ((len = is.read(buff)) > 0 ) { fos.write(buff, 0 , len); } } catch (FileNotFoundException e) { return " fileNotFound " ; } catch (Exception e) { return " upload File failure " ; } finally { try { if (fos != null ) { fos.flush(); fos.close(); } if (is != null ) { is.close(); } } catch (Exception e) { e.printStackTrace(); } } return " file absolute path: " + file.getAbsolutePath(); } else { return " handler is null " ; } } else { return " fileName is null " ; } } }
上传方法和我们以前在Web中上传唯一不同的就是参数一DataHandler,可以将这类看成文件传输器,他可以把文件序列化。然后通过DataHandler可以得到一个输入流InputStream,通过这个流可以读到文件的内容。其他的操作和普通上传类似。
2、 定制wsdd发布文件上传的WebService服务
<? xml version="1.0" encoding="UTF-8" ?> < deployment xmlns ="http://xml.apache.org/axis/wsdd/" xmlns:java ="http://xml.apache.org/axis/wsdd/providers/java" > < service name ="UploadFile" provider ="java:RPC" > < parameter name ="className" value ="com.hoo.service.UploadFileService" /> < parameter name ="allowedMethods" value ="*" /> < parameter name ="scope" value ="Session" /> <!-- 和服务器端上传文件的方法签名对应,参数也对应 --> < operation name ="upload" qname ="operNS:upload" xmlns:operNS ="upload" returnType ="rns:string" xmlns:rns ="http://www.w3.org/2001/XMLSchema" > < parameter name ="handler" type ="ns:DataHandler" xmlns:ns ="http://www.w3.org/2001/XMLSchema" /> < parameter name ="fileName" type ="ns:string" xmlns:ns ="http://www.w3.org/2001/XMLSchema" /> </ operation > < typeMapping qname ="hns:DataHandler" xmlns:hns ="ns:FileUploadHandler" languageSpecificType ="java:javax.activation.DataHandler" serializer ="org.apache.axis.encoding.ser.JAFDataHandlerSerializerFactory" deserializer ="org.apache.axis.encoding.ser.JAFDataHandlerDeserializerFactory" encodingStyle ="http://schemas.xmlsoap.org/soap/encoding/" /> </ service > </ deployment >
上面才xml节点元素在前面都见过了,说明下operation中的参数,注意要指定参数类型,特别是DataHandler的类型,然后就是typeMapping的serializer、deserializer的序列化和反序列化工厂类的配置。
3、 用dos命令发布当前WebService
C:\SoftWare\tomcat-5.0.28\tomcat-5.0.28\webapps\AxisWebService\WEB-INF>java -Djava.ext.dirs=lib org.apache.axis.client.AdminClient -lhttp://localhost:8080/AxisWebService/services/AdminService deployUpload.wsdd
发布完成后,可以通过这个地址查看uploadFile这个service了
http://localhost:8080/AxisWebService/servlet/AxisServlet
4、 编写客户端代码
package com.hoo.client; import java.rmi.RemoteException; import javax.activation.DataHandler; import javax.activation.FileDataSource; import javax.xml.namespace.QName; import javax.xml.rpc.ParameterMode; import javax.xml.rpc.ServiceException; import org.apache.axis.client.Call; import org.apache.axis.client.Service; import org.apache.axis.encoding.XMLType; import org.apache.axis.encoding.ser.JAFDataHandlerDeserializerFactory; import org.apache.axis.encoding.ser.JAFDataHandlerSerializerFactory; /** * <b>function:</b>上传文件WebService客户端 * * @author hoojo * @createDate Dec 18, 2010 1:38:14 PM * @file UploadFileClient.java * @package com.hoo.client * @project AxisWebService * @blog http://blog.csdn.net/IBM_hoojo * @email hoojo_@126.com * @version 1.0 */ public class UploadFileClient { public static void main(String[] args) throws ServiceException, RemoteException { String url = " http://localhost:8080/AxisWebService/services/UploadFile " ; String fileName = " readMe.txt " ; String path = System.getProperty( " user.dir " ) + " \\WebRoot\\ " + fileName; System.out.println(path); // 这样就相当于构造了一个带文件路径的File了 DataHandler handler = new DataHandler( new FileDataSource(path)); Service service = new Service(); Call call = (Call) service.createCall(); call.setTargetEndpointAddress(url); /** * 注册异常类信息和序列化类 ns:FileUploadHandler 和 wsdd 配置文件中的typeMapping中的xmlns:hns="ns:FileUploadHandler" 的对应 DataHandler * 和 wsdd 配置文件中的typeMapping中的qname="hns:DataHandler"的DataHandler对应 */ QName qn = new QName( " ns:FileUploadHandler " , " DataHandler " ); call.registerTypeMapping(DataHandler. class , qn, JAFDataHandlerSerializerFactory. class , JAFDataHandlerDeserializerFactory. class ); call.setOperationName( new QName(url, " upload " )); // 设置方法形参,注意的是参数1的type的DataHandler类型的,和上面的qn的类型是一样的 call.addParameter( " handler " , qn, ParameterMode.IN); call.addParameter( " fileName " , XMLType.XSD_STRING, ParameterMode.IN); // 设置返回值类型,下面2种方法都可以 call.setReturnClass(String. class ); // call.setReturnType(XMLType.XSD_STRING); String result = (String) call.invoke( new Object[] { handler, " remote_server_readMe.txt " }); System.out.println(result); } }
至此,文件传输就完成了。怎么样,还不错吧!
如果你用myEclipse进行开发的话,运行时可能会出现以下的错误:
Exception in thread "main" java.lang.NoClassDefFoundError: com/sun/mail/util/LineInputStream
原因是jar包版本不统一,解决方法如下:
删除Java EE 5 Libraries/javaee.jar/mail里的包有东西.
具体方法如下:
用rar打开X:/Program Files/MyEclipse 6.0/myeclipse/eclipse/plugins/com.genuitec.eclipse.j2eedt.core_6.0.1.zmyeclipse601200710/data/libraryset/EE_5/javaee.jar,然后删除mail,一切就ok了.