We are trying to build a web service here. We want the service to be available at /axis2/services/SmsNotificationService
. The operation that will be invoked is notifySmsDeliveryReceipt
. The following is Spring's endpoint.
import org.jdom.Document;
import org.jdom.Element;
import org.jdom.JDOMException;
import org.jdom.input.SAXBuilder;
import org.springframework.ws.server.endpoint.annotation.Endpoint;
import org.springframework.ws.server.endpoint.annotation.PayloadRoot;
import org.springframework.ws.server.endpoint.annotation.RequestPayload;
import org.springframework.ws.server.endpoint.annotation.ResponsePayload;
import org.springframework.ws.soap.addressing.server.annotation.Action;
import java.io.IOException;
import java.io.StringReader;
@Endpoint
public class SmsNotificationService {
@Action("http://axis2/services/SmsNotificationService")
@PayloadRoot(localPart = "notifySmsDeliveryReceipt", namespace = "http://www.csapi.org/schema/parlayx/sms/notification/v3_1/local")
@ResponsePayload
public Element handleNotifyReceipt(@RequestPayload Element root) {
String correlator = root.getChild("correlator").getValue();
Element deliveryStatusElement = root.getChild("deliveryStatus");
String address = deliveryStatusElement.getChild("address").getValue();
String deliveryStatus = deliveryStatusElement.getChild("deliveryStatus").getValue();
System.out.println("correlator: " + correlator);
System.out.println("address: " + address);
System.out.println("deliveryStatus: " + deliveryStatus);
String s="<soapenv:Envelope xmlns:soapenv=\u2018http://schemas.xmlsoap.org/soap/envelope/\u2019 xmlns:loc=\u2018http://www.csapi.org/schema/parlayx/sms/notification/v3_1/local\u2019>\n"+
"<soapenv:Header/>\n"+
"<soapenv:Body>\n"+
"<loc:notifySmsDeliveryReceiptResponse/>\n"+
"</soapenv:Body>\n"+
"</soapenv:Envelope>";
SAXBuilder sxBuild = new SAXBuilder();
Document doc;
Element returnRoot = null;
try {
doc = sxBuild.build(new StringReader(s));
returnRoot = doc.getRootElement();
} catch (JDOMException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
return returnRoot;
}
}
The client will invoke the service using this XML.
<soapenv:Envelope xmlns:soapenv=‘http://schemas.xmlsoap.org/soap/envelope/’ xmlns:v3=‘http://www.csapi.org/schema/parlayx/common/v3_1’ xmlns:loc=‘http://www.csapi.org/schema/parlayx/sms/notification/v3_1/local’>
<soapenv:Header>
<v3:NotifySOAPHeader>
<spId>600002</spId>
</v3:NotifySOAPHeader>
</soapenv:Header>
<soapenv:Body>
<loc:notifySmsDeliveryReceipt>
<loc:correlator>123</loc:correlator>
<loc:deliveryStatus>
<address>tel:+86123</address>
<deliveryStatus>DeliveredToTerminal</deliveryStatus>
</loc:deliveryStatus>
</loc:notifySmsDeliveryReceipt>
</soapenv:Body>
</soapenv:Envelope>
The service needs to return this XML:
<soapenv:Envelope xmlns:soapenv=‘http://schemas.xmlsoap.org/soap/envelope/’ xmlns:loc=‘http://www.csapi.org/schema/parlayx/sms/notification/v3_1/local’>
<soapenv:Header/>
<soapenv:Body>
<loc:notifySmsDeliveryReceiptResponse/>
</soapenv:Body>
</soapenv:Envelope>
Tomcat's access log registers a service call but the remote caller received an error:
`xxx.xx.xxx.x - - [13/May/2016:13:43:43 +0630] "POST /axis2/services/SmsNotificationService HTTP/1.1" 404 -`
Catalina's log shows the following:
13-May-2016 13:42:32.459 INFO [http-nio-8088-exec-6] org.springframework.ws.soap.addressing.server.AbstractAddressingEndpointMapping.afterPropertiesSet Supporting [WS-Addressing August 2004, WS-Addressing 1.0]
13-May-2016 13:42:32.487 INFO [http-nio-8088-exec-6] org.springframework.beans.factory.support.DefaultListableBeanFactory.preInstantiateSingletons Pre-instantiating singletons in org.springframework.beans.factory.support.DefaultListableBeanFactory@2e8571ab: defining beans [org.springframework.ws.server.endpoint.mapping.PayloadRootAnnotationMethodEndpointMapping#0,org.springframework.ws.soap.server.endpoint.mapping.SoapActionAnnotationMethodEndpointMapping#0,org.springframework.ws.soap.addressing.server.AnnotationActionEndpointMapping#0,org.springframework.ws.server.endpoint.adapter.method.dom.DomPayloadMethodProcessor#0,org.springframework.ws.server.endpoint.adapter.method.SourcePayloadMethodProcessor#0,org.springframework.ws.server.endpoint.adapter.method.dom.Dom4jPayloadMethodProcessor#0,org.springframework.ws.server.endpoint.adapter.method.jaxb.XmlRootElementPayloadMethodProcessor#0,org.springframework.ws.server.endpoint.adapter.method.jaxb.JaxbElementPayloadMethodProcessor#0,org.springframework.ws.server.endpoint.adapter.method.dom.XomPayloadMethodProcessor#0,org.springframework.ws.server.endpoint.adapter.DefaultMethodEndpointAdapter#0,org.springframework.ws.soap.server.endpoint.SoapFaultAnnotationExceptionResolver#0,org.springframework.ws.soap.server.endpoint.SimpleSoapExceptionResolver#0]; root of factory hierarchy
13-May-2016 13:42:32.764 INFO [http-nio-8088-exec-6] org.springframework.ws.soap.saaj.SaajSoapMessageFactory.afterPropertiesSet Creating SAAJ 1.3 MessageFactory with SOAP 1.1 Protocol
13-May-2016 13:42:32.784 INFO [http-nio-8088-exec-6] org.springframework.web.servlet.FrameworkServlet.initServletBean FrameworkServlet 'spring-ws': initialization completed in 2448 ms
13-May-2016 13:43:43.774 WARNING [http-nio-8088-exec-8] org.springframework.ws.server.MessageDispatcher.dispatch No endpoint mapping found for [SaajSoapMessage {http://www.csapi.org/schema/parlayx/sms/notification/v3_1/local}notifySmsDeliveryReceipt]
The problem may lie in the endpoint not being registered by Spring-WS.
Does anyone have any idea how to register an endpoint and declare an operation using Spring-WS?
If you are using spring WS, then you should define
servlet mapping in web.xml file
<servlet>
<servlet-name>webservices</servlet-name>
<servlet-class>org.springframework.ws.transport.http.MessageDispatcherServlet</servlet-class>
<init-param>
<param-name>transformWsdlLocations</param-name>
<param-value>true</param-value>
</init-param>
<init-param>
<param-name>contextConfigLocation</param-name>
<param-value>classpath:springws-config.xml</param-value>
</init-param>
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>webservices</servlet-name>
<url-pattern>/axis2/services/*</url-pattern>
</servlet-mapping>
MessageDispatcherServlet scans all beans of Wsdl11Definition in classpath and publish them. Then you need to create a spring configuration file :
springws-config.xml
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:mvc="http://www.springframework.org/schema/mvc"
xmlns:context="http://www.springframework.org/schema/context"
xmlns:sws="http://www.springframework.org/schema/web-services"
xsi:schemaLocation="http://www.springframework.org/schema/mvc
http://www.springframework.org/schema/mvc/spring-mvc.xsd
http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/web-services
http://www.springframework.org/schema/web-services/web-services-2.0.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context.xsd">
<context:component-scan base-package="some.package.SmsNotificationService"/>
<sws:annotation-driven />
<!-- you can use static-wsdl OR dynamic-wsdl here -->
</beans>