Versions Compared

Key

  • This line was added.
  • This line was removed.
  • Formatting was changed.
Comment: Migrated to Confluence 5.3

Part 1

Prerequisites

This tutorial uses the following frameworks:

  • Maven 23.0.94
  • Apache Camel 12.410.0
  • Apache CXF 2.16.1
  • Spring 23.50.57

Note: The sample project can be downloaded, see the resources section.

...

Code Block
xml
xml
    <properties>
        <cxf-version>2.16.1</cxf-version>
    </properties>

    <dependency>
        <groupId>org.apache.cxf</groupId>
        <artifactId>cxf-rt-core</artifactId>
        <version>${cxf-version}</version>
    </dependency>
    <dependency>
        <groupId>org.apache.cxf</groupId>
        <artifactId>cxf-rt-frontend-jaxws</artifactId>
        <version>${cxf-version}</version>
    </dependency>
    <dependency>
        <groupId>org.apache.cxf</groupId>
        <artifactId>cxf-rt-transports-http</artifactId>
        <version>${cxf-version}</version>
    </dependency>

...

Then we integration the CXF wsdl2java generator in the pom.xml so we have CXF generate the needed POJO classes for our webservice contract.
However at first we must configure maven to live in the modern world of Java 1.5 6 so we must add this to the pom.xml

Code Block
xml
xml
			<!-- to compile with 1.56 -->
			<plugin>
				<groupId>org.apache.maven.plugins</groupId>
				<artifactId>maven-compiler-plugin</artifactId>
				<configuration>
					<source>1.5<6</source>
					<target>1.5<6</target>
				</configuration>
			</plugin>

...

Code Block
xml
xml
			<!-- CXF wsdl2java generator, will plugin to the compile goal -->
			<plugin>
				<groupId>org.apache.cxf</groupId>
				<artifactId>cxf-codegen-plugin</artifactId>
				<version>${cxf-version}</version>
				<executions>
					<execution>
						<id>generate-sources</id>
						<phase>generate-sources</phase>
						<configuration>
							<sourceRoot>${basedir}/target/generated/src/main/java</sourceRoot>
							<wsdlOptions>
								<wsdlOption>
									<wsdl>${basedir}/src/main/webapp/WEB-INF/wsdl/report_incident.xml<wsdl</wsdl>
								</wsdlOption>
							</wsdlOptions>
						</configuration>
						<goals>
							<goal>wsdl2java</goal>
						</goals>
					</execution>
				</executions>
			</plugin>
		</plugins>

You are now setup and should be able to compile the project. So running the mvn compile should run the CXF wsdl2java and generate the source code in the folder &{basedir}/target/generated/src/main/java that we specified in the pom.xml above. Since its in the target/generated/src/main/java maven will pick it up and include it in the build process.

...

Code Block
xml
xml
<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-2.0.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"/>

    <!-- implementation of the webservice -->
    <bean id="reportIncidentEndpoint" class="org.apache.camel.example.reportincident.ReportIncidentEndpointImpl"/>

    <!-- export the webservice using jaxws -->
    <jaxws:endpoint id="reportIncident"
                    implementor="#reportIncidentEndpoint"
                    address="/incident"
                    wsdlLocation="/WEB-INF/wsdl/report_incident.xmlwsdl"
                    endpointName="s:ReportIncidentPort"
                    serviceName="s:ReportIncidentService"
                    xmlns:s="http://reportincident.example.camel.apache.org"/>

</beans>

...

Noticed that we have a spring bean reportIncidentEndpoint that is the implementation of the webservice endpoint we let CXF expose.
Its linked from the jaxws element with the implementator attribute as we use the # mark to identify its a reference to a spring bean. We could have statet stated the classname directly as implementor="org.apache.camel.example.reportincident.ReportIncidentEndpoint" but then we lose the ability to let the ReportIncidentEndpoint be configured by spring.
The address attribute defines the relative part of the URL of the exposed webservice. wsdlLocation is an optional parameter but for persons like me that likes contract-first we want to expose our own .wsdl contracts and not the auto generated by the frameworks, so with this attribute we can link to the real .wsdl file. The last stuff is needed by CXF as you could have several services so it needs to know which this one is. Configuring these is quite easy as all the information is in the wsdl already.

...

Now that the code compiles we would like to run it in inside a web container, so we add jetty to our pom.xml so we can run mvn retty:runfor this purpose we make use of Jetty which we will bootstrap using it's plugin org.mortbay.jetty:maven-jetty-plugin:

Code Block
xml
xml

	<properties>
             ...
             <jetty-version>6.1.1</jetty-version>
	</properties>

       <build>
           <plugins>
               ...
               <!-- so we can run mvn jetty:run -->
               <plugin>
                   <groupId>org.mortbay.jetty</groupId>
                   <artifactId>maven-jetty-plugin</artifactId>
                   <version>${jetty-version}</version>
               </plugin>

Notice: We make use Jetty v6.1.1 as never versions has troubles on my laptop. Feel free to try a newer version on your system, but v6.1.1 works flawless.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 mvn jetty:run and if everything is okay you should be able to access http://localhost:8080Image Removed.
Jetty is smart that it will list the correct URI on the page to our web application, so just click on the link. This is smart as you don't have to remember the exact web context URI for your application - just fire up the default page and Jetty will help you.

So where is the damm damn webservice then? Well as we did configure the web.xml to instruct the CXF servlet to accept the pattern /webservices/* we should hit this URL to get the attention of CXF: http://localhost:8080/mycamel-example-webappreportincident/webservicesImage Removed.
Image Removed Image Added
 

Hitting the webservice

...

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.
Image Removed Image Added
 

Remote Debugging

...

Then we can from our IDE attach a remote debugger and debug as we want.
First we configure IDEA to attach to a remote debugger on port 5005:
Image Removed Image Added
 

Then we set a breakpoint in our code ReportIncidentEndpoint and hit the SoapUI once again and we are breaked at the breakpoint where we can inspect the parameters:
Image Removed Image Added
 

Adding a unit test

...

#Resources