Announcement Announcement Module
No announcement yet.
Custom EndpointMapping Page Title Module
Move Remove Collapse
Conversation Detail Module
  • Filter
  • Time
  • Show
Clear All
new posts

  • Custom EndpointMapping

    I have a special requirement where the service operation that needs to be performed will be part of a custom soap header. So, I have to parse the soap header and invoke the appropriate method on the endpoint. I thought doing this would be a few hours work but have been struggling for 3 days now. Can anyone please suggest how I can achieve this. I am using Spring WS 2.1.3 release. Here is what I tried
    Approach 1:
    1) I wrote a custom endpointmapping by extending SoapActionAnnotationMethodEndpointMapping and overriding getLookupKeyForMessage and getLookupKeyForMethod
    My endpointmapping does not even get registered and invoked in spite of adding to SoapMessageDispatcher endpointMappings property. I do see the endpoint getting created in the trace logs but it does not get invoked at runtime.

    Approach 2:
    2) I finally ended up doing a SimpleMethodEndpointMapping and having a single method being called always. I was hoping I could parse through the headers in that method and decide what service and operation to invoke. Two problems here:
    a) My method is getting invoked but I don't have handle to messagecontext and soap header.
    b) When I return Element, only the root node is returned ex:I intend to return
    <?xml version="1.0" encoding="UTF-8"?>
    <ServiceResponse>Hello World</ServiceResponse>
    But what I get back is
    <?xml version="1.0" encoding="UTF-8"?><ServiceResponse/>
    I tried various ways by using dom4j, jaxb w3c. I also tried returning stringsource&domsource from my method. Nothing seems to work.

    I am new to spring webservices. Any help is greatly appreciated. I am probably doing something wrong since I believe this should be a fairly common scenario. It has been very hard to find useful examples except the annotation ones.

  • #2
    Please post some code and configuration, without it it is hard to determine the case.


    • #3
      Hi Marten,
      Thanks for the response. I made some progress on the approach 1. My custom endpoint mapping is getting invoked now. I think the context:component-scan and sws:annotation-driven tags in the spring-ws-servlet.xml register some endpointmappings and prevent others from being registered. I got rid of those tags and now, my endpointmapping is getting invoked. But Still the response eats up all the child nodes. I get just the root element back in the soapbody. Here is the code....

      My Endpoint:
      public class INGServiceStubEndpoint {
      	public static final String NAMESPACE_URI = "";
      	public static final String SERVICE_RESPONSE_LOCAL_NAME = "serviceResponse";
      	private final DocumentBuilderFactory documentBuilderFactory = DocumentBuilderFactory
      	private INGServiceStub serviceStub;
      	public INGServiceStubEndpoint() {
      	public INGServiceStubEndpoint(INGServiceStub serviceStub) {
      		this.serviceStub = serviceStub;
      	@SoapAction ("GetPolicyInformation")
      	public @ResponsePayload
      	Element serviceGetPolRequest(@RequestPayload Element requestElement)
      			throws ParserConfigurationException {
      		DocumentBuilder documentBuilder = documentBuilderFactory
      		Document document = documentBuilder.newDocument();
      		Element responseElement = document.createElementNS(NAMESPACE_URI,
      		Text responseText = document.createTextNode("Hello");
      		System.out.println("Output XML from Endpoint: " + convertToString(responseElement));
      		return responseElement;
      	private String convertToString(Element responseElement){
      		String xmlString = null; 
      			Transformer transformer = TransformerFactory.newInstance().newTransformer();
      			transformer.setOutputProperty(OutputKeys.INDENT, "yes");
      			StreamResult result = new StreamResult(new StringWriter());
      			DOMSource source = new DOMSource(responseElement);
      			transformer.transform(source, result);
      			xmlString = result.getWriter().toString();
      			return xmlString;
      My spring-ws-servlet.xml
        	<bean id="messageDispatcher"
      		<property name="endpointMappings" ref="customEndpoingMapping">
        	<bean id="customEndpoingMapping"
      		<property name="defaultEndpoint" ref="myEndpoint"></property>
      	<bean id="myEndpoint" class="">
      	<sws:dynamic-wsdl id="serviceStub" portTypeName="ServiceStub"
      		<sws:xsd location="/WEB-INF/genericservice.xsd" />
      Output on Server side (JBoss 5.1 GA):
      2013-06-11 12:23:36,526 INFO  [STDOUT] (http- Output XML from Endpoint: <?xml version="1.0" encoding="UTF-8"?>
      <serviceResponse xmlns="">Hello</serviceResponse>2013-06-11 12:23:36,526 INFO  [STDOUT] (http- 2013-06-11 12:23:36,526 DEBUG [] - Response: <env:Envelope xmlns:env=""><env:Header/><env:Body><serviceResponse xmlns=""/></env:Body></env:Envelope>
      2013-06-11 12:23:36,526 INFO  [STDOUT] (http- 2013-06-11 12:23:36,526 DEBUG [] - Response: <serviceResponse xmlns=""/>
      2013-06-11 12:23:36,526 INFO  [STDOUT] (http- 2013-06-11 12:23:36,526 TRACE [] - Sent response [<env:Envelope xmlns:env=''><env:Header></env:Header><env:Body><serviceResponse xmlns=''/></env:Body></env:Envelope>] for request [<SOAP-ENV:Envelope xmlns:SOAP-ENV=''><SOAP-ENV:Header></SOAP-ENV:Header><SOAP-ENV:Body><GetPol xmlns=''>Hello Sandeep</GetPol></SOAP-ENV:Body></SOAP-ENV:Envelope>]
      2013-06-11 12:23:36,526 INFO  [STDOUT] (http- 2013-06-11 12:23:36,526 TRACE [] - Cleared thread-bound request context: [email protected]
      2013-06-11 12:23:36,526 INFO  [STDOUT] (http- 2013-06-11 12:23:36,526 DEBUG [] - Successfully completed request
      Last edited by Marten Deinum; Jun 12th, 2013, 12:45 AM. Reason: Added code tags.


      • #4
        Please use [ code][/code ] tags when posting code/xml/stacktraces that way it remains readable.

        I think the context:component-scan and sws:annotation-driven tags in the spring-ws-servlet.xml register some endpointmappings
        The sws-annotation-driven registers the default EndpointMapping classes, you can still add your own but you have to make sure that it fires before the default ones, ie you need to set the order property on your EndpointMapping class. The context:component-scan is needed to detect your @Endpoint classes and other @Component classes.


        • #5
          Update: I was finally able to get the proper response from the service instead of just the root element by adding this to my spring-ws-servlet.xml. The problem was with JBoss 5.1 GA SAAJ implementation. So I am good now. Thanks for the replies...

          	<bean id="messageFactory" class="">
              <property name="messageFactory">
                  <bean class="com.sun.xml.internal.messaging.saaj.soap.ver1_1.SOAPMessageFactory1_1Impl"/>