JAVA使用XFire开发和调用Web Service的方法
最近项目中需要实现Word转换为PDF、PDF合并、添加水印等功能,因在SAP中很难实现这样的功能,所以考虑使用JAVA实现这些功能,并在SAP端通过Web Service方式调用。网上查了一些使用XFire开发和调用Web Service的方法,Ctrl + C, Ctrl + V的比较多,现在功能已经实现,为便于以后遇到相同问题提供参考,也是对最近工作的一个总结,因此,写这篇文章做个总结。
本人所使用的开发环境如下:MyEclipse 6.0.1; apache-tomcat 6.0.26; XFire(MyEclipse 6.0.1自带); xfire-1.2.4(调用所需要的相关JAR包)。
一、服务器端开发:
1、创建工程
File->New->Web Service Project;输入工程名,根据向导按默认即可创建一个Web Service工程。
创建完成后,除生成web.xml文件外,还自动生成了一个services.xml;web.xml的内容不需要做修改,但services.xml文件的内容需要修改,后面做介绍。Web.xml文件的内容如下:
<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns="http://java.sun.com/xml/ns/j2ee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" version="2.4" xsi:schemaLocation="http://java.sun.com/xml/ns/j2ee http://java.sun.com/xml/ns/j2ee/web-app_2_4.xsd">
<servlet>
<servlet-name>XFireServlet</servlet-name>
<servlet-class>org.codehaus.xfire.transport.http.XFireConfigurableServlet</servlet-class>
<load-on-startup>0</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>XFireServlet</servlet-name>
<url-pattern>/services/*</url-pattern>
</servlet-mapping>
<welcome-file-list>
<welcome-file>index.jsp</welcome-file>
</welcome-file-list>
</web-app>
2、创建Web Service的接口和实现类
这个步骤可以通过手工创建接口和实现类,也可以通过工具条上的“New Web Service”按钮来自动生成。我是通过手工创建接口和实现类的。
首先,创建一个包“ws”;在该包中创建一个接口“IDoc2PdfWebService”,并定义接口的方法;如下:
package ws;
public interface IDoc2PdfWebService {
/**
* word格式转换为pdf格式并返回结果
* @param fileType word格式的文件后缀 DOC DOCX
* @param fileBytes word格式的文件字节流
* @return PDF格式的文件字节流
*/
public byte[] DocToPdf(String fileType, byte[] docFileBytes);
/**
* 2个PDF文件合并成一个PDF文件并返回结果
* @param pdfFileBytes1 PDF源文件1的文件字节流
* @param pdfFileBytes2 PDF源文件2的文件字节流
* @return 合成的PDF格式的文件字节流
*/
public byte[] PdfMerge(byte[] pdfFileBytes1,byte[] pdfFileBytes2);
}
然后在同个包下创建一个实现该接口的类“Doc2PdfWebServiceImpl”,并实现接口中的方法;如下:
package ws;
public class Doc2PdfWebServiceImpl implements IDoc2PdfWebService {
public byte[] DocToPdf(String fileType, byte[] docFileBytes) {
……
}
public byte[] PdfMerge(byte[] pdfFileBytes1,byte[] pdfFileBytes2) {
……
}
3、配置services.xml文件
下面很重要的一步就是配置services.xml文件;其中<name>节点后面Web Service的发布地址中所使用;<serviceClass>节点为上面步骤创建的接口,格式为包名.接口名;<implementationClass>节点为接口的实现,格式为包名.实现类名;其它默认即可。如下代码所示:
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://xfire.codehaus.org/config/1.0">
<service>
<name>Doc2PdfWebService</name>
<serviceClass>ws.IDoc2PdfWebService</serviceClass>
<implementationClass>
ws.Doc2PdfWebServiceImpl
</implementationClass>
<style>wrapped</style>
<use>literal</use>
<scope>application</scope>
</service></beans>
4、测试服务
这样服务器端的开发已经完成;在浏览器上输入如下地址:
http://localhost:8080/工程名/services/Doc2PdfWebService?wsdl(其中services是在web.xml文件中<url-pattern>节点配置的,而Doc2PdfWebService是在services.xml文件的<name>节点配置的)。如果显示如下的信息则说明服务器端Web Service发布成功。
二、客户端开发:
服务器端Web Service发布成功后,可以通过开发一个客户端程序来调用。
1、新建工程
新建一个java工程;
2、导入所需jar包
首先需要下载XFire,然后导入以下包到工程中:commons-codec-1.3.jar、commons-httpclient-3.0.jar、commons-logging-1.0.4.jar、jdom-1.0.jar、stax-api-1.0.1.jar、wsdl4j-1.6.1.jar、wstx-asl-3.2.0.jar、xfire-all-1.24.jar。
3、新建接口及测试类
新建包“com.demo.client”;将第一步中创建的接口类“IDoc2PdfWebService”复制到该包中,并新建一个测试类“WSTest”,具体实现代码见后。其中 serviceURL的地址即为第一步中测试服务所用的地址,但需要去年“?wsdl”后缀,否则会抛异常。
import org.codehaus.xfire.XFireFactory;
import org.codehaus.xfire.client.XFireProxyFactory;
import org.codehaus.xfire.XFire;
import org.codehaus.xfire.service.Service;
import org.codehaus.xfire.service.binding.ObjectServiceFactory;
public class WSTest{
public static void main(String[] args){
// 创建服务模型,即服务的元数据,使用XFire的ObjectServiceFactory从的服务的接口(IWebServiceTest,
// 首先需要在同一个包下创建所调用的Web Service的接口类)创建;
Service service = new ObjectServiceFactory().create(IWebServiceTest.class);
// 为XFire获得一个代理工厂对象
XFire xfire = XFireFactory.newInstance().getXFire();
XFireProxyFactory factory =new XFireProxyFactory(xfire);
String serviceURL =
"http://localhost:8080/ PdfWebService/services/Doc2PdfWebService ";
IWebServiceTest client = null;
try{
// 使用服务模型和服务端点URL(用来获得WSDL),就可以得到一个服务的本地代理,即实际的客户端
client = (IDoc2PdfWebService)factory.create(service, serviceURL);
}catch(Exception ex){
ex.printStackTrace();
}
File myFilePath = new File("d:/DocToPdf/test.docx");
InputStream in = new FileInputStream(myFilePath);
// 取得文件大小
long length = myFilePath.length();
// 根据大小创建字节数组
byte[] bytes = new byte[(int) length];
int offset = 0;
int numRead = 0;
while (offset < bytes.length &&
(numRead = in.read(bytes, offset, bytes.length - offset)) >= 0){
offset += numRead;
}
in.close(); try{
// 通过客户端调用它的DocToPdf方法来得到我们需要的Web Service
byte[] pdfData = client.DocToPdf("DOCX", bytes);
String pdfFileName = "d:/DocToPdf/test.pdf";
File pdfFilePath = new File(pdfFileName);
try {
if (pdfFilePath.exists()) {
pdfFilePath.delete();
}
} catch (Exception e) {
System.out.println("删除文件操作出错");
e.printStackTrace();
}
FileOutputStream out = new FileOutputStream(pdfFileName);
out.write(pdfData);
out.flush();
out.close();
}
}