Announcement Announcement Module
Collapse
No announcement yet.
Help with echo example Page Title Module
Move Remove Collapse
X
Conversation Detail Module
Collapse
  • Filter
  • Time
  • Show
Clear All
new posts

  • Help with echo example

    Trying my first Spring web service, downloaded the sample code. Have a few questions.

    \WEB-INF\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">
    
    <bean id="echoEndpoint" class="echo.endpoint.EchoEndpoint">
    	<property name="echoService"><ref bean="echoService"/></property>
    </bean>
    
    <bean id="echoService" class="echo.service.impl.EchoServiceImpl"/>
    
    <bean class="org.springframework.ws.server.endpoint.mapping.PayloadRootQNameEndpointMapping">
    	<property name="mappings">
    	<props>
    	<prop key="{http://localhost:9080}EchoRequest">echoEndpoint</prop>
    	</props>
    	</property>
    	<property name="interceptors">
    	<bean
    	class="org.springframework.ws.server.endpoint.interceptor.PayloadLoggingInterceptor"
    	/>
    	</property>
    </bean>
    
    <bean id="echo" 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/echo.xsd"/>
    	<property name="portTypeName" value="Echo"/>
    	<property name="locationUri" value="http://localhost:9080/echoservice/"/>
    	</bean>
    	</property>
    </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">
    
    <display-name>Echo Web Service Application</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>/*</url-pattern>
    </servlet-mapping>
    
    </web-app>
    WEB-INF\echo.xsd

    Code:
    <?xml version="1.0" encoding="UTF-8"?>
    <schema xmlns="http://www.w3.org/2001/XMLSchema" elementFormDefault="qualified" attributeFormDefault="qualified"
            targetNamespace="http://www.springframework.org/spring-ws/samples/echo"
            xmlns:tns="http://www.springframework.org/spring-ws/samples/echo">
    
        <element name="echoRequest">
            <simpleType>
                <restriction base="string">
                    <pattern value="([A-Z]|[a-z])+"/>
                </restriction>
            </simpleType>
        </element>
    
        <element name="echoResponse" type="string"/>
    </schema>
    Code:
    package echo.endpoint;
    
    import echo.service.EchoService;
    import org.w3c.dom.Document;
    import org.w3c.dom.Element;
    import org.springframework.ws.server.endpoint.AbstractDomPayloadEndpoint;
    
    public class EchoEndpoint extends AbstractDomPayloadEndpoint {
    
    private EchoService echoService;
    
    public void setEchoService(EchoService echoService) {
    	this.echoService = echoService;
    }
    
    @Override
    protected Element invokeInternal(Element arg0, Document arg1) throws Exception {
    	//Dummy code
    	echoService.echo("abc");
    	return null;
    }
    
    }
    Code:
    package echo.service;
    
    public interface EchoService {
    	public String echo(java.lang.String name);
    
    }
    Code:
    package echo.service.impl;
    
    import java.text.SimpleDateFormat;
    import java.util.Calendar;
    
    import echo.service.EchoService;
    
    public class EchoServiceImpl implements EchoService {
    
    	public String echo(String name) {
    		if (name == null || name.trim().length() == 0) {
    			return "echoing back: -provide a name-";
    		}
    		SimpleDateFormat dtfmt = new SimpleDateFormat("MM-dd-yyyy hh:mm:ss a");
    		return "echoing back: name " + name + " received on date " + dtfmt.format(Calendar.getInstance().getTime());
    	}
    }
    That being the code, following are my questions:

    1. Is my prop-key configuration in spring-ws-servlet.xml incorrect?

    2. Do I need to modify the echo.sxd namespace?

    3. Should I be able to see the wsdl under: http://localhost:9080/spring-ws/echo.wsdl

    If I type the above in browser, it gives error as: Error 404: No target servlet configured for uri: /spring-ws/echo.wsdl

    I read the documentation, tutorial etc.

    Please advise on what I am missing.

  • #2
    As you guessed, the prop-key entry is incorrect. It should be:
    <prop key="{http://www.springframework.org/spring-ws/samples/echo}echoRequest">echoEndpoint</prop>

    You need to put the XML namespace and the request name (case-sensitive) as defined in the XSD in the prop-key above.

    Also you seem to have got the WSDL url wrong. It should be:
    <host-name(with port number if required)>/<application-name>/<wsdl-bean-name>.wsdl
    I think your application name is "echoservice" and not "spring-ws". Just have a look at it, and change accordingly. It should be like this:
    http://localhost:9080/echoservice/echo.wsdl

    Comment


    • #3
      Echo Example for beginner- without autowiring, annotation etc.

      I made some modifications to the sample code to make it work for me. It might help a new starter. Following are the steps:

      Create a project (e.g. Dynamic Web Project) e.g. MyEcho. So the context root is MyEcho. Application runs under: http://localhost:9080/MyEcho

      Put all the jar files found from spring web services module in the classpath.

      Under src folder, create the of the Java project, create the following classes:

      Code:
      package org.springframework.ws.samples.echo.service;
      
      public interface EchoService {
      
          String echo(String s);
      }
      Code:
      package org.springframework.ws.samples.echo.service.impl;
      
      import org.springframework.ws.samples.echo.service.EchoService;
      
      public class EchoServiceImpl implements EchoService {
      
          public String echo(String s) {
              return s;
          }
      }
      This will require more work. Never the less, invokeInternal method does get executed by the Cleint program.

      Code:
      package org.springframework.ws.samples.echo.ws;
      
      import javax.xml.parsers.DocumentBuilder;
      import javax.xml.parsers.DocumentBuilderFactory;
      import javax.xml.parsers.ParserConfigurationException;
      
      import org.springframework.util.Assert;
      import org.springframework.ws.samples.echo.service.EchoService;
      import org.springframework.ws.server.endpoint.AbstractDomPayloadEndpoint;
      
      import org.w3c.dom.Document;
      import org.w3c.dom.Element;
      import org.w3c.dom.Node;
      import org.w3c.dom.NodeList;
      import org.w3c.dom.Text;
      
      public class EchoEndpoint extends AbstractDomPayloadEndpoint{
      
           public EchoEndpoint() {
        
          }
               @Override
      	protected Element invokeInternal(Element arg0, Document arg1)
      			throws Exception {
      		System.out.println("xyz");
      		return null;
      	}
      }
      Under WebContent\WEB-INF directory, create echo.xsd as:

      Code:
      <?xml version="1.0" encoding="UTF-8"?>
      <schema xmlns="http://www.w3.org/2001/XMLSchema" elementFormDefault="qualified" attributeFormDefault="qualified"
              targetNamespace="http://www.springframework.org/spring-ws/samples/echo"
              xmlns:tns="http://www.springframework.org/spring-ws/samples/echo">
      
          <element name="echoRequest">
              <simpleType>
                  <restriction base="string">
                      <pattern value="([A-Z]|[a-z])+"/>
                  </restriction>
              </simpleType>
          </element>
      
          <element name="echoResponse" type="string"/>
      </schema>
      Under WebContent\WEB-INF\web.xml, code as:

      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">
      
      <display-name>Echo Web Service Application</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>/*</url-pattern>
      </servlet-mapping>
      </web-app>
      The name of the servlet chosen arbitrarily as "spring-ws", as found in web.xml. Create an XML file with the name of the servlet (named arbitrarily). The name of the new file to create will be spring-ws-servlet.xml, As such, create a file called spring-ws-servlet.xml under WebContent\WEB-INF directory.

      Under WebContent\WEB-INF directory, create spring-ws-servlet.xml as:

      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="echoEndpoint" class="org.springframework.ws.samples.echo.ws.EchoEndpoint">
      </bean>
      
      <bean class="org.springframework.ws.server.endpoint.mapping.PayloadRootQNameEndpointMapping">
      <property name="mappings">
      <props>
      <!-- echoRequest is the exact name found in WEB-INF\echo.xsd -->
      <prop key="{http://www.springframework.org/spring-ws/samples/echo}echoRequest">echoEndpoint</prop>
      </props>
      </property>
      <property name="interceptors">
      <bean
      class="org.springframework.ws.server.endpoint.interceptor.PayloadLoggingInterceptor"
      />
      </property>
      </bean>
      
      <bean id="echo" 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/echo.xsd"/>
      <property name="portTypeName" value="Echo"/> <!-- Port name can be arbitrary name chosen by you -->
      <property name="locationUri" value="http://localhost:9080/MyEcho/"/> <!--  MyEcho is context root of application, need to specify context root -->
      </bean>
      </property>
      </bean>
      </beans>
      Deploy your EAR file in the Application server and start your server. Depending on the application server of your choice, you may have a need to change the classloader mode of the EAR file deployed to PARENT_LAST and WAR classloader policy is Application. In the application.xml of the EAR file in the Deployment tab, you can choose the classloader policies.

      If your server and application deployed in the server starts successfully, you can see the WSDL by opening a browser and typing URL as:

      http://localhost:9080/MyEcho/echo.wsdl

      The content of the above echo.wsdl is:
      Code:
      <?xml version="1.0" encoding="UTF-8" ?> 
      - <wsdl:definitions xmlns:wsdl="http://schemas.xmlsoap.org/wsdl/" xmlns:schema="http://www.springframework.org/spring-ws/samples/echo" xmlns:soap="http://schemas.xmlsoap.org/wsdl/soap/" targetNamespace="http://www.springframework.org/spring-ws/samples/echo">
      - <wsdl:types>
      - <schema xmlns="http://www.w3.org/2001/XMLSchema" xmlns:tns="http://www.springframework.org/spring-ws/samples/echo" attributeFormDefault="qualified" elementFormDefault="qualified" targetNamespace="http://www.springframework.org/spring-ws/samples/echo">
      - <element name="echoRequest">
      - <simpleType>
      - <restriction base="string">
        <pattern value="([A-Z]|[a-z])+" /> 
        </restriction>
        </simpleType>
        </element>
        <element name="echoResponse" type="string" /> 
        </schema>
        </wsdl:types>
      - <wsdl:message name="echoResponse">
        <wsdl:part element="schema:echoResponse" name="echoResponse" /> 
        </wsdl:message>
      - <wsdl:message name="echoRequest">
        <wsdl:part element="schema:echoRequest" name="echoRequest" /> 
        </wsdl:message>
      - <wsdl:portType name="Echo">
      - <wsdl:operation name="echo">
        <wsdl:input message="schema:echoRequest" name="echoRequest" /> 
        <wsdl:output message="schema:echoResponse" name="echoResponse" /> 
        </wsdl:operation>
        </wsdl:portType>
      - <wsdl:binding name="EchoBinding" type="schema:Echo">
        <soap:binding style="document" transport="http://schemas.xmlsoap.org/soap/http" /> 
      - <wsdl:operation name="echo">
        <soap:operation soapAction="" /> 
      - <wsdl:input name="echoRequest">
        <soap:body use="literal" /> 
        </wsdl:input>
      - <wsdl:output name="echoResponse">
        <soap:body use="literal" /> 
        </wsdl:output>
        </wsdl:operation>
        </wsdl:binding>
      - <wsdl:service name="EchoService">
      - <wsdl:port binding="schema:EchoBinding" name="EchoPort">
        <soap:address location="http://localhost:9080/MyEcho/" /> 
        </wsdl:port>
        </wsdl:service>
        </wsdl:definitions>
      Next, you can write a client as follows:

      Code:
      package org.springframework.ws.samples.echo.ws;
      
      import java.io.StringReader;
      import javax.xml.transform.stream.StreamResult;
      import javax.xml.transform.stream.StreamSource;
      import org.springframework.ws.client.core.WebServiceTemplate;
      
      public class WebServiceClient {
      //echoRequest tag is defined in WEB-INF\echo.xsd
      	// http://www.springframework.org/spring-ws/samples/echo is the namespace defined in spring-ws-servlet.xml and echo.xsd
          private static final String MESSAGE =
          	 "<echoRequest xmlns=\"http://www.springframework.org/spring-ws/samples/echo\">Hello Web Service World</echoRequest>";
        
          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);
              boolean bool = webServiceTemplate.sendSourceAndReceiveToResult(source, result);
              System.out.println(bool);
          }
         
          public static void main(String[] args){
          	WebServiceClient client = new WebServiceClient();
          	client.setDefaultUri("http://localhost:9080/MyEcho");
          	client.simpleSendAndReceive();    	
          }	
      }
      This client code invoked the invokeInternal(..) method of the Endpoint class.

      However System.out.println(bool); shows bool as false. Any idea?

      Comment

      Working...
      X