Um zu dem neulich erstellten Spring-CXF-Service Routing per Apache Camel hinzuzufügen, sind folgende Schritte nötig:
1. POM anpassen
1:
2:<dependency>
3: <groupId>org.apache.camel</groupId>
4: <artifactId>camel-core</artifactId>
5: <version>1.4.0</version>
6:</dependency>
7:
8:<dependency>
9: <groupId>org.apache.camel</groupId>
10: <artifactId>camel-cxf</artifactId>
11: <version>1.4.0</version>
12:</dependency>
2. spring-context.xml anpassen
1:<?xml version="1.0" encoding="UTF-8"?>
2:<beans xmlns="http://www.springframework.org/schema/beans"
3: xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
4: xmlns:cxf="http://activemq.apache.org/camel/schema/cxfEndpoint"
5: xsi:schemaLocation="http://www.springframework.org/schema/beans
6: http://www.springframework.org/schema/beans/spring-beans.xsd
7: http://activemq.apache.org/camel/schema/cxfEndpoint
8: http://activemq.apache.org/camel/schema/cxfEndpoint/camel-cxf.xsd
9: http://activemq.apache.org/camel/schema/spring
10: http://activemq.apache.org/camel/schema/spring/camel-spring.xsd">
11:
12: <import resource="classpath:META-INF/cxf/cxf.xml" />
13: <import resource="classpath:META-INF/cxf/cxf-extension-soap.xml" />
14: <import resource="classpath:META-INF/cxf/cxf-servlet.xml" />
15:
16: <bean id="myCamelProcessor" class="org.developers.blog.MyCamelProcessor" />
17:
18: <cxf:cxfEndpoint id="helloEndpoint"
19: serviceClass="org.developers.blog.ServiceExample"
20: address="/Hello" />
21:
22: <camelContext id="test_context"
23: xmlns="http://activemq.apache.org/camel/schema/spring"
24: trace="true">
25: <route>
26: <from uri="cxf:bean:helloEndpoint"/>
27: <to uri="bean:myCamelProcessor"/>
28: </route>
29: </camelContext>
30:</beans>
trace="true" ist notwendig, damit anschließend im Logfile auch etwas zu sehen ist.
3. Camel Processor implementieren
1:package org.developers.blog;
2:
3:import java.util.List;
4:import org.apache.camel.Exchange;
5:import org.apache.camel.Processor;
6:
7:public class MyCamelProcessor implements Processor {
8:
9: public void process (Exchange exchange) {
10: String message = (String) exchange.getIn().getBody(List.class).get(0);
11: exchange.getOut().setBody("Hello was: " + message);
12: }
13:}
4. Kompilieren und WAR deployen (z.B. in den Tomcat)
Wenn man den Service nun z.B. über die SoapUI aufruft, schreibt Camel so etwas nach catalina.out (natürlich alles in einer Zeile):
11.09.2008 22:47:47 org.apache.camel.processor.Logger process
INFO: ID-osiris/33225-1221173240660/2-0 -> to1 To[bean:myCamelProcessor]
InOut Properties:{CamelCauseException=null}
Headers:{javax.xml.ws.wsdl.port={http://my.org/ns/}ServiceExamplePort,
org.apache.cxf.service.model.MessageInfo=[MessageInfo INPUT{http://my.org/ns/}sayHello],
org.apache.cxf.message.Message.PROTOCOL_HEADERS={content-type=[text/xml;charset=UTF-8],
host=[localhost:8080],
soapaction=[""],
content-length=[275],
user-agent=[Jakarta Commons-HttpClient/3.0.1]},
operationNameSpace=http://my.org/ns/,
javax.xml.ws.wsdl.interface={http://my.org/ns/}IServiceExample,
HTTP.REQUEST=org.apache.catalina.connector.RequestFacade@16f2723, Accept=null,
org.apache.cxf.headers.Header.list=[],
org.apache.cxf.message.Message.BASE_PATH=/cxf-spring-example/Hello,
org.apache.cxf.message.Message.PATH_INFO=/cxf-spring-example/Hello,
operationName=sayHello,
javax.xml.ws.wsdl.service={http://my.org/ns/}ServiceExampleService,
org.apache.cxf.message.Message.HTTP_REQUEST_METHOD=POST,
org.apache.cxf.message.Message.ENCODING=UTF-8,
org.apache.cxf.message.Message.QUERY_STRING=null,
HTTP.RESPONSE=org.apache.catalina.connector.ResponseFacade@728743,
org.apache.cxf.security.SecurityContext=org.apache.cxf.transport.http.AbstractHTTPDestination$1@10e7233,
org.apache.cxf.async.post.response.dispatch=true,
javax.xml.ws.wsdl.operation={http://my.org/ns/}sayHello,
org.apache.cxf.message.MessageFIXED_PARAMETER_ORDER=false,
org.apache.cxf.transport.Destination=org.apache.cxf.transport.servlet.ServletDestination@13dd5ec,
javax.xml.ws.wsdl.description=/Hello?wsdl,
org.apache.cxf.service.model.BindingMessageInfo=org.apache.cxf.service.model.BindingMessageInfo@a77997,
Content-Type=text/xml;charset=UTF-8,
HTTP.CONTEXT=org.apache.catalina.core.ApplicationContextFacade@48a158} BodyType:org.apache.cxf.message.MessageContentsList Body:Du
Von CXF generierte WSDL
1:
2:<wsdl:definitions name="ServiceExampleService" targetNamespace="http://my.org/ns/">
3:
4: <wsdl:types>
5:
6: <xs:schema attributeFormDefault="unqualified" elementFormDefault="unqualified" targetNamespace="http://my.org/ns/">
7: <xs:element name="sayHello" type="tns:sayHello"/>
8: <xs:element name="sayHelloResponse" type="tns:sayHelloResponse"/>
9:
10: <xs:complexType name="sayHello">
11:
12: <xs:sequence>
13: <xs:element minOccurs="0" name="arg0" type="xs:string"/>
14: </xs:sequence>
15: </xs:complexType>
16:
17: <xs:complexType name="sayHelloResponse">
18:
19: <xs:sequence>
20: <xs:element minOccurs="0" name="return" type="xs:string"/>
21: </xs:sequence>
22: </xs:complexType>
23: </xs:schema>
24: </wsdl:types>
25:
26: <wsdl:message name="sayHelloResponse">
27: <wsdl:part element="tns:sayHelloResponse" name="parameters"></wsdl:part>
28: </wsdl:message>
29:
30: <wsdl:message name="sayHello">
31: <wsdl:part element="tns:sayHello" name="parameters"></wsdl:part>
32: </wsdl:message>
33:
34: <wsdl:portType name="IServiceExample">
35:
36: <wsdl:operation name="sayHello">
37: <wsdl:input message="tns:sayHello" name="sayHello"></wsdl:input>
38: <wsdl:output message="tns:sayHelloResponse" name="sayHelloResponse"></wsdl:output>
39: </wsdl:operation>
40: </wsdl:portType>
41:
42: <wsdl:binding name="ServiceExampleServiceSoapBinding" type="tns:IServiceExample">
43: <soap:binding style="document" transport="http://schemas.xmlsoap.org/soap/http"/>
44:
45: <wsdl:operation name="sayHello">
46: <soap:operation soapAction="" style="document"/>
47:
48: <wsdl:input name="sayHello">
49: <soap:body use="literal"/>
50: </wsdl:input>
51:
52: <wsdl:output name="sayHelloResponse">
53: <soap:body use="literal"/>
54: </wsdl:output>
55: </wsdl:operation>
56: </wsdl:binding>
57:
58: <wsdl:service name="ServiceExampleService">
59:
60: <wsdl:port binding="tns:ServiceExampleServiceSoapBinding" name="ServiceExamplePort">
61: <soap:address location="http://localhost:8080/cxf-spring-example/Hello"/>
62: </wsdl:port>
63: </wsdl:service>
64:</wsdl:definitions>
Man könnte den Parameter verpflichtend machen, indem man auf dem sayHello Type das Attribut minOccurs auf 1 setzt.
SOAP-request (aus der WSDL mittels SoapUI generiert)
1:<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/"
2: xmlns:ns="http://my.org/ns/">
3: <soapenv:Header/>
4: <soapenv:Body>
5: <ns:sayHello>
6: <!--Optional:-->
7: <arg0>World</arg0>
8: </ns:sayHello>
9: </soapenv:Body>
10:</soapenv:Envelope>
SOAP-response
1:<soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/">
2: <soap:Body>
3: <ns2:sayHelloResponse xmlns:ns2="http://my.org/ns/">
4: <return>Hello was: World</return>
5: </ns2:sayHelloResponse>
6: </soap:Body>
7:</soap:Envelope>
