You are viewing an old version of this page. View the current version.

Compare with Current View Page History

« Previous Version 5 Next »

Tutorial for using AXIS 1.4 with Apache Camel

Introduction

Apache AXIS is/was widely used as a webservice framework. So in line with some of the other tutorials to demonstrate how Camel is not an invasive framework but is flexible and integrates well with existing solution.

We have an existing solution that exposes a webservice using AXIS 1.4 deployed as web applications. This is a common solution. We use contract first so we have AXIS generated source code from an existing wsdl file. Then we show how we introduce Spring and Camel to integrate with AXIS.

This tutorial uses the following frameworks:

  • Maven 2.0.9
  • Apache Camel 1.4.0
  • Apache AXIS 1.4
  • Spring 2.5.5

Maven 2

AXIS dependencies is available for maven 2 so we configure our pom.xml as:

        <dependency>
            <groupId>org.apache.axis</groupId>
            <artifactId>axis</artifactId>
            <version>1.4</version>
        </dependency>

        <dependency>
            <groupId>org.apache.axis</groupId>
            <artifactId>axis-jaxrpc</artifactId>
            <version>1.4</version>
        </dependency>

        <dependency>
            <groupId>org.apache.axis</groupId>
            <artifactId>axis-saaj</artifactId>
            <version>1.4</version>
        </dependency>

	<dependency>
	    <groupId>axis</groupId>
	    <artifactId>axis-wsdl4j</artifactId>
	    <version>1.5.1</version>
	</dependency>

	<dependency>
	    <groupId>commons-discovery</groupId>
	    <artifactId>commons-discovery</artifactId>
	    <version>0.4</version>
	</dependency> 

        <dependency>
            <groupId>log4j</groupId>
            <artifactId>log4j</artifactId>
            <version>1.2.14</version>
        </dependency>

Then we need to configure maven to use Java 1.5 and the axis maven plugin that generates the source code based on the wsdl file:

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

            <plugin>
               <groupId>org.codehaus.mojo</groupId>
               <artifactId>axistools-maven-plugin</artifactId>
               <configuration>
	          <sourceDirectory>src/main/resources/</sourceDirectory>
                  <packageSpace>com.mycompany.myschema</packageSpace>
                  <testCases>false</testCases>
                  <serverSide>true</serverSide>
                  <subPackageByFileName>false</subPackageByFileName>
               </configuration>
               <executions>
                 <execution>
                   <goals>
                     <goal>wsdl2java</goal>
                   </goals>
                 </execution>
               </executions>
            </plugin>

wsdl

We use the same .wsdl file as the Tutorial-Example-ReportIncident and copy it to src/main/resources
TODO: maybe in WEB-INF/wsdl

<?xml version="1.0" encoding="ISO-8859-1"?>
<wsdl:definitions xmlns:soap="http://schemas.xmlsoap.org/wsdl/soap/"
	xmlns:tns="http://reportincident.example.camel.apache.org"
	xmlns:xs="http://www.w3.org/2001/XMLSchema"
	xmlns:http="http://schemas.xmlsoap.org/wsdl/http/"
	xmlns:wsdl="http://schemas.xmlsoap.org/wsdl/"
	targetNamespace="http://reportincident.example.camel.apache.org">

	<!-- Type definitions for input- and output parameters for webservice -->
	<wsdl:types>
	<xs:schema targetNamespace="http://reportincident.example.camel.apache.org">
			<xs:element name="inputReportIncident">
				<xs:complexType>
					<xs:sequence>
						<xs:element type="xs:string"  name="incidentId"/>
						<xs:element type="xs:string"  name="incidentDate"/>
						<xs:element type="xs:string"  name="givenName"/>
						<xs:element type="xs:string"  name="familyName"/>
						<xs:element type="xs:string"  name="summary"/>
						<xs:element type="xs:string"  name="details"/>
						<xs:element type="xs:string"  name="email"/>
						<xs:element type="xs:string"  name="phone"/>
					</xs:sequence>
				</xs:complexType>
			</xs:element>
			<xs:element name="outputReportIncident">
				<xs:complexType>
					<xs:sequence>
						<xs:element type="xs:string" name="code"/>
					</xs:sequence>
				</xs:complexType>
			</xs:element>
		</xs:schema>
	</wsdl:types>

	<!-- Message definitions for input and output -->
	<wsdl:message name="inputReportIncident">
		<wsdl:part name="parameters" element="tns:inputReportIncident"/>
	</wsdl:message>
	<wsdl:message name="outputReportIncident">
		<wsdl:part name="parameters" element="tns:outputReportIncident"/>
	</wsdl:message>

	<!-- Port (interface) definitions -->
	<wsdl:portType name="ReportIncidentEndpoint">
		<wsdl:operation name="ReportIncident">
			<wsdl:input message="tns:inputReportIncident"/>
			<wsdl:output message="tns:outputReportIncident"/>
		</wsdl:operation>
	</wsdl:portType>

	<!-- Port bindings to transports and encoding - HTTP, document literal encoding is used -->
	<wsdl:binding name="ReportIncidentBinding" type="tns:ReportIncidentEndpoint">
		<soap:binding transport="http://schemas.xmlsoap.org/soap/http"/>
		<wsdl:operation name="ReportIncident">
			<soap:operation
				soapAction="http://reportincident.example.camel.apache.org/ReportIncident"
				style="document"/>
			<wsdl:input>
				<soap:body parts="parameters" use="literal"/>
			</wsdl:input>
			<wsdl:output>
				<soap:body parts="parameters" use="literal"/>
			</wsdl:output>
		</wsdl:operation>
	</wsdl:binding>

	<!-- Service definition -->
	<wsdl:service name="ReportIncidentService">
		<wsdl:port name="ReportIncidentPort" binding="tns:ReportIncidentBinding">
			<soap:address location="http://reportincident.example.camel.apache.org"/>
		</wsdl:port>
	</wsdl:service>

</wsdl:definitions>

Configuring AXIS

Okay we are now setup for the contract first development and can generate the source file. For now we are still only using standard AXIS and not Spring nor Camel. We still need to setup AXIS as a web application so we configure the web.xml in src/main/webapp/WEB-INF/web.xml as:

	<servlet>
		<servlet-name>axis</servlet-name>
		<servlet-class>org.apache.axis.transport.http.AxisServlet</servlet-class>
	</servlet>

	<servlet-mapping>
		<servlet-name>axis</servlet-name>
		<url-pattern>/services/*</url-pattern>
	</servlet-mapping>

The web.xml just registeres AXIS servlet that is handling the incoming web requests to its servlet mapping. We still need to configure AXIS itself and this is done using its special configuration file server-config.wsdd. We nearly get this file for free if we let Axis generate the source code so we run the maven goal:

mvn axistools:wsdl2java

The tool will generate the source code based on the wsdl and save the files to the following folder:

.\target\generated-sources\axistools\wsdl2java\org\apache\camel\example\reportincident
deploy.wsdd
InputReportIncident.java
OutputReportIncident.java
ReportIncidentBindingImpl.java
ReportIncidentBindingStub.java
ReportIncidentService_PortType.java
ReportIncidentService_Service.java
ReportIncidentService_ServiceLocator.java
undeploy.wsdd

This is standard AXIS and so far no Camel or Spring has been touched. To implement our webservice we will add our code, so we create a new class AxisReportIncidentService that implements the port type interface where we can implement our code logic what happens when the webservice is invoked.

package org.apache.camel.example.axis;

import org.apache.camel.example.reportincident.InputReportIncident;
import org.apache.camel.example.reportincident.OutputReportIncident;
import org.apache.camel.example.reportincident.ReportIncidentService_PortType;

import java.rmi.RemoteException;

/**
 * Axis webservice
 */
public class AxisReportIncidentService implements ReportIncidentService_PortType {

    public OutputReportIncident reportIncident(InputReportIncident parameters) throws RemoteException {
        System.out.println("Hello AxisReportIncidentService is called from " + parameters.getGivenName());

        OutputReportIncident out = new OutputReportIncident();
        out.setCode("OK");
        return out;
    }

}

Now we need to configure AXIS itself and this is done using its server-config.wsdd file. We nearly get this for for free from the auto generated code, we copy the stuff from deploy.wsdd and made a few modifications:

<?xml version="1.0" encoding="UTF-8"?>
<deployment xmlns="http://xml.apache.org/axis/wsdd/" xmlns:java="http://xml.apache.org/axis/wsdd/providers/java">
  <!-- global configuration -->
	<globalConfiguration>
		<parameter name="sendXsiTypes" value="true"/>
		<parameter name="sendMultiRefs" value="true"/>
		<parameter name="sendXMLDeclaration" value="true"/>
		<parameter name="axis.sendMinimizedElements" value="true"/>
	</globalConfiguration>
	<handler name="URLMapper" type="java:org.apache.axis.handlers.http.URLMapper"/>

  <!-- this service is from deploy.wsdd -->
  <service name="ReportIncidentPort" provider="java:RPC" style="document" use="literal">
      <parameter name="wsdlTargetNamespace" value="http://reportincident.example.camel.apache.org"/>
      <parameter name="wsdlServiceElement" value="ReportIncidentService"/>
      <parameter name="schemaUnqualified" value="http://reportincident.example.camel.apache.org"/>
      <parameter name="wsdlServicePort" value="ReportIncidentPort"/>
      <parameter name="className" value="org.apache.camel.example.reportincident.ReportIncidentBindingImpl"/>
      <parameter name="wsdlPortType" value="ReportIncidentService"/>
      <parameter name="typeMappingVersion" value="1.2"/>
      <operation name="reportIncident" qname="ReportIncident" returnQName="retNS:outputReportIncident" xmlns:retNS="http://reportincident.example.camel.apache.org" returnType="rtns:>outputReportIncident" xmlns:rtns="http://reportincident.example.camel.apache.org" soapAction="http://reportincident.example.camel.apache.org/ReportIncident" >
        <parameter qname="pns:inputReportIncident" xmlns:pns="http://reportincident.example.camel.apache.org" type="tns:>inputReportIncident" xmlns:tns="http://reportincident.example.camel.apache.org"/>
      </operation>
      <parameter name="allowedMethods" value="reportIncident"/>

      <typeMapping
        xmlns:ns="http://reportincident.example.camel.apache.org"
        qname="ns:>outputReportIncident"
        type="java:org.apache.camel.example.reportincident.OutputReportIncident"
        serializer="org.apache.axis.encoding.ser.BeanSerializerFactory"
        deserializer="org.apache.axis.encoding.ser.BeanDeserializerFactory"
        encodingStyle=""
      />
      <typeMapping
        xmlns:ns="http://reportincident.example.camel.apache.org"
        qname="ns:>inputReportIncident"
        type="java:org.apache.camel.example.reportincident.InputReportIncident"
        serializer="org.apache.axis.encoding.ser.BeanSerializerFactory"
        deserializer="org.apache.axis.encoding.ser.BeanDeserializerFactory"
        encodingStyle=""
      />
  </service>

  <!-- part of Axis configuration -->
	<transport name="http">
		<requestFlow>
			<handler type="URLMapper"/>
			<handler type="java:org.apache.axis.handlers.http.HTTPAuthHandler"/>
		</requestFlow>
	</transport>
</deployment>

The globalConfiguration and transport is not in the deploy.wsdd file so you gotta write that yourself. The service is a 100% copy from deploy.wsdd. Axis has more configuration to it than shown here, but then you should check the AXIS documentation.

What we need to do now is important, as we need to modify the above configuration to use our webservice class than the default one, so we the classname parameter to:

<parameter name="className" value="org.apache.camel.example.axis.AxisReportIncidentService"/>
  • No labels