Pages

mardi 23 octobre 2012

WS Tutorial Part I Creating JAX-WS webservice using wsgen


Before you start
About this tutorial

Objectives
In this tutorial, you design and develop a simple application with maven that exposes its functionality as web services  in a platform-independent manner. After going through this tutorial, you can apply the concepts and knowledge to develop web services for your application using JAX-WS technology and maven.
  • We will build it with Maven
  • We will not copy jars to the Tomcat. All dependencies will be managed by Maven
Plan :
   1- Develop a web service maven project
   2- Develop a JAXWS web service with SOAP 1.2
           2.1 Develop a Person Management web service
           2.2 Generate web services artifacts with wsgen
           2.3 Update web.xml 
           2.4 Create web service deployment descriptor sun-jaxws.xml
           2.5 Deployment
           2.6 Test with SOAPUI 4.5.1 :
   3- Develop a web service Client maven project
           3.1 create maven project
           3.2 Generate web services artifacts for client with wsimport
           3.3 A factory, a manager and a main class for test

Prerequisites
To complete this tutorial successfully, you should have a basic understanding of web services technology and have some proficiency in Java programming.

System requirements

To run the examples in this tutorial, you need :
  • Eclipse WTP 3.4 
  • Maven 3.0 
  • JAXWS RT 2.1.3 
  • JAVA 6 
  • TOMCAT 6

Introduction to JAX-WS
Why JAX-WS?

Java API for XML Web Services (JAX-WS), JSR 224, is an important part of the Java EE 5 and EE 6 platforms. A follow-up to the release of Java API for XML-based RPC 1.1(JAX-RPC), JAX-WS simplifies the task of developing web services using Java technology. It addresses some of the issues in JAX-RPC 1.1 by providing support for multiple protocols such as SOAP 1.1, SOAP 1.2, XML, and by providing a facility for supporting additional protocols along with HTTP. JAX-WS uses JAXB 2.0 for data binding and supports customizations to control generated service endpoint interfaces. With its support for annotations, JAX-WS simplifies web service development and reduces the size of runtime JAR files. 

Introduction to Maven
Why Maven?
Maven's primary goal is to allow a developer to comprehend the complete state of a development effort in the shortest period of time. In order to attain this goal there are several areas of concern that Maven attempts to deal with:
  • Making the build process easy
  • Providing a uniform build system
  • Providing quality project information
  • Providing guidelines for best practices development
  • Allowing transparent migration to new features
 1- Develop a web service maven project

·         In command Line type to generate a web project with maven using this command :
mvn archetype:generate -DgroupId=com.aam.jaxws.server -DartifactId=PersonManagementServer -DarchetypeArtifactId=maven-archetype-webapp



·         Maven has generated a folder project called  PersonManagementServer



·         Add Jaxws dependency to pom.xml

<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
        xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
        <modelVersion>4.0.0</modelVersion>
        <groupId>com.aam.jaxws.server</groupId>
        <artifactId>PersonManagementServer</artifactId>
        <packaging>war</packaging>
        <version>1.0</version>
        <name>PersonManagementServer Maven Webapp</name>
        <url>http://maven.apache.org</url>
        <dependencies>
               <dependency>
                       <groupId>junit</groupId>
                       <artifactId>junit</artifactId>
                       <version>3.8.1</version>
                       <scope>test</scope>
               </dependency>
               <dependency>
                       <groupId>com.sun.xml.ws</groupId>
                       <artifactId>jaxws-rt</artifactId>
                       <version>2.1.3</version>
               </dependency>
        </dependencies>
        <build>
               <finalName>PersonManagementServer</finalName>
        </build>
</project>    

·         In command line and under  /PersonManagementServer, type mvn eclipse:eclipse to be able to import the project into eclipse.
·         Import the existing maven project to your workspace.

2- Develop a JAXWS web service with SOAP 1.2

Contract-first approach versus code-first approach

A good way to get initiated into JAX-WS is to first develop a web service. You can develop a web service using one of two approaches:
  • Contract first: Start with a WSDL contract, and generate a Java class to implement the service.
  • Code first: Start with a Java class, and use annotations to generate both a WSDL file and a Java interface.
The contract-first WSDL approach requires a good understanding of WSDL and XSD (XML Schema Definition) for defining message formats. It's a good idea to start with the code-first approach if you're fairly new to web services, which is what you'll use in this tutorial to develop web services.

Code-first web services development

Using the code-first approach, you start with a Java class, or classes, that implements features you want to expose as services. The code-first approach is particularly useful when Java implementations are already available and you need to expose implementations as services.

Requirements of a JAX-WS Endpoint

 JAX-WS endpoints must follow these requirements :

·         The implementing class must be annotated with either the javax.jws.WebService or the javax.jws.WebServiceProvider annotation.
·         The implementing class may explicitly reference an SEI through the endpointInterface element of the @WebService annotation but is not required to do so. If no endpointInterface is specified in@WebService, an SEI is implicitly defined for the implementing class.
·         The business methods of the implementing class must be public and must not be declared static or final.
·         Business methods that are exposed to web service clients must be annotated with javax.jws.WebMethod.
·         Business methods that are exposed to web service clients must have JAXB-compatible parameters and return types. See the list of JAXB default data type bindings athttp://docs.oracle.com/javaee/5/tutorial/doc/bnazq.html#bnazs.
·         The implementing class must not be declared final and must not be abstract.
·         The implementing class must have a default public constructor.
·         The implementing class must not define the finalize method.
·         The implementing class may use the javax.annotation.PostConstruct or the javax.annotation.PreDestroy annotations on its methods for lifecycle event callbacks.

2.1 Develop a Person Management web service

Let's start by creating a person management web service that accepts CIN ID and generates person information as a response. The code for the service is provided Listing 1-2-3-4. This is a dummy implementation that prints the person CIN ID and number of items at the console, then returns a dummy PersonOut response.

Listing 1 : File : PersonManagementService.java
package com.aam.jaxws.server;

import java.util.Date;
import java.util.HashMap;
import java.util.Map;

import javax.jws.WebService;
import javax.xml.ws.BindingType;

@WebService(endpointInterface = "com.aam.jaxws.server.PersonManagement", serviceName = "PersonManagementService", targetNamespace = "http://com.aam.jaxws.server/")
@BindingType(value = "http://java.sun.com/xml/ns/jaxws/2003/05/soap/bindings/HTTP/")
public class PersonManagementService implements PersonManagement {

private static Map<String, PersonOut> persons = new HashMap<String, PersonOut>() {
              {put("p1", new PersonOut("p1", "aam", "aam", new Date()));}
              {put("p2", new PersonOut("p2", "bob", "bob", new Date()));}
       };

@Override
public PersonOut findPersonByCIN(String CIN) throws PersonException {
              return persons.get(CIN);
       };
}


Listing 2 : File : PersonManagement.java

package com.aam.jaxws.server;

import javax.jws.WebParam;
import javax.jws.WebService;
import javax.jws.soap.SOAPBinding;
import javax.jws.soap.SOAPBinding.Style;
import javax.jws.soap.SOAPBinding.Use;

@WebService(name = "PersonManagementService")
@SOAPBinding(style = Style.DOCUMENT, use = Use.LITERAL)
public interface PersonManagement {

public PersonOut findPersonByCIN(@WebParam(name = "CIN") String CIN) throws PersonException;

}


Listing 3 : File : PersonOut.java

package com.aam.jaxws.server;

import java.util.Date;

public class PersonOut {

       private String CIN;
       private String name;
       private String firstName;
       private Date birthDate;
      
      //very important to JAXB
       public PersonOut() {

       }

       public PersonOut(String cIN, String name, String firstName, Date birthDate) {
              super();
              CIN = cIN;
              this.name = name;
              this.firstName = firstName;
              this.birthDate = birthDate;
       }
/* Getters & Setters */
}


Listing 4 : File : PersonException.java

package com.aam.jaxws.server;

public class PersonException extends Exception {

}


@WebService (name = "PersonManagementService")
The starting point for developing a JAX-WS web service is a Java class annotated with the javax.jws.WebService annotation. The JAX-WS annotations used are part of the Web Services Metadata for the Java Platform specification (JSR-181). As you have probably noticed, PersonManagementService is annotated with the WebService annotation, which defines the class as a web service endpoint.

@BindingType(value = "http://java.sun.com/xml/ns/jaxws/2003/05/soap/bindings/HTTP/")
Using this annotation we can specify witch binding we want use (Default SOAP 1.1) and in our case is SOAP 1.2.

@SOAPBinding(style = Style.DOCUMENT, use = Use.LITERAL)
The @SOAPBinding annotation is defined by the javax.jws.soap.SOAPBinding interface. It provides details about the SOAP binding used by the service when it is deployed. If the @SOAPBinding annotation is not specified, a service is published using a wrapped doc/literal SOAP binding.

After the web service is implemented, you need to generate any artifacts required to deploy the service, then package the web service as a deployed artifact—typically as a WAR file—and deploy the WAR file to any compliant server that supports the JAX-WS 2.0 specification. Typical artifacts generated are classes that provide conversion of Java objects to XML, and the WSDL file and XSD schema based on the service interface.

2.2 Generate web services artifacts with wsgen

To generate artifacts we will use maven wsgen plugin, let’s update our pom.xml by adding this build fragment and execute mvn clean install command line under the PersonManagementServer folder.

       <build>
              <finalName>PersonManagementServer</finalName>
       <plugins>
           <plugin>
               <groupId>org.codehaus.mojo</groupId>
               <artifactId>jaxws-maven-plugin</artifactId>
               <version>1.10</version>
               <executions>
                   <execution>
                       <phase>process-classes</phase>
                       <goals>
                           <goal>wsgen</goal>
                       </goals>
                   </execution>
               </executions>
               <configuration>
                   <sei>com.aam.jaxws.server.PersonManagementService</sei>
                   <genWsdl>true</genWsdl>
                   <keep>true</keep>
               <resourceDestDir>${basedir}/src/main/webapp/WEB-INF/wsdl</resourceDestDir>
                   <sourceDestDir>${basedir}/src/main/java</sourceDestDir>
               </configuration>
           </plugin>
       </plugins>
  </build>
  



The wsgen plugin has generated artifacts and wsdl :




2.3 Update web.xml :

Update web.xml deployment descriptor for the deployment. Defines WSServletContextListener as listener class, WSServlet as your PersonManagementService servlet.

<web-app>
       <display-name>Archetype Created Web Application</display-name>

<listener>
     <listener-class>
        com.sun.xml.ws.transport.http.servlet.WSServletContextListener
      </listener-class>
</listener>

       <servlet>
              <servlet-name>PersonManagementService</servlet-name>
              <servlet-class>
                    com.sun.xml.ws.transport.http.servlet.WSServlet
              </servlet-class>
              <load-on-startup>1</load-on-startup>
       </servlet>

       <servlet-mapping>
              <servlet-name>PersonManagementService</servlet-name>
              <url-pattern>/PersonManagementService</url-pattern>
       </servlet-mapping>

       <mime-mapping>
              <extension>txt</extension>
              <mime-type>text/xml</mime-type>
       </mime-mapping>

</web-app>

2.4 Create web service deployment descriptor sun-jaxws.xml:

    Create a web service deployment descriptor, which is also known as JAX-WS RI deployment descriptor – sun-jaxws.xml.

<?xml version="1.0" encoding="UTF-8"?>
<endpoints version="2.0"
       xmlns="http://java.sun.com/xml/ns/jax-ws/ri/runtime">

       <endpoint implementation="com.aam.jaxws.server.PersonManagementService"
              name="PersonManagementService"
              url-pattern="/PersonManagementService"     
      />

</endpoints>


2.5 Deployment :
Copy the generated WAR file to {$TOMCAT}/webapps/ folder and start the Tomcat server.

29-oct.-2012 11:13:59 org.apache.tomcat.util.digester.SetPropertiesRule begin
29-oct.-2012 11:13:59 org.apache.coyote.http11.Http11Protocol init
INFO: Initialisation de Coyote HTTP/1.1 sur http-8080
29-oct.-2012 11:13:59 org.apache.catalina.startup.Catalina load
INFO: Initialization processed in 364 ms
29-oct.-2012 11:13:59 org.apache.catalina.core.StandardService start
INFO: Démarrage du service Catalina
29-oct.-2012 11:13:59 org.apache.catalina.core.StandardEngine start
INFO: Starting Servlet Engine: Apache Tomcat/6.0.35
29-oct.-2012 11:13:59 com.sun.xml.ws.transport.http.servlet.WSServletContextListener contextInitialized
INFO: WSSERVLET12: JAX-WS context listener initializing
29-oct.-2012 11:14:00 com.sun.xml.ws.transport.http.servlet.WSServletDelegate <init>
INFO: WSSERVLET14: JAX-WS servlet initializing
29-oct.-2012 11:14:00 org.apache.coyote.http11.Http11Protocol start
INFO: Démarrage de Coyote HTTP/1.1 sur http-8080
29-oct.-2012 11:14:00 org.apache.jk.common.ChannelSocket init
INFO: JK: ajp13 listening on /0.0.0.0:8009
29-oct.-2012 11:14:00 org.apache.jk.server.JkMain start
INFO: Jk running ID=0 time=0/19  config=null
29-oct.-2012 11:14:00 org.apache.catalina.startup.Catalina start
INFO: Server startup in 1088 ms

For testing, you can access this URL http://localhost:8080/PersonManagementServer/PersonManagementService  , if you see following page, it means web services are deploy successfully.



 <?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<!-- Generated by JAX-WS RI at http://jax-ws.dev.java.net. RI's version is JAX-WS RI 2.1.3-b02-. -->
<definitions targetNamespace="http://com.aam.jaxws.server/" name="PersonManagementService" xmlns="http://schemas.xmlsoap.org/wsdl/" xmlns:tns="http://com.aam.jaxws.server/" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:soap12="http://schemas.xmlsoap.org/wsdl/soap12/">
  <import namespace="http://server.jaxws.aam.com/" location="PersonManagementServicePortType.wsdl"/>
  <binding name="PersonManagementServicePortBinding" type="ns1:PersonManagementService" xmlns:ns1="http://server.jaxws.aam.com/">
    <soap12:binding transport="http://www.w3.org/2003/05/soap/bindings/HTTP/" style="document"/>
    <operation name="findPersonByCIN">
      <soap12:operation soapAction=""/>
      <input>
        <soap12:body use="literal"/>
      </input>
      <output>
        <soap12:body use="literal"/>
      </output>
      <fault name="PersonException">
        <soap12:fault name="PersonException" use="literal"/>
      </fault>
    </operation>
  </binding>
  <service name="PersonManagementService">
    <port name="PersonManagementServicePort" binding="tns:PersonManagementServicePortBinding">
      <soap12:address location="REPLACE_WITH_ACTUAL_URL"/>
    </port>
  </service>
</definitions>


2.6 Test with SOAPUI 4.5.1 :

You have now successfully created and published your web service and Testd it using Soap UI.

You can use this links to Download source code
  DOWNLOAD SERVER PROJECT

After downloading, execute mvn clean install command  and  import the prjectto your eclipse. You can after deploy the WebService in your favorite server and use Soap UI or move on to the next article to generate a java client project using jaxws and maven

END.