Eclipse下使用Apache CFX开发部署文件上传的WebService
配置和部署
该示例将展示如何配置和开发一个运行在服务器上的基于 CXF 的 Web 服务,该服务会上传客户端提交的文件。参见下列规范。
Tomcat Web 服务器 5.5 或更高版本:Tomcat servlet 引擎是一个开源包,是 Apache Software Foundation 的 Jakarta 项目的一部分。它是 servlet 和 JSP 规范的官方参考实现。Tomcat 可以作为一个独立的 Web 服务器使用,也可以作为一个 servlet/JSP 引擎实现。可以从 http://tomcat.apache.org/download-60.cgi 下载 Tomcat 的最新发行版。
Apache-cxf-2.3. 或更高版本: Apache CXF 是一个开源服务框架。CXF 帮助您使用前端编程 API(如 JAX-WS 和 JAX-RS)构建和开发服务。这些服务可以支持各种协议,如 SOAP、XML/HTTP、RESTful HTTP 或 CORBA,并可以使用多种传输方式,如 HTTP、JMS 或 JBI。您可以从 http://cxf.apache.org/download.html 下载最新版本。
Eclipse IDE:一种集成开发环境 (IDE),集编写、编辑、编译和运行计算机程序的所有工具于一体。并且,Eclipse 提供了出色的集成开发环境。您可以在 www.eclipse.org 找到 eclipse 的最新发行版。
设置环境
- 在系统中安装 Jdk 1.5 或更高版本。
- 下载了 apache-cxf 发行版后,设置 CXF_HOME 环境变量。
- 下载 Tomcat 的最新发行版,并设置 TOMCAT_HOME 环境变量。
创建 Web 服务
- 在 JavaEE 透视图中 启动 Eclipse,并选择 File > New > Other > Dynamic Web Project,创建名为 ‘CxfService’ 的项目。
- 展开 CxfService Project 选项卡,选择 Java Resource: src 并创建 ‘com.ibm.uploadbean’ 包。
- ‘com.ibm.uploadbean’ 包将包含一个简单的 java bean 类,该类将获取并设置文件名、文件类型和 DataHandler 类型。该 bean 将作为参数传递来调用该服务。因此,在该包下创建一个类,并命名为 ‘FileUploader’。
package com.ibm.uploadbean;
import javax.activation.DataHandler;
public class FileUploader
{
private String Name;
private String FileType;
private DataHandler Dfile;
public String getName()
{
return this.Name;
}
public void setName(String Name)
{
this.Name = Name;
}
public DataHandler getDfile()
{
return this.Dfile;
}
public void setDfile(DataHandler Dfile)
{
this.Dfile = Dfile;
}
public String getFileType() {
return FileType;
}
public void setFileType(String FileType) {
this.FileType = FileType;
}
}
- 每个 Web 服务都需要一个 Service Endpoint Interface (SEI),通过该接口客户端可以调用实现类。现在选择 Java Resource: src,创建另一个名为 ‘com.ibm.uploadservice’ 的包。
- 创建一个名为 ‘UploadSEI’ 的接口,其中包含 ‘uploadFile’ 方法
package com.ibm.uploadservice;
import javax.jws.WebParam;
import javax.jws.WebService;
import com.ibm.uploadbean.FileUploader;
@WebService
public interface UploadSEI {
void uploadFile(@WebParam(name="Dfile") FileUploader Dfile);
}
6. 创建一个名为‘UploadServiceImpl’的服务实现类,它在‘com.ibm.uploadservice’包的内部实现接口。该类定义了实现方法 uploadFile,后者使用 FileUploader bean 作为其参数。
package com.ibm.uploadservice;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import javax.activation.DataHandler;
import javax.jws.WebService;
import com.ibm.uploadbean.FileUploader;
@WebService(endpointInterface = "com.ibm.uploadservice.UploadSEI",
serviceName = "UploadService")
public class UploadServiceImpl implements UploadSEI{
public void uploadFile(FileUploader Dfile) {
DataHandler handler = Dfile.getDfile();
try {
InputStream is = handler.getInputStream();
OutputStream os = new FileOutputStream(new File("E:/uploads/"
+ Dfile.getName() +"."+
Dfile.getFileType()));
byte[] b = new byte[100000];
int bytesRead = 0;
while ((bytesRead = is.read(b)) != -1) {
os.write(b, 0, bytesRead);
}
os.flush();
os.close();
is.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
- “OutputStream” 将把文件保存到提供的指定位置。
- 下一步是创建配置文件 ‘cxf.xml’,该文件会根据实现类 ‘UploadServiceImpl’ 创建 JAX-WS 端点。确保该文件位于 ‘src’ 根文件夹中,否则根据您的文件路径编辑 Web.xml。
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:jaxws="http://cxf.apache.org/jaxws"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd
http://cxf.apache.org/jaxws
http://cxf.apache.org/schemas/jaxws.xsd">
<import resource="classpath:META-INF/cxf/cxf.xml" />
<import resource="classpath:META-INF/cxf/cxf-extension-soap.xml"/>
<import resource="classpath:META-INF/cxf/cxf-servlet.xml" />
<jaxws:endpoint id="uploadfile"
implementor="com.ibm.uploadservice.UploadServiceImpl"
address="/UploadWS">
<jaxws:properties>
<entry key="mtom-enabled" value="true"/>
</jaxws:properties>
</jaxws:endpoint>
</beans>
- 编辑 Web-INF 文件夹中的 ‘Web.xml’ 文件。
<?xml version="1.0" encoding="UTF-8"?>
<Web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns="http://java.sun.com/xml/ns/javaee"
xmlns:Web="http://java.sun.com/xml/ns/javaee/Web-app_2_5.xsd"
xsi:schemaLocation="http://java.sun.com/xml/ns/javaee
http://java.sun.com/xml/ns/javaee/Web-app_2_5.xsd" id="WebApp_ID" version="2.5">
<display-name>CxfService</display-name>
<context-param>
<param-name>contextConfigLocation</param-name>
<param-value>classpath:cxf.xml</param-value>
</context-param>
<listener>
<listener-class>
org.springframework.Web.context.ContextLoaderListener
</listener-class>
</listener>
<servlet>
<servlet-name>CXFServlet</servlet-name>
<servlet-class>
org.apache.cxf.transport.servlet.CXFServlet
</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>CXFServlet</servlet-name>
<url-pattern>/*</url-pattern>
</servlet-mapping>
</Web-app>
- 在 WebContent > Web-INF 下创建名为 ‘lib’ 的文件夹(参见图 5),然后在 lib 文件夹中包括以下 .jar 文件。您可以在已下载的 CXF 分配库中找到所有这些 jar 文件。
aopalliance-1.0.jar
asm-2.2.3.jar
commons-lang-2.4.jar
commons-logging-1.1.jar
cxf-api-2.1.5.jar
cxf-common-schemas-2.1.5.jar
cxf-common-utilities-2.1.5.jar
cxf-rt-bindings-soap-2.1.5.jar
cxf-rt-bindings-xml-2.1.5.jar
cxf-rt-core-2.1.5.jar
cxf-rt-databinding-jaxb-2.1.5.jar
cxf-rt-frontend-jaxws-2.1.5.jar
cxf-rt-frontend-simple-2.1.5.jar
cxf-rt-transports-http-2.1.5.jar
cxf-rt-ws-addr-2.1.5.jar
cxf-tools-common-2.1.5.jar
FastInfoset-1.2.2.jar
geronimo-activation_1.1_spec-1.0.2.jar
geronimo-annotation_1.0_spec-1.1.1.jar
geronimo-javamail_1.4_spec-1.3.jar
geronimo-jaxws_2.1_spec-1.0.jar
geronimo-stax-api_1.0_spec-1.0.1.jar
geronimo-ws-metadata_2.0_spec-1.1.2.jar
jaxb-api-2.1.jar
jaxb-impl-2.1.9.jar
neethi-2.0.4.jar
saaj-api-1.3.jar
saaj-impl-1.3.2.jar
spring-beans-2.0.8.jar
spring-context-2.0.8.jar
spring-core-2.0.8.jar
spring-Web-2.0.8.jar
wsdl4j-1.6.2.jar
wstx-asl-3.2.6.jar
xml-resolver-1.2.jar
XmlSchema-1.4.5.jar
- 右键单击项目,选择 Export > WAR file(参见图 7)。复制 WAR 文件并粘贴到 Tomcat_Home 下的 Webapps 目录。启动 Tomcat 服务器。
- 启动 tomcat 服务器后,Web 服务将被部署到服务器上。进入 Tomcat Manager,输入用户名和密码,然后登录。您会发现已部署的名为 ‘CxfService’ 的服务,单击该服务,将看到可用的服务及其 WSDL 位置。单击 location 超链接,查看 WSDL。
Service Endpoint - http://localhost:8080/CxfService/UploadWS
WSDL 位置 - http://localhost:8080/CxfService/UploadWS?wsdl
生成 Stub
要调用服务,客户端必须知道 Service Endpoint Interface 和 bean 文件,后者将作为参数进行调用。要获得这些内容,客户端可以通过服务的 WSDL 创建 stub。
CXF 发行版提供了一个名为 ‘wsdl2java.bat’ 的工具,该工具可以为特定服务创建 stub,同时为 WSDL 位置提供一些额外的参数。
从命令提示符中访问 $(CXF_HOME) 的 bin 目录,并输入以下命令。
wsdl2java
–
client
–
verbose http://localhost:8080/CxfService/UploadWS?wsdl
这将运行 bin 目录中的 wsdl2java.bat 文件。‘-client’ 选项为客户端主线生成开始(starting point)代码。‘–verbose’ 选项在生成代码的过程中显示注释。参见图 9。
在成功执行命令后,将发现在 $(CXF_HOME)/bin 目录的 ‘com.ibm.uploadservice’ 包下创建了 stub。
创建客户端
接下来,我们将创建客户端项目,以便可以使用 Web 服务。在本例中,客户端是一个 POJO 客户端,您还可以创建一个需要 Web 容器的客户端。执行以下步骤,开发一个客户端。
- 在 Eclipse 中,选择 File > New > Other > Dynamic Web project,创建一个名为 ‘CxfClient’ 的新项目。
- 创建一个名为 ‘com.ibm.uploadservice’ 的包(如在 stub 中),并将所有生成的 stub 复制并粘贴到其中。
- 创建另一个名为 ‘com.ibm.client’ 的包。在该包中创建一个名为 ‘Client’ 的新类。该类将通过生成的 stub 调用已开发的服务。该类将包含 main() 方法,因此执行将从这里开始。
package com.ibm.client;
import java.io.File;
import javax.activation.DataHandler;
import javax.activation.DataSource;
import javax.activation.FileDataSource;
import org.apache.cxf.interceptor.LoggingInInterceptor;
import org.apache.cxf.interceptor.LoggingOutInterceptor;
import org.apache.cxf.jaxws.JaxWsProxyFactoryBean;
import com.ibm.uploadservice.*;
public final class Client {
public static void main(String args[]) throws Exception {
JaxWsProxyFactoryBean factory = new JaxWsProxyFactoryBean();
factory.getInInterceptors().add(new LoggingInInterceptor());
factory.getOutInterceptors().add(new LoggingOutInterceptor());
factory.setServiceClass(UploadSEI.class);
factory.setAddress
("http://localhost:8080/CxfService/UploadWS");
UploadSEI client =(UploadSEI) factory.create();
FileUploader file=new FileUploader();
file.setName("Partha");
file.setFileType("doc");
DataSource source = new FileDataSource(new File("D:/my_upload_doc.doc"));
file.setDfile(new DataHandler(source));
client.uploadFile(file);
System.exit(0);
}
}
- 不要忘记在 WebContent > Web-INF > lib 中包含前面提到的 .jar 文件。
- ‘DataSource’ 对象源代码将包含上传文件的理想位置。在本例中为 ‘D:/my_upload_doc.doc’,可根据您的文件进行相应修改。
- setName("Partha") 是所上传文件的保存名。修改 setFileType("doc") 参数可相应地设置文件类型。
- 您可能会在 ‘file.setDfile’ 中得到一个类型匹配错误,这可能是因为生成的 ‘FileUploade.java’ 有一个 ‘byte[]’ 变量,而不是 ‘DataHandler’ 变量。将 byte[] 修改为 DataHander 就可以解决该问题。您还应当在其中导入 ‘javax.activation.DataHandler’。在任何情况下,引用 清单 1 中创建服务时使用的 bean 类。
- 要运行客户端,右键单击 Client.java 文件并选择 Run as > Java Application。如果没有发生错误的话,您会发现您的文件以给定的名称保存在服务指定的位置中。