SOAP and REST WebServices with SOAP WS Interceptor

REST WebService
  • REST : Representational State Transfer
  • REST is a kind of structure. It is not a protocol.
  • REST uses JAX-RS java API for webservice development.
  • REST supports text, html, xml and JSON data Formats.
  • REST generates WADL (WebService Application Description Language).
  • REST allows client to interact with a web-based system using simple URLs rather than complex request paremeters and request body.
  • The purpose of WADL is to define a contract between two parties.
  • At the client end all the resources are Representational and can be accessed by Browser or REST client.
  • RESET uses following JAX-RS based annotations.
  • @Path
  • @Get
  • @Post
  • @Delete
  • @Put
  • @Produces
  • @Consumes

Example

import javax.ws.rs.Consumes;
import javax.ws.rs.POST;
import javax.ws.rs.Path;
import javax.ws.rs.Produces;
import javax.ws.rs.QueryParam;
import javax.ws.rs.core.MediaType;

@Consumes(MediaType.APPLICATION_XML)
@Produces(MediaType.APPLICATION_XML)
@Path("/import")
public class RestPackageManagementWS {

private static final String MODULE = "PKG-MGMT-REST-WS";
private PackageWSBLManager packageManagementWSBLManager;

public RestPackageManagementWS() {
packageManagementWSBLManager = new PackageWSBLManager();
}

@POST
@Path("/pkg")
@Consumes(MediaType.APPLICATION_XML)
@Produces(MediaType.APPLICATION_XML)
public PackageManagementResponse wsImportPackage(
@QueryParam(value = "action")String action,
PkgData packageData,
@QueryParam(value="parameter1")String parameter1,
@QueryParam(value="parameter2")String parameter2){
parameter1 = StringUtil.trimParameter(parameter1);
parameter2 = StringUtil.trimParameter(parameter2);
action = StringUtil.trimParameter(action);
if(LogManager.getLogger().isDebugLogLevel()){
LogManager.getLogger().debug(MODULE, "Called wsImportPackage with Request Parameters: "
+ " Action: " + action
+ " Parameter1: " + parameter1
+ ", Parameter2: " + parameter2);
}
return packageManagementWSBLManager.importPackage(new PackageManagementRequest(packageData, action, parameter1, parameter2));
}
}

RestServices.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:context="http://www.springframework.org/schema/context"
       xmlns:jaxrs="http://cxf.apache.org/jaxrs" xmlns:util="http://www.springframework.org/schema/util"
       xmlns:bean="http://www.springframework.org/schema/util" xmlns:security="http://www.springframework.org/schema/security"
       xsi:schemaLocation="http://www.springframework.org/schema/beans
        http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
        http://www.springframework.org/schema/context
        http://www.springframework.org/schema/context/spring-context-3.0.xsd
        http://cxf.apache.org/jaxrs
        http://cxf.apache.org/schemas/jaxrs.xsd http://www.springframework.org/schema/util http://www.springframework.org/schema/util/spring-util-2.0.xsd
        http://www.springframework.org/schema/security http://www.springframework.org/schema/security/spring-security-3.0.xsd">

    <import resource="classpath:META-INF/cxf/cxf.xml" />
    <import resource="classpath:META-INF/cxf/cxf-servlet.xml" />

    <bean id="loggingFeature" class="org.apache.cxf.feature.LoggingFeature">
        <property name="prettyLogging" value="true" />
    </bean>

    <bean  class="com.elitecore.nvsmx.ws.packagemanagement.restws.RestPackageManagementWS" id="PackageManagement" />
    <jaxrs:server address="/restful/import" id="Package">
        <jaxrs:serviceBeans>
            <ref bean="PackageManagement" />
        </jaxrs:serviceBeans>
        <jaxrs:extensionMappings>
            <entry key="xml" value="application/xml" />
        </jaxrs:extensionMappings>
</jaxrs:server>

</beans>
Note: Put your RestServices.xml file under WEB-INF folder

web.xml file

<servlet>
<description>Apache CXF Endpoint For Rest</description>
<display-name>cxfrest</display-name>
<servlet-name>cxfrest</servlet-name>
<servlet-class>
org.apache.cxf.transport.servlet.CXFServlet
</servlet-class>
<init-param>
<param-name>config-location</param-name>
<param-value>/WEB-INF/restservice.xml</param-value>
</init-param>

<load-on-startup>1</load-on-startup>
</servlet>

<servlet-mapping>
<servlet-name>cxfrest</servlet-name>
<url-pattern>/restservices/*</url-pattern>
</servlet-mapping>

SOAP WebService
  • SOAP : Simple Object Access Protocol
  • SOAP is a Protocol.
  • SOAP generates WSDL.
  • WSDL : WebService Description Language
  • SOAP has it own security mechanism.
  • SOAP uses JAX-WS API for webservices development.
  • At end point client code need to generate for usage of SOAP webservices.
  • Originally SOAP was developed by Microsoft.
  • SOAP supports XML formats only.
  • SOAP used following JAX-WS based annotations
  •      @WebService
  •      @WebMethod
  •      @WebParam
  •      @WebResult

SOAPServices.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:jaxws="http://cxf.apache.org/jaxws"
xmlns:soap="http://cxf.apache.org/bindings/soap"
xmlns:cxf="http://cxf.apache.org/core"
xsi:schemaLocation="
http://www.springframework.org/schema/beans 
http://www.springframework.org/schema/beans/spring-beans-2.5.xsd 
http://cxf.apache.org/bindings/soap 
http://cxf.apache.org/schemas/configuration/soap.xsd 
http://cxf.apache.org/jaxws 
http://cxf.apache.org/schemas/jaxws.xsd
http://cxf.apache.org/core
http://cxf.apache.org/schemas/core.xsd">


<jaxws:endpoint xmlns:tns="http://PackageManagementWS.ws.nvsmx.elitecore.com/"
id="PackageManagementWS"
implementor="com.elitecore.nvsmx.ws.packagemanagement.PackageManagementWS"
endpointName="tns:PackageManagementWS"
serviceName="tns:PackageManagementService"
address="/PackageManagementService" >

<jaxws:binding>
<soap:soapBinding version="1.2"/>
</jaxws:binding>
<jaxws:features>
<bean class="org.apache.cxf.feature.LoggingFeature" />
</jaxws:features>
</jaxws:endpoint>
</beans>

Web.xml file

<servlet>
<description>Apache CXF Endpoint For Rest</description>
<display-name>cxfsoap</display-name>
<servlet-name>cxfsoap</servlet-name>
<servlet-class>
org.apache.cxf.transport.servlet.CXFServlet
</servlet-class>
<init-param>
<param-name>config-location</param-name>
<param-value>/WEB-INF/SOAPservices.xml</param-value>
</init-param>

<load-on-startup>1</load-on-startup>
</servlet>

<servlet-mapping>
<servlet-name>cxfrest</servlet-name>
<url-pattern>/soapservices/*</url-pattern>
</servlet-mapping>

Java File
import javax.jws.WebMethod;
import javax.jws.WebParam;
import java.util.List;

public class PackageManagementWS {

private static final String MODULE = "PKG-MGMT-WS";
private PackageWSBLManager packageManagementWSBLManager;

public PackageManagementWS() {
packageManagementWSBLManager = new PackageWSBLManager();
}

@Override
@WebMethod(operationName = WS_IMPORT_PACKAGE)
public PackageManagementResponse wsImportPackage(
@WebParam(name = "action") String action,
PkgData packageData,
@WebParam(name = "parameter1") String parameter1,
@WebParam(name = "parameter2") String parameter2) {
parameter1 = StringUtil.trimParameter(parameter1);
parameter2 = StringUtil.trimParameter(parameter2);
action = StringUtil.trimParameter(action);
if (getLogger().isDebugLogLevel()) {
getLogger().debug(MODULE, "Called wsImportPackage with Request Parameters: "
+ " Action: " + action
+ " Parameter1: " + parameter1
+ ", Parameter2: " + parameter2);
}
return packageManagementWSBLManager.importPackage(new PackageManagementRequest(packageData, action, parameter1, parameter2));
}
}


SOAP WebServices Interceptor

Note : To prepare SOAP Interceptor you need to add below tags in the SOAPServices.xml file

<bean id="MyInterceptor" class="com.elitecore.nvsmx.ws.interceptor.WebServiceRequestInterceptor"/>

<cxf:bus>
        <cxf:inInterceptors>
            <ref bean="MyInterceptor"/>
        </cxf:inInterceptors>
    </cxf:bus>

Java Implementation

import javax.xml.namespace.QName;

import org.apache.cxf.binding.soap.SoapMessage;
import org.apache.cxf.binding.soap.interceptor.AbstractSoapInterceptor;
import org.apache.cxf.interceptor.Fault;
import org.apache.cxf.phase.Phase;

public class WebServiceRequestInterceptor extends AbstractSoapInterceptor {

    private static final String MODULE = "WS-REQUEST-INTERCEPTOR";

public WebServiceRequestInterceptor() {
        super(Phase.USER_LOGICAL);
    }

    public void handleMessage(SoapMessage message) throws Fault {
    if (getLogger().isDebugLogLevel()) {
getLogger().debug(MODULE, "called handleMessage()");
}
     
  javax.xml.namespace.QName qName = (QName)message.get("javax.xml.ws.wsdl.port");
 
  if(qName != null){
 
  String webServiveName = qName.getLocalPart();
  if(webServiveName!=null) {
 
  WebServiceModule module = WebServiceModule.fromName(webServiveName);
  if(module != null ){
 
  boolean hasReachedFlag =  module.hasReachedTPSLimit();
if ( hasReachedFlag == true){
if (getLogger().isDebugLogLevel()) {
getLogger().debug(MODULE, "TPS limit Reached. Call not Allowed for '"+webServiveName+"'");
}
throw new Fault(new Exception("TPS limit Reached. Call not Allowed for '"+webServiveName+"'"));


  }else{
  if (getLogger().isInfoLogLevel()) {
getLogger().debug(MODULE, "No Web-Service module matched");
}
  }
  }else{
  if (getLogger().isInfoLogLevel()) {
getLogger().debug(MODULE, "No Local Part found for given call");
}
  }
  }else{
  if (getLogger().isInfoLogLevel()) {
getLogger().debug(MODULE, "No Qualified Name found for given Call");
}
  }
    }
}