Configuration and development
This example will show how to configure and develop a CXF based webservice running on a server that would perform uploading of files submitted by the client. See below the following specifications.
Tomcat web server 5.5 or above: The Tomcat servlet engine is an open-source package developed as part of the Apache Software Foundation's Jakarta project. It is the official reference implementation for both the servlet and JSP specifications. Tomcat can act as a stand-alone Web server and also as a servlet/JSP engine. We can download the latest release of Tomcat from http://tomcat.apache.org/download-60.cgi.
Apache-cxf-2.3. or above: Apache CXF is an open source services framework. CXF helps you build and develop services using frontend programming APIs, like JAX-WS and JAX-RS. These services can speak a variety of protocols such as SOAP, XML/HTTP, RESTful HTTP, or CORBA and work over a variety of transports such as HTTP, JMS or JBI.You can download the lates version from http://cxf.apache.org/download.html.
Eclipse IDE: An integrated development environment (IDE) is an all-in-one tool for writing, editing, compiling, and running computer programs. And Eclipse provides an excellent integrated development environment. You can find the latest release of eclipse in www.eclipse.org.
- Install Jdk 1.5 or above in your system.
- After downloading apache-cxf distribution set the CXF_HOME environment variable.
- Download latest version of Tomcat and set the TOMCAT_HOME environment variable.
- Start Eclipse in JavaEE perspective and select File > New > Other > Dynamic web Project named 'CxfService'.
- Expand the CxfService Project tab, select Java Resource: src and create a package 'com.ibm.uploadbean'.
- The package 'com.ibm.uploadbean' will contain a simple java bean class which will get and set the name of the file, the type of the file and the DataHandler type. The bean will be passed as a parameter to invoke this service. So create a class under that package and name it as 'FileUploader'. The code listing for this class is given below in Listing 1 and figure 2.
Figure 2. File Uploader bean class
Listing 1. FileUploader.java
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;
}
}
|
- Every web service requires a Service Endpoint Interface (SEI), through which the client can invoke the implementation class. Now select Java Resource: src and create another package named 'com.ibm.uploadservice'.
- Create an interface named 'UploadSEI' containing a method named 'uploadFile' as shown in the listing 2 and figure 3.
Figure 3. UploadSEI - Service Endpoint Interface
Listing 2. UploadSEI.java
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);
}
|
- Create a service implementation class named 'UploadServiceImpl' implementing the interface inside the same package 'com.ibm.uploadservice'. This class defines the implementation method uploadFile which uses the FileUploader bean as its parameter. See the figure 4 below and the listing 3.
Figure 4. Upload Service Implementation
Listing 3. UploadServiceImpl.java
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();
}
}
}
|
- The "OutputStream" will save the file in desired location as provided.
- Next is to create a configuration file 'cxf.xml' that would create a JAX-WS endpoint based on our implementation class 'UploadServiceImpl'. Make sure that the file is in the root 'src' folder, otherwise edit the web.xml according to your path of the file. See figure 5 and listing 4.
Figure 5. CXF configuration file
Listing 4. cxf.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>
|
- Edit the 'web.xml' file in the WEB-INF folder. See listing 5.
Listing 5. 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>
|
- Create a folder named 'lib' under WebContent > WEB-INF (see figure 5) and include the following .jar files in the lib folder. You can find all these jars in the CXF distribution library which you have already downloaded.
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
Your errors will now disappear. Check in the below figure 6.
Figure 6. CXF configuration file
- Right click the project select Export > WAR file (see figure 7). Copy the WAR file and paste it in the webapps directory under Tomcat_Home. Start the Tomcat server.
Figure 7. WAR creation
- On starting the tomcat server the Web service gets deployed in it. Go to the Tomcat Manager, enter username, password and log into it. You will find the deployed service named 'CxfService', click onto it and you will find the available service with its WSDL location. Click on the location hyperlink to see the WSDL. See figure 8.
Figure 8. Tomcat Console
Service Endpoint - http://localhost:8080/CxfService/UploadWS
WSDL location - http://localhost:8080/CxfService/UploadWS?wsdl
In order to invoke the service the client must know the Service Endpoint Interface and the bean file which is to be invoked as a parameter. In order to get the things the client can create stubs from the WSDL of the service.
CXF distribution provides a tool called 'wsdl2java.bat' which can create the stubs for a particular service when provided the WSDL location with some additional parameters.
Go to the bin directory of $(CXF_HOME) from the command prompt and type the
following command.wsdl2java –client
–verbose http://localhost:8080/CxfService/UploadWS?wsdl
This is going to run the wsdl2java.bat file present in the bin directory. The '-client' option generates starting point code for a client mainline. The '–verbose' option displays comments during the code generation process. See figure 9.
On successful execution of the command you will find the stubs created under the package 'com.ibm.uploadservice' in the $(CXF_HOME)/bin directory.
Figure 9. Stub Generation Command
Now we are going to create the client project so that the web service can be consumed. In this example the client is a POJO client, you can also make a web client which would require a web container to run. Follow the below steps to develop a client.
- In Eclipse select File > New > Other > Dynamic web project and create a new project named 'CxfClient'.
- Create a package named 'com.ibm.uploadservice' (as in the stubs) and copy-paste all the generated stubs in it.
- Create another package named 'com.ibm.client'. Create a new class named 'Client' in the package. This class is going to invoke the developed service through the generated stubs. This class will contain the main() method so execution will start from here. See the code listing 6 for this class.
Figure 10. Client invoking service java class
Listing 6. Client.java
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);
}
}
|
- Do not forget to include the previously mentioned .jar files in the WebContent > WEB-INF > lib.
- The 'DataSource' object source will contain the desired location of your uploading file. Here it is 'D:/my_upload_doc.doc' change it according to your file.
- The setName("Partha") will be the saving name of the uploaded file. Set the file type accordingly by modifying the setFileType("doc") parameter.
- You still might get a type mis-match error in 'file.setDfile', this might be because the generated stub 'FileUploade.java' has been having a 'byte[]' variable instead of having a 'DataHandler' variable .Change the byte[] to DataHander to resolve this problem. You should also import 'javax.activation.DataHandler' in it. In any inconvenience refer to the bean class used during the service creation in Listing 1.
- To run the client right-click on the Client.java file and select Run as > Java Application. If everything is perfect then you will find your file in saved by the given name in the location specified in the service.

