Monday, 22 April 2013

Webservice with cxf using embedded Jetty

Jetty is a pure Java-based HTTP server and Java Servlet container. Jetty provides support for SPDY, Web Sockets, OSGi, JMX, JNDI, JASPI, AJP and many other integrations. More details about jetty please click following links.
This blog instruction will help us to create a sample webservice using cxf using embedded jetty (jetty://).

  • HTTP jaxws setup with CXF using embedded Jetty
    1. Create a dynamic web project.
    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.

    5. <?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>
      

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































    7. Modify GreetingsImpl.java add following code snippet.
    8. /**
      *
      * Copyright (c) Kaustuv Maji , 2013
      * Repos - https://github.com/kaustuvmaji
      * Blog -  http://kaustuvmaji.blogspot.in 
      *
      */
      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);
              }
          }
      }
      
    9. Modify generated web.xml WEB-INF/web.xml add following xml snippet.
    10. <?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>SimpleJettyExample</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/conf/*-beans.xml</param-value>
        </context-param>
        <listener>
          <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
        </listener>
      </web-app>
      
    11. Create a xml file name cxf-jetty-beans.xml under WEB-INF/conf
    12. <?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:cxf="http://cxf.apache.org/core"
             xmlns:jaxws="http://cxf.apache.org/jaxws"
          xmlns:httpj="http://cxf.apache.org/transports/http-jetty/configuration" 
          xsi:schemaLocation="
                              http://cxf.apache.org/core 
                              http://cxf.apache.org/schemas/core.xsd
                              http://www.springframework.org/schema/beans 
                              http://www.springframework.org/schema/beans/spring-beans.xsd
                              http://cxf.apache.org/transports/http-jetty/configuration 
                              http://cxf.apache.org/schemas/configuration/http-jetty.xsd
                              http://cxf.apache.org/jaxws 
                              http://cxf.apache.org/schemas/jaxws.xsd">
          <!-- import resource -->
          <import resource="classpath:META-INF/cxf/cxf*.xml" />
          <bean id="biosocket" class="org.eclipse.jetty.server.bio.SocketConnector">
              <property name="host" value="localhost" />
              <property name="port" value="9001" />
          </bean>
          <bean id="defaultHandler" class="org.eclipse.jetty.server.handler.DefaultHandler" />
          <!-- Cxf Bus implementation -->
          <cxf:bus>
              <!-- Cxf features implementation global -->
              <cxf:features>
                  <!-- cxf logging implementation -->
                  <cxf:logging />
              </cxf:features>
          </cxf:bus>
          <!-- Jetty server configuration and implementation -->
          <httpj:engine-factory bus="cxf">
              <!-- jetty server port we can add host too -->
              <httpj:engine host="localhost" port="9001">
                  <!-- jetty thread pooling -->
                  <httpj:threadingParameters minThreads="5" maxThreads="15" />
                  <httpj:connector>
                      <ref bean="biosocket" />
                  </httpj:connector>
                  <httpj:handlers>
                      <ref bean="defaultHandler" />
                  </httpj:handlers>
                  <httpj:sessionSupport>true</httpj:sessionSupport>
              </httpj:engine>
          </httpj:engine-factory>
      </beans>
      
    13. Modify generated cxf-beans.xml WEB-INF/conf/cxf-beans.xml add following xml snippet.
    14. <?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="http://localhost:9001/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>
      
    15. Export and package this as war.Destination path %JBOSS_HOME%\server\default
    16. Open command prompt and go to directory %JBOSS_HOME\bin
    17. Execute run.bat -c default -b 0.0.0.0
    18. Deployement will be sucessfull according to above instructions. following log message will apear in jboss console log.
      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 http://localhost:9001/Greetings
      INFO: jetty-7.5.4.v20111024
      INFO: Started SelectChannelConnector@localhost:9003 STARTING
      INFO: started o.e.j.s.h.ContextHandler{,null}
      13:22:16,863 INFO  [ContextLoader] Root WebApplicationContext: initialization completed in 9333 ms
      13:22:16,965 INFO  [Http11Protocol] Starting Coyote HTTP/1.1 on http-0.0.0.0-8080
      13:22:16,990 INFO  [AjpProtocol] Starting Coyote AJP/1.3 on ajp-0.0.0.0-8009
      13:22:17,032 INFO  [Server] JBoss (MX MicroKernel) [4.2.3.GA (build: SVNTag=JBoss_4_2_3_GA date=200807181417)] Started in 33s:865ms
      
      WSDL url : http://localhost:9003/Greetings?wsdl

      Please check the above snapshot wsdl tab. Icon (j:) it means that 9003 is cxf embeded jetty web server port. 9003 jetty port configuration is done in cxf-jetty-beans.xml .

  • HTTP jaxrs setup with CXF using embedded Jetty

  • Developing sample restful webservice please go through following link. The link will help you to create sample restful webservice in details. In this section we will only configure jaxrs server to use cxf embabed jetty.
    1. Create a xml file name cxf-jetty-beans.xml under WEB-INF/conf
    2. <?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:cxf="http://cxf.apache.org/core"
             xmlns:jaxws="http://cxf.apache.org/jaxws"
          xmlns:httpj="http://cxf.apache.org/transports/http-jetty/configuration" 
          xsi:schemaLocation="
                              http://cxf.apache.org/core 
                              http://cxf.apache.org/schemas/core.xsd
                              http://www.springframework.org/schema/beans 
                              http://www.springframework.org/schema/beans/spring-beans.xsd
                              http://cxf.apache.org/transports/http-jetty/configuration 
                              http://cxf.apache.org/schemas/configuration/http-jetty.xsd
                              http://cxf.apache.org/jaxws 
                              http://cxf.apache.org/schemas/jaxws.xsd">
          <!-- import resource -->
          <import resource="classpath:META-INF/cxf/cxf*.xml" />
          <bean id="biosocket" class="org.eclipse.jetty.server.bio.SocketConnector">
              <property name="host" value="localhost" />
              <property name="port" value="9001" />
          </bean>
          <bean id="defaultHandler" class="org.eclipse.jetty.server.handler.DefaultHandler" />
          <!-- Cxf Bus implementation -->
          <cxf:bus>
              <!-- Cxf features implementation global -->
              <cxf:features>
                  <!-- cxf logging implementation -->
                  <cxf:logging />
              </cxf:features>
          </cxf:bus>
          <!-- Jetty server configuration and implementation -->
          <httpj:engine-factory bus="cxf">
              <!-- jetty server port we can add host too -->
              <httpj:engine host="localhost" port="9001">
                  <!-- jetty thread pooling -->
                  <httpj:threadingParameters minThreads="5" maxThreads="15" />
                  <httpj:connector>
                      <ref bean="biosocket" />
                  </httpj:connector>
                  <httpj:handlers>
                      <ref bean="defaultHandler" />
                  </httpj:handlers>
                  <httpj:sessionSupport>true</httpj:sessionSupport>
              </httpj:engine>
          </httpj:engine-factory>
      </beans>
      

    3. Modify jaxrs-beans.xml under WEB-INF/conf and mention the jetty host port in jaxrs server section

    4. <?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:jaxrs="http://cxf.apache.org/jaxrs"
      xmlns:cxf="http://cxf.apache.org/core" 
          xsi:schemaLocation="
      http://www.springframework.org/schema/beans
      http://www.springframework.org/schema/beans/spring-beans.xsd
      http://cxf.apache.org/core 
      http://cxf.apache.org/schemas/core.xsd
      http://cxf.apache.org/jaxrs
      http://cxf.apache.org/schemas/jaxrs.xsd"
          default-lazy-init="false">
          <!-- Service -->
          <bean id="customerService" class="com.kaustuv.jaxrs.example.service.DemoCustomerServiceImpl" 
          init-method="init" 
          destroy-method="destroy" />
          <!-- Jaxrs Server -->
          <jaxrs:server id="restserver" address="http://localhost:9001/customerService">
              <!-- adding service bean -->
              <jaxrs:serviceBeans>
                  <ref bean="customerService" />
              </jaxrs:serviceBeans>
              <!-- adding media type provider -->
              <jaxrs:providers>
                  <ref bean="jsonProvider" />
                  <ref bean="jaxbXmlProvider" />
                  <ref bean="cors-filter" />
              </jaxrs:providers>
              <jaxrs:features>
                  <cxf:logging/>
              </jaxrs:features>
              <!-- Keeping extention type -->
              <jaxrs:extensionMappings>
                  <entry key="json" value="application/json" />
                  <entry key="xml" value="application/xml" />
              </jaxrs:extensionMappings>
          </jaxrs:server>
      </beans>
      
      Above instructions will be enable our jaxrs project to use cxf embedded jetty.

  • Testing
  • Post production testing procedure will be as same as discussed is previous blog. Please click on jaxws or jaxrs browse testing section for more details procedures.
    • References:
    Jetty wiki
    Embedded Jetty
    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.

    You are responsible for confirming that this notice actually works for your blog and that it is displayed. If you employ other cookies, for example by adding third-party features, this notice may not work for you. Learn more about this notice and your responsibilities.

    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.

    Thursday, 11 April 2013

    Restful Web Services example using CXF , JAXRS.

    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. In the web services world, REpresentational State Transfer (REST) is a key design idiom that embraces a stateless client-server architecture in which the web services are viewed as resources and can be identified by their URLs. This basic REST design principle establishes a one-to-one mapping between create, read, update, and delete (CRUD) operations and HTTP methods.
      • To create a resource on the server, use POST.
      • To retrieve a resource, use GET.
      • To change the state of a resource or to update it, use PUT.
      • To remove or delete a resource, use DELETE.
    More details about RESTFul web services please go to references section of this blog.
    This Blog instruction will help us to create a sample RESTful webservice using cxf and jaxrs api.

  • Required Software
  • Pre-requsite
  • Instructions assume that jdk,jboss,cxf is installed without any error.

  • Instructions
    1. Create a dynamic web project in eclipse.
















    2. Create a file name customer.xsd under /WEB-INF and use the following xml snippet.

    3. <?xml version="1.0" encoding="UTF-8"?>
      <xsd:schema xmlns:xsd="http://www.w3.org/2001/XMLSchema">
          <xsd:complexType name="customer">
              <xsd:sequence>
                  <xsd:element name="address" type="address" />
                  <xsd:element name="customerId" type="xsd:long" />
                  <xsd:element name="customerName" type="xsd:string" />
                  <xsd:element name="phone" type="xsd:long" />
              </xsd:sequence>
          </xsd:complexType>
          <xsd:complexType name="address">
              <xsd:sequence>
                  <xsd:element name="street" type="xsd:string" />
                  <xsd:element name="city" type="xsd:string" />
                  <xsd:element name="state" type="xsd:string" />
                  <xsd:element name="country" type="xsd:string" />
                  <xsd:element name="pincode" type="xsd:long" />
              </xsd:sequence>
          </xsd:complexType>
      </xsd:schema>
      


















    4. Generate Jaxb classes from customer.xsd using eclipse.
    5. After execution of above steps com.kaustuv.jaxrs.example.vo package will be created which contains three Jaxb generated classes. Address.java , Customer.java , ObjectFactory.


































    6. Add @XmlRootElement to both jaxb generated classes. please have a look into following code snippets.

    7. Address.java
      package com.kaustuv.jaxrs.example.vo;
      
      import javax.xml.bind.annotation.XmlAccessType;
      import javax.xml.bind.annotation.XmlAccessorType;
      import javax.xml.bind.annotation.XmlElement;
      import javax.xml.bind.annotation.XmlRootElement;
      import javax.xml.bind.annotation.XmlType;
      
      
      /**
       * <p>Java class for address complex type.
       * 
       * <p>The following schema fragment specifies the expected content contained within this class.
       * 
       * <pre>
       * &lt;complexType name="address">
       *   &lt;complexContent>
       *     &lt;restriction base="{http://www.w3.org/2001/XMLSchema}anyType">
       *       &lt;sequence>
       *         &lt;element name="street" type="{http://www.w3.org/2001/XMLSchema}string"/>
       *         &lt;element name="city" type="{http://www.w3.org/2001/XMLSchema}string"/>
       *         &lt;element name="state" type="{http://www.w3.org/2001/XMLSchema}string"/>
       *         &lt;element name="country" type="{http://www.w3.org/2001/XMLSchema}string"/>
       *         &lt;element name="pincode" type="{http://www.w3.org/2001/XMLSchema}long"/>
       *       &lt;/sequence>
       *     &lt;/restriction>
       *   &lt;/complexContent>
       * &lt;/complexType>
       * </pre>
       * 
       * 
       */
      @XmlRootElement(name="address")
      @XmlAccessorType(XmlAccessType.FIELD)
      @XmlType(name = "address", propOrder = {
          "street",
          "city",
          "state",
          "country",
          "pincode"
      })
      public class Address {
      
          @XmlElement(required = true)
          protected String street;
          @XmlElement(required = true)
          protected String city;
          @XmlElement(required = true)
          protected String state;
          @XmlElement(required = true)
          protected String country;
          protected long pincode;
      
          /**
           * Gets the value of the street property.
           * 
           * @return
           *     possible object is
           *     {@link String }
           *     
           */
          public String getStreet() {
              return street;
          }
      
          /**
           * Sets the value of the street property.
           * 
           * @param value
           *     allowed object is
           *     {@link String }
           *     
           */
          public void setStreet(String value) {
              this.street = value;
          }
      
          /**
           * Gets the value of the city property.
           * 
           * @return
           *     possible object is
           *     {@link String }
           *     
           */
          public String getCity() {
              return city;
          }
      
          /**
           * Sets the value of the city property.
           * 
           * @param value
           *     allowed object is
           *     {@link String }
           *     
           */
          public void setCity(String value) {
              this.city = value;
          }
      
          /**
           * Gets the value of the state property.
           * 
           * @return
           *     possible object is
           *     {@link String }
           *     
           */
          public String getState() {
              return state;
          }
      
          /**
           * Sets the value of the state property.
           * 
           * @param value
           *     allowed object is
           *     {@link String }
           *     
           */
          public void setState(String value) {
              this.state = value;
          }
      
          /**
           * Gets the value of the country property.
           * 
           * @return
           *     possible object is
           *     {@link String }
           *     
           */
          public String getCountry() {
              return country;
          }
      
          /**
           * Sets the value of the country property.
           * 
           * @param value
           *     allowed object is
           *     {@link String }
           *     
           */
          public void setCountry(String value) {
              this.country = value;
          }
      
          /**
           * Gets the value of the pincode property.
           * 
           */
          public long getPincode() {
              return pincode;
          }
      
          /**
           * Sets the value of the pincode property.
           * 
           */
          public void setPincode(long value) {
              this.pincode = value;
          }
      }
      

      Customer.java
      package com.kaustuv.jaxrs.example.vo;
      
      import javax.xml.bind.annotation.XmlAccessType;
      import javax.xml.bind.annotation.XmlAccessorType;
      import javax.xml.bind.annotation.XmlElement;
      import javax.xml.bind.annotation.XmlRootElement;
      import javax.xml.bind.annotation.XmlType;
      
      
      /**
       * <p>Java class for customer complex type.
       * 
       * <p>The following schema fragment specifies the expected content contained within this class.
       * 
       * <pre>
       * &lt;complexType name="customer">
       *   &lt;complexContent>
       *     &lt;restriction base="{http://www.w3.org/2001/XMLSchema}anyType">
       *       &lt;sequence>
       *         &lt;element name="address" type="{}address"/>
       *         &lt;element name="customerId" type="{http://www.w3.org/2001/XMLSchema}long"/>
       *         &lt;element name="customerName" type="{http://www.w3.org/2001/XMLSchema}string"/>
       *         &lt;element name="phone" type="{http://www.w3.org/2001/XMLSchema}long"/>
       *       &lt;/sequence>
       *     &lt;/restriction>
       *   &lt;/complexContent>
       * &lt;/complexType>
       * </pre>
       * 
       * 
       */
      @XmlRootElement(name="customer")
      @XmlAccessorType(XmlAccessType.FIELD)
      @XmlType(name = "customer", propOrder = {
          "address",
          "customerId",
          "customerName",
          "phone"
      })
      public class Customer {
      
          @XmlElement(required = true)
          protected Address address;
          protected long customerId;
          @XmlElement(required = true)
          protected String customerName;
          protected long phone;
      
          /**
           * Gets the value of the address property.
           * 
           * @return
           *     possible object is
           *     {@link Address }
           *     
           */
          public Address getAddress() {
              return address;
          }
      
          /**
           * Sets the value of the address property.
           * 
           * @param value
           *     allowed object is
           *     {@link Address }
           *     
           */
          public void setAddress(Address value) {
              this.address = value;
          }
      
          /**
           * Gets the value of the customerId property.
           * 
           */
          public long getCustomerId() {
              return customerId;
          }
      
          /**
           * Sets the value of the customerId property.
           * 
           */
          public void setCustomerId(long value) {
              this.customerId = value;
          }
      
          /**
           * Gets the value of the customerName property.
           * 
           * @return
           *     possible object is
           *     {@link String }
           *     
           */
          public String getCustomerName() {
              return customerName;
          }
      
          /**
           * Sets the value of the customerName property.
           * 
           * @param value
           *     allowed object is
           *     {@link String }
           *     
           */
          public void setCustomerName(String value) {
              this.customerName = value;
          }
      
          /**
           * Gets the value of the phone property.
           * 
           */
          public long getPhone() {
              return phone;
          }
      
          /**
           * Sets the value of the phone property.
           * 
           */
          public void setPhone(long value) {
              this.phone = value;
          }
      }
      

      ObjectFactory
      package com.kaustuv.jaxrs.example.vo;
      
      import javax.xml.bind.annotation.XmlRegistry;
      
      
      /**
       * This object contains factory methods for each 
       * Java content interface and Java element interface 
       * generated in the com.kaustuv.jaxrs.example.vo package. 
       * <p>An ObjectFactory allows you to programatically 
       * construct new instances of the Java representation 
       * for XML content. The Java representation of XML 
       * content can consist of schema derived interfaces 
       * and classes representing the binding of schema 
       * type definitions, element declarations and model 
       * groups.  Factory methods for each of these are 
       * provided in this class.
       * 
       */
      @XmlRegistry
      public class ObjectFactory {
      
      
          /**
           * Create a new ObjectFactory that can be used to create new instances of schema derived classes for package: com.kaustuv.jaxrs.example.vo
           * 
           */
          public ObjectFactory() {
          }
      
          /**
           * Create an instance of {@link Customer }
           * 
           */
          public Customer createCustomer() {
              return new Customer();
          }
      
          /**
           * Create an instance of {@link Address }
           * 
           */
          public Address createAddress() {
              return new Address();
          }
      }
      

    8. Open web.xml under WEB-INF\web.xml and add following xml snippet


    9. <?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>jaxrs-example</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/conf/*beans.xml</param-value>
          </context-param>
          <listener>
              <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
          </listener>
      </web-app>
      


    10. Create a new package "com.kaustuv.jaxrs.example.service"

    11. create a new service interface name DemoCustomerService under package "com.kaustuv.jaxrs.example.service". Add following code snippet.

    12. /**
      *
      * Copyright (c) Kaustuv Maji , 2013
      * Repos - https://github.com/kaustuvmaji
      * Blog -  http://kaustuvmaji.blogspot.in 
      *
      */
      package com.kaustuv.jaxrs.example.service;
      
      import javax.ws.rs.DELETE;
      import javax.ws.rs.GET;
      import javax.ws.rs.POST;
      import javax.ws.rs.PUT;
      import javax.ws.rs.Path;
      import javax.ws.rs.QueryParam;
      import javax.ws.rs.core.Response;
      
      import com.kaustuv.jaxrs.example.vo.Customer;
      
      /**
       * This is rest services interface .
       * Methods  
       *     i.   Add customer               {@link #addCustomer(Customer)}.
       *     ii.  Get customer by customerId {@link #getCustomerById(long)}.
       *     iii. Update customer            {@link #updateCustomer(Customer)}.
       *     iv.  Delete customer            {@link #deleteCustomer(long)}.
       *     
       * @since   1.0
       * @version 1.0
       * 
       * @author KMaji
       *
       */
      public interface DemoCustomerService {
      
        /**
         * This method is used to demonstrate http method GET.
         * 
         * @param custId will be accepted as Queryparam. 
         * @return response
         */
        @GET
        @Path("/getCustomerById")
        public Response getCustomerById(@QueryParam("custId") long custId);
      
        /**
         * This method is used to demonstrate http method POST.
         * @param customer
         * @return response
         */
        @POST
        @Path("/addCustomer")
        public Response addCustomer(Customer customer);
      
        /**
         * This method is used to demonstrate Http method DELETE.
         * @param custId will be accepted as Queryparam. 
         * @return response
         */
        @DELETE
        @Path("/deleteCustomer")
        public Response deleteCustomer(@QueryParam("custId") long custId);
      
        /**
         * This method is to demonstrate http method PUT.
         * 
         * @param customer
         * @return response
         */
        @PUT
        @Path("/updateCustomer")
        public Response updateCustomer(Customer customer);
      }
      

    13. Create DemoCustomerServiceImpl under package "com.kaustuv.jaxrs.example.service". Add following code snippet

    14. /**
      |
      | Copyright (c) Kaustuv Maji , 2013
      | 
      | Please do not use source code in production.
      | Repos -  https://github.com/kaustuvmaji
      | Blog  -  http://kaustuvmaji.blogspot.in 
      */
      package com.kaustuv.jaxrs.example.service;
      
      import java.util.HashMap;
      import java.util.Map;
      
      import javax.ws.rs.core.Context;
      import javax.ws.rs.core.Response;
      import javax.ws.rs.core.UriInfo;
      
      import org.apache.log4j.Logger;
      
      import com.kaustuv.jaxrs.example.vo.Address;
      import com.kaustuv.jaxrs.example.vo.Customer;
      
      /**
       * This implementation class is to implement rest service interface.
       * Methods  
       *     --   Add customer               {@link #addCustomer(Customer)}.
       *     --   Get customer by customerId {@link #getCustomerById(long)}.
       *     --   Update customer            {@link #updateCustomer(Customer)}.
       *     --   Delete customer            {@link #deleteCustomer(long)}.
       *     --   init                       {@link #init()}. 
       *     --   destory                    {@link #destroy()}.
       *     
       * @since   1.0
       * @version 1.0
       * 
       * @author KMaji
       *
       */
      public class DemoCustomerServiceImpl implements DemoCustomerService {
      
        @Context
        UriInfo uriInfo;
      
        private final static String ACCESS_CONTROL_ALLOW_ORIGIN = "*";
      
        private Logger log;
      
        private Map<Long, Customer> customers;
      
        public DemoCustomerServiceImpl() {
          log = Logger.getLogger(DemoCustomerServiceImpl.class);
          customers = new HashMap<Long, Customer>();
        }
      
        public Response getCustomerById(long custId) {
          log.info("Executing getCustomerById operation");
          if (!customers.containsKey(custId)) {
            return Response.status(Response.Status.BAD_REQUEST)
                           .location(uriInfo.getAbsolutePath())
                           .entity("customer not found")
                           .header("Access-Control-Allow-Origin", ACCESS_CONTROL_ALLOW_ORIGIN)
                           .build();
          }
          return Response.ok(uriInfo.getAbsolutePath())
                         .entity(customers.get(custId))
                         .header("Access-Control-Allow-Origin", ACCESS_CONTROL_ALLOW_ORIGIN)
                         .build();
        }
      
        public Response addCustomer(Customer customer) {
          log.info("Executing Add Customer operation");
          if (customers.containsKey(customer.getCustomerId())) {
           return Response.status(Response.Status.BAD_REQUEST)
                    .location(uriInfo.getAbsolutePath())
                    .entity("Exsisting customer found with same id.")
                    .header("Access-Control-Allow-Origin", ACCESS_CONTROL_ALLOW_ORIGIN)
                    .build();
          }
          customers.put(customer.getCustomerId(), customer);
          log.info("Added new customer with customer id" + customer.getCustomerId());
          return Response.ok(uriInfo.getAbsolutePath())
                         .entity(customer)
                         .header("Access-Control-Allow-Origin", ACCESS_CONTROL_ALLOW_ORIGIN)
                         .build();
        }
      
        public Response deleteCustomer(long custId) {
          log.info("Executing Delete Customer operation");
          if (!customers.containsKey(custId)) {
           return  Response.status(Response.Status.BAD_REQUEST)
                    .location(uriInfo.getAbsolutePath())
                    .entity("customer not found")
                    .header("Access-Control-Allow-Origin", ACCESS_CONTROL_ALLOW_ORIGIN)
                    .build();
          }
          customers.remove(custId);
          log.info("Removed customer contains customerid " + custId);
          return Response.ok(uriInfo.getAbsolutePath())
                         .entity("Removed customer contains customerid " + custId)
                         .header("Access-Control-Allow-Origin", ACCESS_CONTROL_ALLOW_ORIGIN)
                         .build();
        }
      
        public Response updateCustomer(Customer customer) {
          log.info("Executing update Customer operation");
          if (!customers.containsKey(customer.getCustomerId())) {
           return Response.status(Response.Status.BAD_REQUEST)
                    .location(uriInfo.getAbsolutePath())
                    .entity("customer not found")
                    .header("Access-Control-Allow-Origin", ACCESS_CONTROL_ALLOW_ORIGIN)
                    .build();
          }
          customers.put(customer.getCustomerId(), customer);
          return Response.ok(uriInfo.getAbsolutePath())
                         .entity(customer)
                         .header("Access-Control-Allow-Origin", ACCESS_CONTROL_ALLOW_ORIGIN)
                         .build();
        }
      
        /**
         * Init method is used to prepare data which we 
         * will use for testing purpose.
         * usage of this method is defined in bean definition.
         */
        public void init() {
          Customer cus1 = new Customer();
          cus1.setCustomerId(1l);
          cus1.setCustomerName("Kaustuv Maji");
          cus1.setPhone(9830098300l);
          Address add = new Address();
          add.setStreet("saltlake");
          add.setCity("kolkata");
          add.setState("westbengal");
          add.setCountry("India");
          add.setPincode(700106);
          cus1.setAddress(add);
          customers.put(cus1.getCustomerId(), cus1);
          log.info("Added " + cus1.getCustomerName() + " into Customer info");
          Customer cus2 = new Customer();
          cus2.setCustomerId(2l);
          cus2.setCustomerName("customer 2");
          customers.put(cus2.getCustomerId(), cus2);
          log.info("Added " + cus2.getCustomerName() + " into Customer info");
          log.info("Customer info map contains " + customers.size() + " details");
        }
      
        /**
         * destroy method is also used after our testing purpose is done.
         * usage of this method is defined in bean definition.
         */
        public void destroy() {
          log.info("Cleaning up customers info map");
          customers.clear();
        }
      }
      

    15. Create a xml file name global-beans.xml under WEB-INF/conf
    16. <beans xmlns="http://www.springframework.org/schema/beans" 
      xmlns:cache="http://www.springframework.org/schema/cache" 
      xmlns:p="http://www.springframework.org/schema/p"
      xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
      xmlns:cxf="http://cxf.apache.org/core" 
      xmlns:jaxrs="http://cxf.apache.org/jaxrs"
      xsi:schemaLocation="
      http://www.springframework.org/schema/beans
      http://www.springframework.org/schema/beans/spring-beans.xsd
      http://cxf.apache.org/core 
      http://cxf.apache.org/schemas/core.xsd
      http://cxf.apache.org/jaxrs
      http://cxf.apache.org/schemas/jaxrs.xsd"
          default-lazy-init="false">
          <import resource="classpath:META-INF/cxf/cxf*.xml" />
          <!-- Cxf Jason provider -->
          <bean id="jsonProvider" class="org.apache.cxf.jaxrs.provider.JSONProvider">
              <property name="dropRootElement" value="true" />
              <property name="supportUnwrapped" value="true" />
          </bean>
          <!-- Cxf Jaxb Provider -->
          <bean id="jaxbXmlProvider" class="org.apache.cxf.jaxrs.provider.JAXBElementProvider" />
          <!-- Cxf Cors filter (cross domain purpose)-->
          <bean id="cors-filter" class="org.apache.cxf.jaxrs.cors.CrossOriginResourceSharingFilter"/>
      </beans>
      

    17. Create a xml name jaxrs-beans.xml under WEB-INF/conf

    18. <?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:jaxrs="http://cxf.apache.org/jaxrs"
      xmlns:cxf="http://cxf.apache.org/core" 
          xsi:schemaLocation="
      http://www.springframework.org/schema/beans
      http://www.springframework.org/schema/beans/spring-beans.xsd
      http://cxf.apache.org/core 
      http://cxf.apache.org/schemas/core.xsd
      http://cxf.apache.org/jaxrs
      http://cxf.apache.org/schemas/jaxrs.xsd"
          default-lazy-init="false">
          <!-- Service -->
          <bean id="customerService" class="com.kaustuv.jaxrs.example.service.DemoCustomerServiceImpl" 
          init-method="init" 
          destroy-method="destroy" />
          <!-- Jaxrs Server -->
          <jaxrs:server id="restserver" address="/customerService">
              <!-- adding service bean -->
              <jaxrs:serviceBeans>
                  <ref bean="customerService" />
              </jaxrs:serviceBeans>
              <!-- adding media type provider -->
              <jaxrs:providers>
                  <ref bean="jsonProvider" />
                  <ref bean="jaxbXmlProvider" />
                  <ref bean="cors-filter" />
              </jaxrs:providers>
              <jaxrs:features>
                  <cxf:logging/>
              </jaxrs:features>
              <!-- Keeping extention type -->
              <jaxrs:extensionMappings>
                  <entry key="json" value="application/json" />
                  <entry key="xml" value="application/xml" />
              </jaxrs:extensionMappings>
          </jaxrs:server>
      </beans>
      

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

























    20. Open command prompt and go to directory %JBOSS_HOME\bin .
    21. Execute run.bat -c default -b 0.0.0.0
    22. click on our wadl url for our restful webservice project.
    23. http://localhost:8080/jaxrs-example/customerService?_wadl






























      • Post Development testing

    1. open soap ui and create a new project using our wadl url.
    2. http://localhost:8080/jaxrs-example/customerService?_wadl



      Test Http GET Method
    3. Explore soap ui project name RestCustomerService. Select Request of service getCustomerById
    4. enter value of parameter custId in following example picture value is 2 . click on submit



    5. Test Http POST Method
    6. Explore soap ui project name RestCustomerService. Select Request of service addCustoer
    7. enter customer xml use following snippet and click on submit .
    8. <customer>
      <customerId>3</customerId>
      <customerName>testPost</customerName>
      <phoneNumber>9831098301</phoneNumber>
      <address>
      <street>saltlake</street>
      <city>kolkata</city>
      <state>westbengal</state>
      <country>India</country>
      <pincode>700064</pincode>
      </address>
      </customer>

       





      Test Http PUT Method
    9. Explore soap ui project name RestCustomerService. Select Request of service updateCustomer
    10. enter customer xml use following snippet and click on submit .

    11. <customer>
      <customerId>3</customerId>
      <customerName>testUpdate</customerName>
      <phoneNumber>9831098301</phoneNumber>
      <address>
      <street>saltlake</street>
      <city>kolkata</city>
      <state>westbengal</state>
      <country>India</country>
      <pincode>700064</pincode>
      </address>
      </customer>

       




      Test Http DELETE Method
    12. Explore soap ui project name RestCustomerService. Select Request of service deleteCustomer
    13. enter value of parameter custId in following example picture value is 3 . click on submit .


    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:
    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.

    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.

    Friday, 5 April 2013

    Jboss Tomcat Https Configuration


    This post is to enable https configuration using a self-signed certificate on a Jboss application server. 
    There are few common steps we can use to configure https on tomcat server.
    • Pre-requsite
      • Instructions assume that jdk and jboss installation is done without any error.
    • Generating certificates and keystore private using keytool
      • Creating the keystore and private key
    1.Open a Command-line or Terminal window and go to %JBOSS_HOME%/server/default/conf.
    2.Execute "keytool -genkey -alias jbosskey -keypass changeit -keyalg RSA -keystore server.keystore" .
       (use host name as first and last name)

         3.server.keystore is generated.
         4.Execute "keytool -list -keystore server.keystore".


      • Generating and storing the certificate.
       1. Execute 
    "keytool -export -alias jbosskey -keypass changeit -file server.crt - keystore server.keystore". 
       2. server.crt is generated.
       3. Execute 
    "keytool -import -alias jbosscert -keypass changeit -file server.crt -keystore server.keystore".
       4. Execute "keytool -list -keystore server.keystore". User will see see a TrustedCertEntry named jbosscert in the listing.

    • Jboss Configuration 
      • JVM parameter 
    Edit %JBOSS_HOME%/bin/run.bat file add following jvm argument in "JAVA_OPTS" of server

    "-Djavax.net.debug=SSL
    -Djavax.net.ssl.trustStore=%JBOSS_HOME%\server\default\conf\server.keystore
    -Djavax.net.ssl.keyStorePassword=changeit"
    

    • JBoss Web Configuration 

    1. Edit %JBOSS_HOME%\server\default\deploy\jboss-web.deployer\server.xml and add following "<connector>". In case of tomcat we will configure following 
    in %TOMCAT_HOME%\server\conf\server.xml
      • Basic Configuration  
    <Connector port="8443" 
          minSpareThreads="5" maxSpareThreads="75"
          enableLookups="true" disableUploadTimeout="true" 
          acceptCount="100"  maxThreads="200"
          scheme="https" secure="true" SSLEnabled="true"
          keystoreFile="/conf/server.keystore" keystorePass="changeit"
          clientAuth="false" sslProtocol="TLS"/>
    
      • With protocal parameter
    <Connector
               protocol="org.apache.coyote.http11.Http11Protocol"
               port="8443" minSpareThreads="5" maxSpareThreads="75"
               enableLookups="true" disableUploadTimeout="true" 
               acceptCount="100"  maxThreads="200"
               scheme="https" secure="true" SSLEnabled="true"
               keystoreFile="conf/server.keystore" keystorePass="changeit"
               clientAuth="false" sslProtocol="TLS"/>