Announcement Announcement Module
Collapse
No announcement yet.
Creating a SOAP message/Beginners help Page Title Module
Move Remove Collapse
X
Conversation Detail Module
Collapse
  • Filter
  • Time
  • Show
Clear All
new posts

  • Creating a SOAP message/Beginners help

    I'm new to WS and have probably made a disaster in modifying the tutorial to meet my needs. The current issue is creating a SOAP message to send to the service. I based the client code from one of the examples, don't remember exactly where. Right now it has code from multiple attempts, so sorry for the mess.
    PersonLookupClient:
    Code:
    public class PersonLookupClient {
    
        private static final String MESSAGE = "<soap:Envelope xmlns:soap=\"http://schemas.xmlsoap.org/soap/envelope/\" "
                + "xmlns:xsd=\"http://www.w3.org/2001/XMLSchema\" " + "xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\">" + "<soap:Body>"
                + "<request xmlns=\"http://localhost:8080\">" + "     Hello" + " </request>" + " </soap:Body>" + "</soap:Envelope>";
    
        private static final String MESSAGE2 = "<PersonLookupRequest xmlns=\"http://localhost:8081/pl/schemas\">" + "<Name>An</Name>"
                + "</PersonLookupRequest>";
    
        private static final String MESSAGE3 = "<message xmlns=\"http://tempuri.org\">Hello Web Service World</message>";
        private static final String MESSAGE4 = "<?xml version=\"1.0\"?>" + "<request xmlns=\"http://localhost:8080\">" + "     Hello" + " </request>";
    
        private final WebServiceTemplate webServiceTemplate = new WebServiceTemplate();
    
        public void setDefaultUri(String defaultUri) {
    
            webServiceTemplate.setDefaultUri(defaultUri);
        }
    
        // send to the configured default URI
        public void simpleSendAndReceive() {
    
            StreamSource source = new StreamSource(new StringReader(MESSAGE));
            StreamResult result = new StreamResult(System.out);
    
            webServiceTemplate.sendSourceAndReceiveToResult(source, result);
        }
    
        // send to an explicit URI
        public void customSendAndReceive() {
    
            Resource r = new ByteArrayResource(MESSAGE.getBytes());
            // (MESSAGE4);
            Source requestSource = null;
            try {
                requestSource = new ResourceSource(r);
            }
            catch (IOException e) {
            }
    
            StreamSource source = new StreamSource(new StringReader(MESSAGE));
            StreamResult result = new StreamResult(System.out);
            webServiceTemplate.sendSourceAndReceiveToResult("http://localhost:8080/PersonLookup", requestSource, result);
        }
    
        public static void main(String[] args) {
    
            PersonLookupClient personLookupClient = new PersonLookupClient();
            personLookupClient.customSendAndReceive();
        }
    
    }
    Running it returns the exception:
    Code:
    Mar 3, 2008 10:52:48 AM INFO: Creating SAAJ 1.2 MessageFactory
    Exception in thread "main" org.springframework.ws.soap.saaj.SaajSoapEnvelopeException: Could not access envelope: org.xml.sax.SAXException: WSWS3066E: Error: Expected 'envelope' but found  link Message being parsed: ; nested exception is javax.xml.soap.SOAPException: org.xml.sax.SAXException: WSWS3066E: Error: Expected 'envelope' but found  link Message being parsed: 
    	at org.springframework.ws.soap.saaj.SaajSoapMessage.getEnvelope(SaajSoapMessage.java:90)
    	at org.springframework.ws.soap.AbstractSoapMessage.getSoapBody(AbstractSoapMessage.java:36)
    	at org.springframework.ws.soap.AbstractSoapMessage.getPayloadSource(AbstractSoapMessage.java:46)
    	at org.springframework.ws.client.core.WebServiceTemplate$SourceExtractorMessageExtractor.extractData(WebServiceTemplate.java:590)
    	at org.springframework.ws.client.core.WebServiceTemplate.sendAndReceive(WebServiceTemplate.java:417)
    	at org.springframework.ws.client.core.WebServiceTemplate.doSendAndReceive(WebServiceTemplate.java:359)
    	at org.springframework.ws.client.core.WebServiceTemplate.sendSourceAndReceiveToResult(WebServiceTemplate.java:305)
    	at org.springframework.ws.client.core.WebServiceTemplate.sendSourceAndReceiveToResult(WebServiceTemplate.java:290)
    	at com.farrow.ldap.service.PersonLookupClient.customSendAndReceive(PersonLookupClient.java:70)
    	at com.farrow.ldap.service.PersonLookupClient.main(PersonLookupClient.java:76)
    Caused by: javax.xml.soap.SOAPException: org.xml.sax.SAXException: WSWS3066E: Error: Expected 'envelope' but found  link Message being parsed: 
    	at com.ibm.ws.webservices.engine.SOAPPart.getEnvelope(SOAPPart.java:638)
    	at org.springframework.ws.soap.saaj.Saaj12Implementation.getEnvelope(Saaj12Implementation.java:142)
    	at org.springframework.ws.soap.saaj.SaajSoapMessage.getEnvelope(SaajSoapMessage.java:86)
    	... 9 more
    Caused by: org.xml.sax.SAXException: WSWS3066E: Error: Expected 'envelope' but found  link Message being parsed: 
    	at com.ibm.ws.webservices.engine.WebServicesFault.makeFault(WebServicesFault.java:206)
    	at com.ibm.ws.webservices.engine.SOAPPart._getSOAPEnvelope(SOAPPart.java:1062)
    	at com.ibm.ws.webservices.engine.SOAPPart.getAsSOAPEnvelope(SOAPPart.java:604)
    	at com.ibm.ws.webservices.engine.SOAPPart.getEnvelope(SOAPPart.java:632)
    	... 11 more
    I'm using Apache Tomcat to test the service on port 8080. The tutorial in different places had namespaces for localhost and for com.mycompany..., but since I'm not testing against the service, I changed the later to localhost:8081. I haven't been able to find the proper documentation explaining what I should be using for namespaces, and acknowledge that this could be a large part of the problem.

    Other resources:
    spring-ws-servlet.xml
    Code:
    <?xml version="1.0" encoding="UTF-8"?>
    <beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
           xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.0.xsd">
    
    	<bean id="personLookupEndpoint"
    		class="com.farrow.ldap.service.PersonLookupEndpoint">
    		<constructor-arg ref="plService" />
    	</bean>
    
    	<bean id="plService"
    		class="com.farrow.ldap.service.PersonLdapLookup" >
    		<property name="personDao" ref="plDao" />
    	</bean>
    		
    	<bean id="plDao"
    		class="com.farrow.ldap.dao.PersonDaoLdap" >
    		<property name="root" value="" />
    	</bean>
    
    	<bean
    		class="org.springframework.ws.server.endpoint.mapping.PayloadRootQNameEndpointMapping">
    		<property name="mappings">
    			<props>
    				<prop
    					key="{http://localhost:8080/pl/schemas}PersonLookupRequest">
    					personLookupEndpoint
    				</prop>
    			</props>
    		</property>
    		<property name="interceptors">
    			<bean
    				class="org.springframework.ws.server.endpoint.interceptor.PayloadLoggingInterceptor" />
    		</property>
    	</bean>
    
    	<bean id="person"
    		class="org.springframework.ws.wsdl.wsdl11.DynamicWsdl11Definition">
    
    		<property name="builder">
    			<bean
    				class="org.springframework.ws.wsdl.wsdl11.builder.XsdBasedSoap11Wsdl4jDefinitionBuilder">
    				<property name="schema" value="/WEB-INF/pl.xsd" />
    
    				<property name="portTypeName" value="NameResourcePort" />
    
    				<property name="locationUri"
    					value="http://localhost:8080/personLookupService/" />
    
    				<property name="targetNamespace"
    					value="http://localhost:8080/pl/definitions" />
    
    			</bean>
    		</property>
    	</bean>
    	
    	<bean id="webServiceClient" class="com.farrow.ldap.service.PersonLookupClient">
            <property name="defaultUri" value="http://localhost:8080/PersonLookup"/>
        </bean>
    	
    
    </beans>
    web.xml
    Code:
    <?xml version="1.0" encoding="UTF-8"?>
    
    <web-app xmlns="http://java.sun.com/xml/ns/j2ee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
             xsi:schemaLocation="http://java.sun.com/xml/ns/j2ee http://java.sun.com/xml/ns/j2ee/web-app_2_4.xsd"
             version="2.4">
    
        <display-name>RAF Person Lookup Service</display-name>
    
        <servlet>
            <servlet-name>spring-ws</servlet-name>
            <servlet-class>org.springframework.ws.transport.http.MessageDispatcherServlet</servlet-class>
        </servlet>
    
        <servlet-mapping>
            <servlet-name>spring-ws</servlet-name>
            <url-pattern>/PersonLookup*</url-pattern>
        </servlet-mapping>
    
    </web-app>
    pl.wsdl
    Code:
    <?xml version="1.0" encoding="UTF-8"?>
    <wsdl:definitions xmlns:wsdl="http://schemas.xmlsoap.org/wsdl/"
                      xmlns:soap="http://schemas.xmlsoap.org/wsdl/soap/"
                      xmlns:schema="http://localhost:8081/pl/schemas"
                      xmlns:tns="http://localhost:8081/pl/definitions"
                      targetNamespace="http://localhost:8081/pl/definitions">
        <wsdl:types>
            <xsd:schema xmlns:xsd="http://www.w3.org/2001/XMLSchema">
                <xsd:import namespace="http://localhost:8081/pl/schemas" schemaLocation="pl.xsd"/>
            </xsd:schema>
        </wsdl:types>
        <wsdl:message name="PersonLookup">
            <wsdl:part element="schema:PersonLookupRequest" name="PersonLookup">
            </wsdl:part>
        </wsdl:message>
        <wsdl:portType name="NameResourcePort">
            <wsdl:operation name="Lookup">
                <wsdl:input message="tns:PersonLookup" name="PersonLookup">
                </wsdl:input>
            </wsdl:operation>
        </wsdl:portType>
        <wsdl:binding name="NameResourceBinding" type="tns:NameResourcePort">
            <soap:binding style="document" transport="http://schemas.xmlsoap.org/soap/http"/>
            <wsdl:operation name="Lookup">
                <soap:operation soapAction=""/>
                <wsdl:input name="PersonLookup">
                    <soap:body use="literal"/>
                </wsdl:input>
            </wsdl:operation>
        </wsdl:binding>
        <wsdl:service name="PersonLdapLookup">
            <wsdl:port binding="tns:NameResourceBinding" name="NameResourcePort">
                <soap:address location="http://localhost:8080/personLookupService/"/>
            </wsdl:port>
        </wsdl:service>
    </wsdl:definitions>
    Any help sorting this out is appreciated

  • #2
    Alright, I found an example for creating/sending a SOAP message. Now the client looks like this: (the two methods are different means to the same end)
    Code:
    package com.farrow.ldap.service;
    
    
    import java.net.URL;
    
    import javax.xml.soap.MessageFactory;
    import javax.xml.soap.Name;
    import javax.xml.soap.SOAPBody;
    import javax.xml.soap.SOAPBodyElement;
    import javax.xml.soap.SOAPConnection;
    import javax.xml.soap.SOAPConnectionFactory;
    import javax.xml.soap.SOAPElement;
    import javax.xml.soap.SOAPEnvelope;
    import javax.xml.soap.SOAPHeader;
    import javax.xml.soap.SOAPMessage;
    import javax.xml.soap.SOAPPart;
    import javax.xml.transform.Source;
    import javax.xml.transform.Transformer;
    import javax.xml.transform.TransformerFactory;
    import javax.xml.transform.stream.StreamResult;
    
    import org.springframework.ws.client.core.WebServiceTemplate;
    
    
    
    public class PersonLookupClient {
    
    
        private final WebServiceTemplate webServiceTemplate = new WebServiceTemplate();
    
        public void setDefaultUri(String defaultUri) {
    
            webServiceTemplate.setDefaultUri(defaultUri);
        }
    
    
        // send to an explicit URI
        public void customSendAndReceive() {
    
    
            try {
    
                // First create the connection
                SOAPConnectionFactory soapConnFactory = SOAPConnectionFactory.newInstance();
                SOAPConnection connection = soapConnFactory.createConnection();
    
                // Next, create the actual message
                MessageFactory messageFactory = MessageFactory.newInstance();
                SOAPMessage message = messageFactory.createMessage();
    
                // Create objects for the message parts
                SOAPPart soapPart = message.getSOAPPart();
                SOAPEnvelope envelope = soapPart.getEnvelope();
                SOAPBody body = envelope.getBody();
    
                // Populate the body
                // Create the main element and namespace
                // SOAPElement bodyElement = body.addChildElement(envelope.createName("getPrice", "ns1", "urn:xmethods-BNPriceCheck"));
                // Add content
                // bodyElement.addChildElement("isbn").addTextNode("0672324229");
    
                // Save the message
                message.saveChanges();
    
    
                // Check the input
                System.out.println("\nREQUEST:\n");
                message.writeTo(System.out);
                System.out.println();
    
                // Populate the Message
                // StreamSource preppedMsgSrc = new StreamSource(new FileInputStream("prepped.msg"));
                // soapPart.setContent(preppedMsgSrc);
    
    
                // Send the message and get a reply
    
                // Set the destination
                String destination = "http://localhost:8080/PersonLookup";
                // Send the message
                SOAPMessage reply = connection.call(message, destination);
    
    
                // Check the output
                System.out.println("\nRESPONSE:\n");
                // Create the transformer
                TransformerFactory transformerFactory = TransformerFactory.newInstance();
                Transformer transformer = transformerFactory.newTransformer();
                // Extract the content of the reply
                Source sourceContent = reply.getSOAPPart().getContent();
                // Set the output for the transformation
                StreamResult result = new StreamResult(System.out);
                transformer.transform(sourceContent, result);
                System.out.println();
    
                // Close the connection
                connection.close();
    
            }
            catch (Exception e) {
                System.out.println(e.getMessage());
            }
    
    
    
            // StreamSource source = new StreamSource(new StringReader(new SaajSoapMessage(soapMessage).toString()));
            // StreamResult result = new StreamResult(System.out);
            // webServiceTemplate.sendSourceAndReceiveToResult("http://localhost:8080/PersonLookup", source, result);
        }
    
        public void customSendAndReceive2() {
    
            try {
                // Create a SOAPConnection
                SOAPConnectionFactory factory = SOAPConnectionFactory.newInstance();
    
                SOAPConnection connection = factory.createConnection();
    
                // Create a SOAPMessage
                MessageFactory messageFactory = MessageFactory.newInstance();
                SOAPMessage message = messageFactory.createMessage();
                SOAPPart soapPart = message.getSOAPPart();
                SOAPEnvelope envelope = soapPart.getEnvelope();
                SOAPHeader header = envelope.getHeader();
                SOAPBody body = envelope.getBody();
                header.detachNode();
    
                // Create a SOAPBodyElement
                Name bodyName = envelope.createName("PersonLookupRequest", "pl", "http://localhost:8081/pl/schemas");
                SOAPBodyElement bodyElement = body.addBodyElement(bodyName);
                // Insert Content
                Name name = envelope.createName("Name");
                SOAPElement symbol = bodyElement.addChildElement(name);
                symbol.addTextNode("SUNW");
    
                // Create an endpint point which is either URL or String type
                URL endpoint = new URL("http://localhost:8080/PersonLookup");
    
                // Check the input
                System.out.println("\nREQUEST:\n");
                message.writeTo(System.out);
                System.out.println();
    
                // Send a SOAPMessage (request) and then wait for SOAPMessage (response)
                SOAPMessage response = connection.call(message, endpoint);
    
                System.out.println("\nRESPONSE:\n");
                // Create the transformer
                TransformerFactory transformerFactory = TransformerFactory.newInstance();
                Transformer transformer = transformerFactory.newTransformer();
                // Extract the content of the reply
                Source sourceContent = response.getSOAPPart().getContent();
                // Set the output for the transformation
                StreamResult result = new StreamResult(System.out);
                transformer.transform(sourceContent, result);
                System.out.println();
    
                // Close the SOAPConnection
                connection.close();
    
            }
            catch (Exception e) {
                System.out.println(e.getMessage());
            }
    
    
        }
    
        public static void main(String[] args) {
    
            PersonLookupClient personLookupClient = new PersonLookupClient();
            personLookupClient.customSendAndReceive2();
        }
    
    }
    Running either method gives the following output:
    Code:
    Mar 4, 2008 10:07:35 AM org.springframework.ws.soap.saaj.SaajSoapMessageFactory afterPropertiesSet
    INFO: Creating SAAJ 1.2 MessageFactory
    
    Mar 4, 2008 10:07:38 AM com.ibm.ws.ssl.config.SSLConfigManager
    INFO: ssl.disable.url.hostname.verification.CWPKI0027I
    Mar 4, 2008 10:07:39 AM com.ibm.ws.webservices.engine.transport.http.HttpOutboundChannelConnection
    SEVERE: WSWS3514E: No HTTP response body is available from the connection for: http://localhost:8080/PersonLookup
    I'm assuming it's related either to an incorrect namespace or a malformed message (ie the message doesn't get to the endpoint).

    Ideas?

    Thanks

    Comment

    Working...
    X