This tutorial uses the following frameworks:
Note: The sample project can be downloaded, see the resources section.
Initial Project Setup
We want the integration to be a standard .war application that can be deployed in any web container such as Tomcat, Jetty or even heavy weight application servers such as WebLogic or WebSphere. There fore we start off with the standard Maven webapp project that is created with the following long archetype command:
Notice that the groupId etc. doens't have to be org.apache.camel it can be com.mycompany.whatever. But I have used these package names as the example is an official part of the Camel distribution.
Then we have the basic maven folder layout. We start out with the webservice part where we want to use Apache CXF for the webservice stuff. So we add this to the pom.xml
Developing the WebService
As we want to develop webservice with the contract first approach we create our .wsdl file. As this is a example we have simplified the model of the incident to only include 8 fields. In real life the model would be a bit more complex, but not to much.
We put the wsdl file in the folder
Then we integration the CXF wsdl2java generator in the pom.xml so we have CXF generate the needed POJO classes for our webservice contract.
And then we can add the CXF wsdl2java code generator that will hook into the compile goal so its automatic run all the time:
You are now setup and should be able to compile the project. So running the
Configuration of the web.xml
Next up is to configure the web.xml to be ready to use CXF so we can expose the webservice.
And then we have the CXF part where we define the CXF servlet and its URI mappings to which we have chosen that all our webservices should be in the path
Then the last piece of the puzzle is to configure CXF, this is done in a spring XML that we link to fron the web.xml by the standard Spring
We have named our CXF configuration file
Getting rid of the old jsp world
The maven archetype that created the basic folder structure also created a sample .jsp file index.jsp. This file
Configuration of CXF
The cxf-config.xml is as follows:
The 3 import elements is needed by CXF and they must be in the file.
Noticed that we have a spring bean reportIncidentEndpoint that is the implementation of the webservice endpoint we let CXF expose.
Implementing the ReportIncidentEndpoint
Phew after all these meta files its time for some java code so we should code the implementor of the webservice. So we fire up
You can use
As we want to quickly see our webservice we implement just a quick and dirty as it can get. At first beware that since its jaxws and Java 1.5 we get annotations for the money, but they reside on the interface so we can remove them from our implementations so its a nice plain POJO again:
We just output the person that invokes this webservice and returns a OK response. This class should be in the maven source root folder
To test if we are home free we run
Running our webservice
Now that the code compiles we would like to run it inside a web container, for this purpose we make use of Jetty which we will bootstrap using it's plugin
Notice: We make use of the Jetty version being defined inside the Camel's Parent POM.
So to see if everything is in order we fire up jetty with
So where is the damn webservice then? Well as we did configure the web.xml to instruct the CXF servlet to accept the pattern
Hitting the webservice
Now we have the webservice running in a standard .war application in a standard web container such as Jetty we would like to invoke the webservice and see if we get our code executed. Unfortunately this isn't the easiest task in the world - its not so easy as a REST URL, so we need tools for this. So we fire up our trusty webservice tool SoapUI and let it be the one to fire the webservice request and see the response.
Using SoapUI we sent a request to our webservice and we got the expected OK response and the console outputs the System.out so we are ready to code.
Okay a little sidestep but wouldn't it be cool to be able to debug your code when its fired up under Jetty? As Jetty is started from maven, we need to instruct maven to use debug mode.
Then you need to restart Jetty so its stopped with ctrl + c. Remember to start a new shell to pickup the new environment settings. And start jetty again.
Then we can from our IDE attach a remote debugger and debug as we want.
Then we set a breakpoint in our code
Adding a unit test
Oh so much hard work just to hit a webservice, why can't we just use an unit test to invoke our webservice? Yes of course we can do this, and that's the next step.
Here we have a plain old JUnit class. As we want to test webservices we need to start and expose our webservice in the unit test before we can test it. And JAXWS has pretty decent methods to help us here, the code is simple as:
The Endpoint class is the
Next up is to create a webservice client so we can invoke our webservice. For this we actually use the CXF framework directly as its a bit more easier to create a client using this framework than using the JAXWS style. We could have done the same for the server part, and you should do this if you need more power and access more advanced features.
So now we are ready for creating a unit test. We have the server and the client. So we just create a plain simple unit test method as the usual junit style:
Now we are nearly there. But if you run the unit test with
Well what is that, CXF also uses Jetty for unit test - well its just shows how agile, embedable and popular Jetty is.
So lets run our junit test with, and it reports:
Yep thats it for now. We have a basic project setup.
End of part 1
Thanks for being patient and reading all this more or less standard Maven, Spring, JAXWS and Apache CXF stuff. Its stuff that is well covered on the net, but I wanted a full fledged tutorial on a maven project setup that is web service ready with Apache CXF. We will use this as a base for the next part where we demonstrate how Camel can be digested slowly and piece by piece just as it was back in the times when was introduced and was learning the Spring framework that we take for granted today.