Monday, April 28, 2014

SOAP: Spring Web Service

SOAP Web Services provide a platform agnostic integration mechanism that allows disparate systems to exchange data regardless of the platform they are running on.

For example, SOAP web services are commonly used to integrate .NET applications with applications running on the Java platform.
Almost all modern platforms and frameworks (Java, .Net, Ruby, PHP, etc) provide comprehensive libraries and tooling that allow developers to quickly and easily expose and consume SOAP services.

This post will look at Spring Web Services and take you through a step by step tutorial for building, deploying and testing a simple role first SOAP service for retrieving simple role client details.
  1. Create schema file springws.xsd:
    <?xml version="1.0" encoding="UTF-8"?>
    <!-- (c) 2010 DIRECTV, Inc. All rights reserved. -->
    <xsd:schema xmlns:xsd="http://www.w3.org/2001/XMLSchema"
        elementFormDefault="qualified" xmlns:jaxb="http://java.sun.com/xml/ns/jaxb"
        xmlns:tns="urn:springws:springwsservices" targetNamespace="urn:springws:springwsservices"
        xmlns:xjc="http://java.sun.com/xml/ns/jaxb/xjc"
        jaxb:extensionBindingPrefixes="xjc" jaxb:version="2.1">
    
        <xsd:complexType name="Role">
            <xsd:sequence>
                <xsd:element name="roleId" type="xsd:integer" />
                <xsd:element name="roleName" type="xsd:string" />
            </xsd:sequence>
        </xsd:complexType>
    
        <xsd:element name="RoleResponse">
            <xsd:complexType>
                <xsd:sequence>
                    <xsd:element name="RoleDetails" type="tns:Role" />
                </xsd:sequence>
            </xsd:complexType>
        </xsd:element>
    
        <xsd:element name="RoleRequest">
            <xsd:complexType>
                <xsd:sequence>
                    <xsd:element name="roleId" type="xsd:integer" />
                    <xsd:element name="roleName" type="xsd:string" />
                </xsd:sequence>
            </xsd:complexType>
        </xsd:element>
    
    </xsd:schema>
    
  2. Create application context application-context-ws.xml:
    <?xml version="1.0" encoding="UTF-8"?>
    <beans xmlns="http://www.springframework.org/schema/beans"
        xmlns:oxm="http://www.springframework.org/schema/oxm" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
        xmlns:sws="http://www.springframework.org/schema/web-services"
        xmlns:context="http://www.springframework.org/schema/context"
        xsi:schemaLocation="    http://www.springframework.org/schema/beans                            
                                http://www.springframework.org/schema/beans/spring-beans-3.0.xsd    
                                http://www.springframework.org/schema/oxm 
                                http://www.springframework.org/schema/oxm/spring-oxm-3.0.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-3.0.xsd">
    
        <!-- scans packages to find and register beans and activate annotations 
            within the application context -->
        <context:component-scan base-package="com.fpt.webservices" />
    
        <!-- enable the support for @Endpoint and related Spring-WS annotations -->
        <sws:annotation-driven />
    
        <oxm:jaxb2-marshaller id="marshaller"
            contextPath="com.fpt.webservices.model" />
    
        <bean id="webServiceTemplate" class="org.springframework.ws.client.core.WebServiceTemplate">
            <property name="marshaller" ref="marshaller" />
            <property name="unmarshaller" ref="marshaller" />
            <property name="defaultUri" value="http://localhost:8081/spring-ws-master/" />
        </bean>
    
        <!-- Our test service bean -->
        <bean id="RoleDetailService"
            class="org.springframework.ws.wsdl.wsdl11.DefaultWsdl11Definition"
            lazy-init="true">
            <property name="schemaCollection">
                <list>
                    <bean
                        class="org.springframework.xml.xsd.commons.CommonsXsdSchemaCollection">
                        <property name="inline" value="true" />
                        <property name="xsds">
                            <list>
                                <value>classpath:springws.xsd</value>
                            </list>
                        </property>
                    </bean>
                    <bean
                        class="org.springframework.ws.soap.security.wss4j.Wss4jSecurityInterceptor">
                        <property name="validationActions" value="UsernameToken Timestamp" />
                        <property name="validationCallbackHandler">
                            <bean
                                class="org.springframework.ws.soap.security.wss4j.callback.SimplePasswordValidationCallbackHandler">
                                <property name="users">
                                    <props>
                                        <prop key="Bert">Ernie</prop>
                                    </props>
                                </property>
                            </bean>
                        </property>
                    </bean>
                </list>
            </property>
            <property name="portTypeName" value="RoleDetailService" />
            <property name="serviceName" value="RoleDetailService" />
            <property name="locationUri" value="/endpoints" />
        </bean>
    
        <!--Way 01 For validating your request and response So that you don't send 
            a string instead of an integer -->
        <bean
            class="org.springframework.ws.server.endpoint.mapping.PayloadRootAnnotationMethodEndpointMapping">
            <property name="interceptors">
                <list>
                    <ref local="validatingInterceptor" />
                </list>
            </property>
        </bean>
        <bean id="validatingInterceptor"
            class="org.springframework.ws.soap.server.endpoint.interceptor.PayloadValidatingInterceptor">
            <property name="schema" value="classpath:springws.xsd" />
            <property name="validateRequest" value="true" />
            <!-- <property name="validateResponse" value="true" /> -->
        </bean>
    </beans>
    
  3. Create EndPoint layer:
    package com.fpt.webservices.endpoint;
    
    import org.springframework.beans.factory.annotation.Autowired;
    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 com.fpt.webservices.model.Role;
    import com.fpt.webservices.model.RoleRequest;
    import com.fpt.webservices.model.RoleResponse;
    import com.fpt.webservices.service.RoleService;
    
    @Endpoint
    public class RoleEndPoint {
    
        private static final String TARGET_NAMESPACE = "urn:springws:springwsservices";
        
        @Autowired
        private RoleService roleService;
        
        //http://localhost:8080/spring-ws-master/webservices/RoleDetailService.wsdl
        @PayloadRoot(localPart = "RoleRequest", namespace = TARGET_NAMESPACE)    
        public @ResponsePayload
        RoleResponse getRoleResponse(@RequestPayload RoleRequest roleRequest) {
            RoleResponse roleResponse = new RoleResponse();
            roleResponse = roleService.getRole(new Role(roleRequest.getRoleId(), roleRequest.getRoleName()));
            return roleResponse;
        }
    }
    
  4. Create Service layer:
    package com.fpt.webservices.service;
    
    import org.springframework.beans.factory.annotation.Autowired;
    import org.springframework.stereotype.Service;
    
    import com.fpt.webservices.dao.RoleDao;
    import com.fpt.webservices.model.Role;
    import com.fpt.webservices.model.RoleResponse;
    
    @Service
    public class RoleServiceImpl implements RoleService {
    
        @Autowired
        private RoleDao roleDao;
        
        @Override
        public RoleResponse getRole(Role role) {
            return roleDao.getRole(role);
        }
    }
    
  5. Create Dao layer:
    package com.fpt.webservices.service;
    
    import org.springframework.beans.factory.annotation.Autowired;
    import org.springframework.stereotype.Service;
    
    import com.fpt.webservices.dao.RoleDao;
    import com.fpt.webservices.model.Role;
    import com.fpt.webservices.model.RoleResponse;
    
    @Service
    public class RoleServiceImpl implements RoleService {
    
        @Autowired
        private RoleDao roleDao;
        
        @Override
        public RoleResponse getRole(Role role) {
            return roleDao.getRole(role);
        }
    }
    
    
    
    Source Code

No comments:

Post a Comment