见: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了.
