Sunday 7 April 2013

Web Services example using CXF & JBOSS

A web service is a method of communication between multiple devices over the World Wide Web. Using Web Services we can publish application's functions to everyone. This Blog explains how we can create simple Web Services using cxf,jaxws.

Instructions assume that jdk,jboss,cxf is installed without any error.

1. Create a dynamic web project in eclipse.

2. Create a folder wsdl under WEB-INF.

3. Create a file Sample.wsdl under WEB-INF\wsdl.


4. Add following wsdl snippet in WEB-INF\wsdl\Sample.wsdl and save the file.

<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<wsdl:definitions name="Sample" 
    xmlns:soap="http://schemas.xmlsoap.org/wsdl/soap/"
 xmlns:tns="http://poc.kaustuv.com/ws/service/greetings" 
 xmlns:wsdl="http://schemas.xmlsoap.org/wsdl/" 
 xmlns:xsd="http://www.w3.org/2001/XMLSchema"
 targetNamespace="http://poc.kaustuv.com/ws/service/greetings">
 <!-- The WSDL types element is a container for XML Schema type definitions.
 The type definitions you place here are referenced from higher-level message 
 definitions in order to define the structural details of the message -->
 <wsdl:types>
  <xsd:schema targetNamespace="http://poc.kaustuv.com/ws/service/greetings">
   <xsd:element name="GreetingsRequest">
    <xsd:complexType>
     <xsd:sequence>
      <xsd:element name="name" type="xsd:string" />
     </xsd:sequence>
    </xsd:complexType>
   </xsd:element>
   <xsd:element name="GreetingsResponse">
    <xsd:complexType>
     <xsd:sequence>
      <xsd:element name="message" type="xsd:string" />
     </xsd:sequence>
    </xsd:complexType>
   </xsd:element>
  </xsd:schema>
 </wsdl:types>
 <!--The WSDL message element defines an abstract message that can 
 serve as the input or output of an operation. Messages consist of
 one or more part elements, where each part is associated with either
 an element (when using document style) or a type (when using RPC style) -->
 <wsdl:message name="GreetingsReq">
  <wsdl:part element="tns:GreetingsRequest" name="parameterIn" />
 </wsdl:message>
 <wsdl:message name="GreetingsRes">
  <wsdl:part element="tns:GreetingsResponse" name="parameterOut" />
 </wsdl:message>
 <!--The WSDL portType element defines a group of operations, also known as an interface in most environments .-->
 <wsdl:portType name="Greetings">
  <wsdl:operation name="Greetings">
   <wsdl:input message="tns:GreetingsReq" />
   <wsdl:output message="tns:GreetingsRes" />
  </wsdl:operation>
 </wsdl:portType>
 <!-- The WSDL binding element describes the concrete details 
 of using a particular portType with a given protocol. 
 The binding element contains several extensibility elements 
 as well as a WSDL operation element for each operation in 
 the portType it's describing . Here bnding is document literal -->
 <wsdl:binding name="GreetingsSOAPBinding" type="tns:Greetings">
  <!-- Style of binding canbe document or rpc -->
  <soap:binding style="document" transport="http://schemas.xmlsoap.org/soap/http" />
  <wsdl:operation name="Greetings">
   <soap:operation soapAction="Greetings" />
   <wsdl:input>
    <soap:body use="literal" />
   </wsdl:input>
   <wsdl:output>
    <soap:body use="literal" />
   </wsdl:output>
  </wsdl:operation>
 </wsdl:binding>
 <!-- The WSDL service element defines a collection of ports, 
 or endpoints, that expose a particular binding -->
 <wsdl:service name="GreetingsService">
  <wsdl:port name="GreetingsPort" binding="tns:GreetingsSOAPBinding">
  <!-- address of service -->
   <soap:address location="http://www.kaustuv.com/ws/service/" />
  </wsdl:port>
 </wsdl:service>
</wsdl:definitions>

 


WSDL stands for Web Services Description Language it describes how to access a web service and what operations it will perform. WSDL contains five essential elements.
ElementName Description
types A container for abstract type definitions defined using XML Schema. In above example wsdl we have defined GreetingsRequest and GreetingsResponse under wsdl:types section.
message A definition of an abstract message that may consist of multiple parts, each part may be of a different type. In above example wsdl we have defined GreetingsReq and GreetingsRes using wsdl:message section.
portType An abstract set of operations supported by one or more endpoints (commonly known as an interface); operations are defined by an exchange of messages. In above example wsdl we have defined operation name Greetings and add messages as a input and output to this operation within wsdl:portType section.
binding A concrete protocol and data format specification for a particular portType. In above example wsdl we have specified that we will use document and transport layer will be "http://schemas.xmlsoap.org/soap/http". We have also defined operation here and inside there we also defined soapAction along with the input and output style.
service A collection of related endpoints, where an endpoint is defined as a combination of a binding and an address (URI). In above example please check wsdl:service tag. now that section we have defined service name and and port. In port we add our newly created binding and add soap address.

5. Generate java classes and service interfrace using eclipse wsdl2java.

Now please check the relationship between the namespace what we specified in wsdl and the package name which is created after above steps. During execution of wsdl2java command it parse the wsdl and the related schema and create java classes. The namespace in example wsdl was "http://poc.kaustuv.com/ws/service/greetings" now from this it created com.kaustuv.poc.ws.service.greetings package . Package com.kaustuv.poc.ws.service.greetings contains service Interface, service Implemenation , RequestType and ResponseType.
 
6. Modify GreetingsImpl.java add following code snippet.

package com.kaustuv.poc.ws.service.greetings;

import java.util.logging.Logger;
import javax.jws.WebMethod;
import javax.jws.WebParam;
import javax.jws.WebResult;
import javax.jws.WebService;
import javax.jws.soap.SOAPBinding;
import javax.xml.bind.annotation.XmlSeeAlso;

@javax.jws.WebService(
                      serviceName = "GreetingsService",
                      portName = "GreetingsPort",
                      targetNamespace = "http://poc.kaustuv.com/ws/service/greetings",
                      wsdlLocation = "WEB-INF/wsdl/Sample.wsdl",
                      endpointInterface = "com.kaustuv.poc.ws.service.greetings.Greetings")
                      
public class GreetingsImpl implements Greetings {

    private static final Logger LOG = Logger.getLogger(GreetingsImpl.class.getName());

    /* (non-Javadoc)
     * @see com.kaustuv.poc.ws.service.greetings.Greetings#greetings(com.kaustuv.poc.ws.service.greetings.GreetingsRequest  parameterIn )*
     */
    public com.kaustuv.poc.ws.service.greetings.GreetingsResponse greetings(GreetingsRequest parameterIn) { 
        LOG.info("Executing operation greetings");
        System.out.println(parameterIn);
        try {
            com.kaustuv.poc.ws.service.greetings.GreetingsResponse _return = new GreetingsResponse();
            _return.setMessage(parameterIn.getName());
            return _return;
        } catch (java.lang.Exception ex) {
            ex.printStackTrace();
            throw new RuntimeException(ex);
        }
    }
}

7. Modify generated cxf-beans.xml WEB-INF/cxf-beans.xml add following xml snippet.

<?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"
xsi:schemaLocation="http://www.springframework.org/schema/beans 
     http://www.springframework.org/schema/beans/spring-beans-2.5.xsd 
     http://cxf.apache.org/jaxws http://cxf.apache.org/schemas/jaxws.xsd">
    <import resource="classpath:META-INF/cxf/cxf.xml" />
    <import resource="classpath:META-INF/cxf/cxf-extension-soap.xml" />
    <import resource="classpath:META-INF/cxf/cxf-servlet.xml" />
 
    <jaxws:endpoint 
        xmlns:tns="http://poc.kaustuv.com/ws/service/greetings" 
        id="greetings"
        implementor="com.kaustuv.poc.ws.service.greetings.GreetingsImpl"
        wsdlLocation="WEB-INF/wsdl/Sample.wsdl" 
        endpointName="tns:GreetingsPort"
        serviceName="tns:GreetingsService" 
        address="/Greetings">
  <!-- xml:tns , enpointname ans servicename will be same as in wsdl -->
  <!-- /Greetings means our webservice url will be 
  http://<host>:<port>/<webapplicationname>/Greeting?wsdl 
  -->
        <jaxws:features>
  <!-- Used for cxf log to see soap packet structure -->
            <bean class="org.apache.cxf.feature.LoggingFeature" />
        </jaxws:features>
    </jaxws:endpoint>
</beans>

 


8. Modify generated web.xml WEB-INF/web.xml add following xml snippet.

<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://java.sun.com/xml/ns/javaee" xmlns:web="http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd" xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd" id="WebApp_ID" version="2.5">
  <display-name>SimpleJaxwsExample</display-name>
  <servlet>
    <description>Apache CXF Endpoint</description>
    <display-name>cxf</display-name>
    <servlet-name>cxf</servlet-name>
    <servlet-class>org.apache.cxf.transport.servlet.CXFServlet</servlet-class>
    <load-on-startup>1</load-on-startup>
  </servlet>
  <servlet-mapping>
    <servlet-name>cxf</servlet-name>
    <url-pattern>/*</url-pattern>
  </servlet-mapping>
  <session-config>
    <session-timeout>60</session-timeout>
  </session-config>
  <context-param>
    <param-name>contextConfigLocation</param-name>
    <param-value>WEB-INF/cxf-beans.xml</param-value>
  </context-param>
  <listener>
    <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
  </listener>
</web-app>

9. Export and package this as war.Destination path %JBOSS_HOME%\server\default






































10. Open command prompt and go to directory %JBOSS_HOME\bin .
11. Execute run.bat -c default -b 0.0.0.0

main:14:50:42,533:INFO :[ContainerBase]:Initializing Spring root WebApplicationContext
main:14:50:42,534:INFO :[ContextLoader]:Root WebApplicationContext: initialization started
main:14:50:42,601:INFO :[XmlWebApplicationContext]:Refreshing Root WebApplicationContext: startup date [Sun Apr 07 14:50:42 IST 2013]; root of context hierarchy
main:14:50:42,706:INFO :[XmlBeanDefinitionReader]:Loading XML bean definitions from ServletContext resource [/WEB-INF/cxf-beans.xml]
main:14:50:42,789:INFO :[XmlBeanDefinitionReader]:Loading XML bean definitions from class path resource [META-INF/cxf/cxf.xml]
main:14:50:42,829:INFO :[XmlBeanDefinitionReader]:Loading XML bean definitions from class path resource [META-INF/cxf/cxf-extension-soap.xml]
main:14:50:42,863:INFO :[XmlBeanDefinitionReader]:Loading XML bean definitions from class path resource [META-INF/cxf/cxf-servlet.xml]
main:14:50:44,050:INFO :[DefaultListableBeanFactory]:Pre-instantiating singletons in org.springframework.beans.factory.support.DefaultListableBeanFactory@1187d2f: defining beans [cxf,org.apache.cxf.bus.spring.BusWiringBeanFactoryPostProcessor,org.apache.cxf.bus.spring.Jsr250BeanPostProcessor,org.apache.cxf.bus.spring.BusExtensionPostProcessor,org.apache.cxf.binding.soap.SoapBindingFactory,org.apache.cxf.binding.soap.SoapTransportFactory,org.apache.cxf.binding.soap.customEditorConfigurer,greetings]; root of factory hierarchy
INFO: Creating Service {http://poc.kaustuv.com/ws/service/greetings}GreetingsService from WSDL: WEB-INF/wsdl/Sample.wsdl
INFO: Setting the server's publish address to be /Greetings
main:14:50:46,334:INFO :[ContextLoader]:Root WebApplicationContext: initialization completed in 3797 ms

11. click on http://localhost:8080/SimpleJaxwsExample/

12. click on [wsdl url] http://localhost:8080/SimpleJaxwsExample/Greetings?wsdl
If Https is not enable please try Https Configuration link
click on [wsdl url] https://localhost:8443/SimpleJaxwsExample/Greetings?wsdl

  • Post Development testing
  • We can test webservice by various web service testing tools such as soap ui, soap lite etc. Here we will test this greetings web service by using java client.
    import java.net.MalformedURLException;
    import java.net.URL;
    
    import javax.xml.namespace.QName;
    import javax.xml.ws.Service;
    
    import org.apache.cxf.endpoint.Client;
    import org.apache.cxf.endpoint.Endpoint;
    import org.apache.cxf.frontend.ClientProxy;
    import org.apache.cxf.interceptor.LoggingInInterceptor;
    import org.apache.cxf.interceptor.LoggingOutInterceptor;
    
    /**
     * @author KMaji
     *
     */
    public class SampleWebServiceClient {
      /**
       * @param args
       * @throws MalformedURLException 
       */
      public static void main(String[] args) throws MalformedURLException {
    
        Service service = Service.create(new URL("http://localhost:8080/SimpleJaxwsExample/Greetings?wsdl"),
                                         new QName("http://poc.kaustuv.com/ws/service/greetings",
                                                   "GreetingsService"));
    
        Greetings greetings = service.getPort(Greetings.class);
        Client client = ClientProxy.getClient(greetings);
        Endpoint endPoint = client.getEndpoint();
        endPoint.getOutInterceptors().add(new LoggingOutInterceptor());
        endPoint.getInInterceptors().add(new LoggingInInterceptor());
        GreetingsResponse gRes = null;
        GreetingsRequest gReq = new GreetingsRequest();
        gReq.setName("kaustuv");
        try {
          gRes = greetings.greetings(gReq);
        }
        catch (Exception e) {
          e.printStackTrace();
        }
        System.out.println("Response" + gRes.getMessage());
      }
    }
    
Above instruction is also compatible with jboss 5.1.* series for deployment. Remove xml-beans.jar and geronimo-servlet_2.5_spec-1.1.2.jar due to incompatibility of slf4j version we need to remove slf4j-api-1.6.2.jar and slf4j-jdk14-1.6.2.jar from your web application packaging path (WEB-INF\lib).

Click here to download source code of above example

Source Code


  • References:
WSDL
W3school wsdl introduction
CXF documents

European Union laws require you to give European Union visitors information about cookies used on your blog. In many cases, these laws also require you to obtain consent.

As a courtesy, we have added a notice on your blog to explain Google's use of certain Blogger and Google cookies, including use of Google Analytics and AdSense cookies.

No comments:

Post a Comment