Dienstag, 28 Oktober 2008

A simple ActiveMQ example

A small class to get started with ActiveMQ. Inspired by the examples contained in the ActiveMQ download.

MyFirstActiveMqQueue.java

   1:/*
   2: * Small class to get started with ActiveMQ. Inspired by the examples contained in the
   3: * ActiveMQ download. Gisbert Amm, 2008-10-28
   4: */
   5:package de.gisbertamm.activemqstart;
   6:
   7:import javax.jms.JMSException;
   8:import org.apache.activemq.ActiveMQConnectionFactory;
   9:import org.apache.activemq.broker.BrokerService;
  10:import javax.jms.Connection;
  11:import javax.jms.DeliveryMode;
  12:import javax.jms.Destination;
  13:import javax.jms.ExceptionListener;
  14:import javax.jms.Message;
  15:import javax.jms.MessageConsumer;
  16:import javax.jms.MessageListener;
  17:import javax.jms.MessageProducer;
  18:import javax.jms.Session;
  19:import javax.jms.TextMessage;
  20:import org.apache.activemq.ActiveMQConnection;
  21:
  22:/**
  23: *
  24: * @author gisbert.amm
  25: */
  26:public class MyFirstActiveMqQueue {
  27:
  28:    private static ActiveMQConnectionFactory connectionFactory;
  29:    private static Connection connection;
  30:    private static Session session;
  31:    private static Destination destination;
  32:    private static boolean transacted = false;
  33:
  34:    public static void main(String[] args) throws Exception {
  35:        BrokerService broker = new BrokerService();
  36:        broker.setUseJmx(true);
  37:        broker.addConnector("tcp://localhost:61616");
  38:        broker.start();
  39:
  40:        setUp();
  41:        createProducerAndSendAMessage();
  42:        System.out.println("Simulating a huge network delay :)");
  43:        Thread.sleep(4000);
  44:        createConsumerAndReceiveAMessage();
  45:
  46:        //TODO: Find out how to get rid of the exceptions thrown when stopping the broker
  47:        broker.stop();
  48:    }
  49:
  50:    private static void setUp() throws JMSException {
  51:        connectionFactory = new ActiveMQConnectionFactory(
  52:                ActiveMQConnection.DEFAULT_USER,
  53:                ActiveMQConnection.DEFAULT_PASSWORD,
  54:                ActiveMQConnection.DEFAULT_BROKER_URL);
  55:        connection = connectionFactory.createConnection();
  56:        connection.start();
  57:        session = connection.createSession(transacted, Session.AUTO_ACKNOWLEDGE);
  58:        destination = session.createQueue("mmy first active mq queue");
  59:    }
  60:
  61:    private static void createProducerAndSendAMessage() throws JMSException {
  62:        MessageProducer producer = session.createProducer(destination);
  63:        producer.setDeliveryMode(DeliveryMode.NON_PERSISTENT);
  64:        TextMessage message = session.createTextMessage("Hello World!");
  65:        System.out.println("Sending message: " + message.getText());
  66:        producer.send(message);
  67:    }
  68:
  69:    private static void createConsumerAndReceiveAMessage() throws JMSException, InterruptedException {
  70:        connection = connectionFactory.createConnection();
  71:        connection.start();
  72:        MessageConsumer consumer = session.createConsumer(destination);
  73:        MyConsumer myConsumer = new MyConsumer();
  74:        connection.setExceptionListener(myConsumer);
  75:        consumer.setMessageListener(myConsumer);
  76:    }
  77:
  78:    private static class MyConsumer implements MessageListener, ExceptionListener {
  79:
  80:        synchronized public void onException(JMSException ex) {
  81:            System.out.println("JMS Exception occured.  Shutting down client.");
  82:            System.exit(1);
  83:        }
  84:
  85:        public void onMessage(Message message) {
  86:            if (message instanceof TextMessage) {
  87:                TextMessage textMessage = (TextMessage) message;
  88:                try {
  89:                    System.out.println("Received message: " + textMessage.getText());
  90:                } catch (JMSException ex) {
  91:                    System.out.println("Error reading message: " + ex);
  92:                }
  93:            } else  {
  94:                System.out.println("Received: " + message);
  95:            }
  96:        }
  97:    }
  98:}

Technorati Tags:

Posted by gisbert.amm at 12:07 AM in SOA

Montag, 15 September 2008

Camel-Routen visualisieren

1. Neuesten Stand der Camel-Sourcen holen und bauen

Wir werden jetzt kleinere Features von Camel benutzen, die es im Release 1.4.0 noch nicht gibt (z.B. den Ablageort des Camel-Contextes zu konfigurieren). Deshalb ist es Zeit, die Camel-Sourcen auszuchecken und die aktuelle Version selbst zu bauen:

svn co https://svn.apache.org/repos/asf/activemq/camel/trunk camel
set MAVEN_OPTS=-Xmx512m -XX:MaxPermSize=128m
mvn install -Dtest=false

(vgl. http://activemq.apache.org/camel/building.html)

Das dauert eine Weile. In der Zwischenzeit können wir unser Projekt anpassen.

2. POM anpassen

Zunächst zentralisieren wir die Camel-Versionsangabe an einer Stelle, damit wir bei der nächsten Versionsänderung nur diese anpassen müssen. Dazu fügen wir der POM auf Hauptebene diesen Eintrag hinzu:

property.xml

   1:<properties>
   2:        <camel.version>1.5-SNAPSHOT</camel.version>
   3:</properties>

Nun können wir alle Vorkommen der Camel-Versionsnummer durch eine Referenz auf diese Property (${camel.version}) ersetzen, im vi z.B. mittels
%s,1.4.0,${camel.version},g

Wir ergänzen folgende Dependency, damit das Maven Camel-Plugin den Spring-Kontext laden kann:

dependency.xml

   1:<dependency>
   2:        <groupId>org.apache.camel</groupId>
   3:        <artifactId>camel-spring</artifactId>
   4:        <version>${camel.version}</version>
   5:</dependency>
   6:

In den <build><plugins>-Abschnitt fügen wir diese Konfiguration ein:

plugin-eintrag-build.xml

   1:<plugin>
   2:        <groupId>org.apache.camel</groupId>
   3:        <artifactId>camel-maven-plugin</artifactId>
   4:        <version>${camel.version}</version>
   5:        <configuration>
   6:                <fileApplicationContextUri>src/main/webapp/WEB-INF/spring-context.xml</fileApplicationContextUri>
   7:        </configuration>
   8:</plugin>
   9:

Der Parameter <fileApplicationContextUri> ist einer der Gründe, warum Camel 1.5 benötigt wird (dieser Code wurde von den Camel-Entwicklern am 1. September 2008 eingebaut).

Außerdem fügen wir einen Reporting-Abschnitt ein:

plugin-eintrag-reporting.xml

   1:<reporting>
   2:        <plugins>
   3:                <plugin>
   4:                        <groupId>org.apache.camel</groupId>
   5:                        <artifactId>camel-maven-plugin</artifactId>
   6:                        <version>${camel.version}</version>
   7:                </plugin>
   8:        </plugins>
   9:</reporting>
  10:

Damit sind die Vorbereitungen abgeschlossen und wir können die Visualisierung der Route erstellen.

3. Visualisierung der Route mit GraphViz

Sobald Maven mit dem Kompilieren und Installieren von Camel 1.5-SNAPSHOT fertig ist, können wir mit mvn camel:dot eine graphische Repräsentation der Route erstellen. Dazu muss dot auf dem Rechner installiert sein (Doku dazu findet sich unter http://activemq.apache.org/camel/camel-maven-plugin.html und http://activemq.apache.org/camel/visualisation.html). Die graphische Darstellung der Route wird nach target/site/cameldoc generiert und sieht zunächst so aus:

Das ist weder sehr schön noch besonders praktikabel; aber da Camel GraphViz benutzt, kann man die Routen mit relativ wenig Aufwand nachbearbeiten. Die Datei target/site/cameldoc/routes.dot sieht etwa so aus:

routes.dot

   1:digraph CamelRoutes {
   2:
   3:node [style = "rounded,filled", fillcolor = yellow, fontname="Helvetica-Oblique"];
   4:
   5:subgraph cluster_0 {
   6:label = "Camel Routes";
   7:color = grey;
   8:style = "dashed";
   9:URL = "Camel Routes.html";
  10:
  11:
  12:node1 [
  13:label = "cxf:bean:helloEndpoint"
  14:tooltip = "cxf:bean:helloEndpoint"
  15:URL = "http://activemq.apache.org/camel/message-endpoint.html"
  16:];
  17:
  18:
  19:node2 [
  20:label = "Interceptor Ref"
  21:tooltip = "Interceptor Ref: Delegate(DeadLetterChannel[Delegate(TraceInterceptor[To[bean:myCamelProcessor]]), RecipientList[log:org.apache.camel.DeadLetterChannel?level=error], RedeliveryPolicy[maximumRedeliveries=5, initialRedeliveryDelay=1000, maximumRedeliveryDelay=60000, useExponentialBackOff=false, backOffMultiplier=2.0, useCollisionAvoidance=false, collisionAvoidanceFactor=0.15]])"
  22:URL = "http://activemq.apache.org/camel/interceptor-ref.html"
  23:shape = "box"
  24:];
  25:
  26:node1 -> node2 [
  27:];
  28:
  29:node3 [
  30:label = "bean:myCamelProcessor"
  31:tooltip = "bean:myCamelProcessor"
  32:URL = "http://activemq.apache.org/camel/message-endpoint.html"
  33:];
  34:
  35:node2 -> node3 [
  36:label = "Delegate(DeadLetterChannel[Delegate(TraceInterceptor[To[bean:myCamelProcessor]]), RecipientList[log:org.apache.camel.DeadLetterChannel?level=error], RedeliveryPolicy[maximumRedeliveries=5, initialRedeliveryDelay=1000, maximumRedeliveryDelay=60000, useExponentialBackOff=false, backOffMultiplier=2.0, useCollisionAvoidance=false, collisionAvoidanceFactor=0.15]])"
  37:];
  38:
  39:}
  40:
  41:}

Die Labels sind etwas geschwätzig; das läßt sich jedoch leicht ändern, indem man den Text großzügig kürzt. Außerdem kann man von http://activemq.apache.org/camel/images/eip/ die passenden Bildchen herunterladen und mit image = "<Pfad im Dateisystem> in die Grafik einarbeiten (GraphViz kann leider aktuell nicht mit HTTP-URLs umgehen). Die resultierende Datei sieht z.B. so aus:

routes.dot

   1:digraph CamelRoutes {
   2:
   3:node [fontname="Helvetica-Oblique", fontsize="10", fontcolor="red"];
   4:
   5:subgraph cluster_0 {
   6:label = "Camel Routes";
   7:color = grey;
   8:style = "dashed";
   9:URL = "Camel Routes.html";
  10:
  11:
  12:node1 [
  13:label = "cxf:bean:helloEndpoint"
  14:labelloc = "t"
  15:tooltip = "cxf:bean:helloEndpoint"
  16:URL = "http://activemq.apache.org/camel/message-endpoint.html"
  17:shape = "box"
  18:image = "images/MessageEndpointIcon.png"
  19:];
  20:
  21:
  22:node2 [
  23:label = "Interceptor Ref"
  24:tooltip = "TraceInterceptor"
  25:URL = "http://activemq.apache.org/camel/interceptor-ref.html"
  26:shape = "box"
  27:image = "images/WireTapIcon.png"
  28:];
  29:
  30:node1 -> node2 [
  31:label = "Logging"
  32:];
  33:
  34:node3 [
  35:label = "bean:myCamelProcessor"
  36:tooltip = "bean:myCamelProcessor"
  37:URL = "http://activemq.apache.org/camel/message-endpoint.html"
  38:shape = "box"
  39:image = "images/MessageTranslatorIcon.png"
  40:];
  41:
  42:node2 -> node3 [
  43:];
  44:
  45:}
  46:
  47:}

Und das Bildchen, das dabei herauskommt, kann sich schon eher sehen lassen.

Technorati Tags:

Posted by gisbert.amm at 9:16 PM in SOA

Freitag, 12 September 2008

SOAP Service Testing

Recently I looked for an easy and trivial way for testing webservices at junit tests. One way is the jetty servlet container which is runnable as ambedded server at java source code.

(1) First you have to define the content of your soap request. An example could be:

   1:<soapenv:Envelope 
   2:  xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" 
   3:  xmlns:xsd="http://www.w3.org/2001/XMLSchema" 
   4:  xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
   5:  <soapenv:Body>
   6:    <ns1:sayHello soapenv:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/" xmlns:ns1="http://127.0.0.1:40406/hello">
   7:      <integer href="#id0"/>
   8:    </ns1:sayHello>
   9:    <multiRef id="id0" soapenc:root="0" soapenv:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/" 
  10:      xsi:type="xsd:long" xmlns:soapenc="http://schemas.xmlsoap.org/soap/encoding/">Rafael</multiRef>
  11:  </soapenv:Body>
  12:</soapenv:Envelope>

(2) Equivalent Axis Service Call mechanism, that generates the soap content above:

JavaCall.java
   1:Call c = new Call(serviceURL + "/hello");
   2:c.addParameter("string", new QName("http://www.w3.org/2001/XMLSchema", "string"), ParameterMode.IN);
   3:c.setReturnType(new QName(serviceURL + "/Server", "string"));
   4:Object o = c.invoke(serviceURL + "/hello", "sayHello", new String[]{"Rafael"});
   5:String returnString = o.toString();

(3) Second you define the response soap content. An example could be:

soap-response.xml
   1:<?xml version="1.0" encoding="UTF-8"?>
   2:<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
   3:        <soapenv:Body>
   4:                <ns1:sayHello soapenv:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/" xmlns:ns1="http://127.0.0.1:40406/hello">
   5:                        <hello href="#id0"/>
   6:                </ns1:sayHello>
   7:                <multiRef id="id0" soapenc:root="0" soapenv:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/" xsi:type="xsd:string" xmlns:soapenc="http://schemas.xmlsoap.org/soap/encoding/">Server: Hello Rafael</multiRef>
   8:        </soapenv:Body>
   9:</soapenv:Envelope>

(4) Then you implement a simple servlet, which generated the expected response which generic content:

ServletTest.java
   1:public class SimpleServlet extends HttpServlet { 
   2:
   3:    public void doProcess (HttpServletRequest req, HttpServletResponse res)
   4:        throws ServletException, IOException {
   5:        ServletOutputStream out = res.getOutputStream();
   6:        res.setContentType("text/xml");
   7:        out.print("... response soap code snippet + generic code ...");
   8:        out.close();
   9:    }
  10:    
  11:    public void doGet (HttpServletRequest req, HttpServletResponse res)
  12:        throws ServletException, IOException {
  13:            doProcess(req, res);
  14:    }
  15:    
  16:    public void doPost (HttpServletRequest req, HttpServletResponse res)
  17:        throws ServletException, IOException {
  18:            doProcess(req, res);
  19:    }
  20:
  21:    public String getServletInfo() {
  22:        return "A simple servlet";
  23:    }
  24:}

(5) Last you have to implement the junit test:

UnitTest.java
   1:public class TestSoap {
   2:
   3:    @Test
   4:    public testSoap() throws Exception {
   5:        ServletTester tester = new ServletTester();
   6:        tester.setContextPath("/");
   7:        tester.addServlet(ServletTest.class, "/*");
   8:        String serviceURL = 
   9:            tester.createSocketConnector(true);
  10:        tester.start();
  11:        
  12:        String soapRequest = "... first snippet, which will generated from second java snippet ...";
  13:        
  14:        //second axis call snippet with the service url
  15:        
  16:        assertEquals("Server: Hello Rafael",response.getContent());
  17:    }
  18:} 

Regards Rafael Sobek

Technorati Tags:

Posted by rafael.sobek at 10:36 PM in SOA

Donnerstag, 11 September 2008

Zum Spring-CXF-Service Routing mit Apache Camel hinzufügen

Um zu dem neulich erstellten Spring-CXF-Service Routing per Apache Camel hinzuzufügen, sind folgende Schritte nötig:

1. POM anpassen

pom-schnipsel.xml

   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

spring-config.xml

   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

MyCamelProcessor.java

   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

wsdl.xml

   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)

SOAP-request.xml

   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

SOAP-response..xml

   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>

Posted by gisbert.amm at 11:18 PM in SOA

Donnerstag, 4 September 2008