Friday, July 22, 2011

JAX-WS Tutorial



Java API for XML Web Services (JAX-WS), is a set of APIs for creating web services in XML format (SOAP). JAX-WS provides many annotation to simplify the development and deployment for both web service clients and web service providers (endpoints).

Quick Start:-
 Some quick start examples for JAX-WS 2.x.

jax-ws-disgram
WS Communication Using JAX-WS


 For developing JAX-WS based service's  we have a two choice


1:- RPC Style
2:-Document Style

Iam showing example with Document Style web services

Here are the steps to create a document style web service in JAX-WS.
1. Create a Web Service Endpoint Interface 
Actually, annotated with @SOAPBinding is optional, because the default style is document.


File : HelloWorld.java 


package com.amit.ws;
import javax.jws.WebMethod;
import javax.jws.WebService;
import javax.jws.soap.SOAPBinding
import javax.jws.soap.SOAPBinding.Style;
 
//Service Endpoint Interface
@WebService
@SOAPBinding(style = Style.DOCUMENT, use=Use.LITERAL) //optional
public interface HelloWorld{
   @WebMethod String getHelloWorldAsString(String name);
}

2. Create a Web Service Endpoint Implementation 

File : HelloWorldImpl.java

package com.amit.ws;

 import javax.jws.WebService;
 
  //Service Implementation
@WebService(endpointInterface = "com.amit.ws.HelloWorld")
public class HelloWorldImpl implements HelloWorld{
 
 @Override
 public String getHelloWorldAsString(String name) {
  return "Hello World JAX-WS " + name;
 }
 
}
3. Create a Endpoint Publisher.
File : HelloWorldPublisher.java


package com.amit.endpoint;
 
import javax.xml.ws.Endpoint;
import com.amit.ws.HelloWorldImpl;
 
//Endpoint publisher
  public class HelloWorldPublisher{
 
  public static void main(String[] args) {
    Endpoint.publish("http://localhost:8080/ws/hello", new HelloWorldImpl());
    }
 } 
 
 4. wsgen command
    Document style requires extra classes to run, you can use “wsgen” 
    to generate all necessary 
   Java artifacts (mapping classes, wsdl or xsd schema). The “wsgen” 
   command is required to read a
   service endpoint implementation class :
 
   wsgen -keep -cp . com.amit.ws.HelloWorldImpl
 
 If you want this task Automated,write Ant script for building it.
 Here is Sample Ant Script For generating artifacts for your service. 
 
<?xml version="1.0" ?>
 <project name="WS" default="compress">   
    <path id="compile.classpath">
         <fileset dir="lib">
              <include name="*.jar"/>
            </fileset>
     </path>
 
  <target name="init">
    <mkdir dir="build/classes"/>
    <mkdir dir="dist"/>
    <mkdir dir="src/wsdl"/>
  </target>
  
   <target name="clean">
     <delete dir="build" />
     <delete dir="dist" />
     <delete dir="src/wsdl" />
     <delete dir="bin" />
    </target>

 <target name="compile" depends="init">
     <javac srcdir="src" destdir="build/classes" includeantruntime="false">
      <classpath refid="compile.classpath"/>
     </javac>
  </target>
  
  <target name="compress" depends="compile">
           <jar destfile="dist/WS.jar" basedir="build/classes">
            <manifest >
               <attribute name="main-class" value="com.amit.endpoint.
                 HelloWorldPublisher"/>
             </manifest>
            </jar>  
  </target>
  
    <target name="execute" depends="ws">
      <java classname="com.amit.endpoint.HelloWorldPublisher" 
      classpath="build/classes"></java>
    </target> 
  
  <property name="java.home1" value="C:/Program Files (x86)/Java/jdk1.6.0_20"/>  
      <property name="class-dir" value="build/classes/"/>   
      <property name="wsgen-outdir" value="build/classes/"/>   
      <property name="wsdl-outdir" value="src/wsdl/"/>   
      <property name="src-outdir" value="src/"/>   
      <property name="gen-classdir" value="build/classes/"/>   
      <property name="wsgen-cmd" value="${java.home1}/bin/wsgen"/>   
      <echo message="###############calling the web services generation 
       task wsgen####################" />   
      <target name="ws">   
          <exec executable="${wsgen-cmd}">   
             <arg value="-verbose"/>   
             <arg value="-classpath"/>   
             <arg value="${class-dir}"/>   
             <arg value="-wsdl"/>   
             <arg value="-d"/>   
             <arg value="${wsgen-outdir}"/>   
             <arg value="-r"/>   
             <arg value="${wsdl-outdir}"/>   
             <arg value="-s"/>   
             <arg value="${src-outdir}"/>   
             <arg value="-servicename"/>
           <arg value="{http://ws.amit.com/}HelloWorldImplService"/> 
             <arg value="-portname"/>
          <arg value="{http://ws.amit.com/}HelloWorldImplServicePort"/>
           <arg value="-keep"/>   
             <arg value="com.amit.ws.HelloWorldImpl" />   
          </exec>   
    </target>
 </project>
 
 also build ant.bat for Windows and ant.sh for Unix here is the
 sample ant.bat file 
 
 ant.bat
"%JAVA_HOME%\bin\java" -jar G:\test\lib\ant-launcher.jar %1 %2 %3 %4 %5 %6 
 
go to your project home dir then fire  task
 C:/ws/>ant 
and then 
C:/ws/>ant ws
then it will generate artifacts (mapping classes, wsdl or xsd schema)
It will generate two classes inside your src dir with automatically generated 
package "jws" e.g like in my directory structure com.amit.ws.jws and inside 
jws two java files  

File : GetHelloWorldAsString.java

package com.amit.ws.jaxws;

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;
 
@XmlRootElement(name = "getHelloWorldAsString"
namespace = "http://ws.amit.com/")
@XmlAccessorType(XmlAccessType.FIELD)
@XmlType(name = "getHelloWorldAsString"
namespace = "http://ws.amit.com/")
public class GetHelloWorldAsString {
 
    @XmlElement(name = "arg0", namespace = "")
    private String arg0;
 
    /**
     * 
     * @return
     *     returns String
     */
    public String getArg0() {
        return this.arg0;
    }
 
    /**
     * 
     * @param arg0
     *     the value for the arg0 property
     */
    public void setArg0(String arg0) {
        this.arg0 = arg0;
    }
 
}

 File : GetHelloWorldAsStringResponse.java


package com.amit.ws.jaxws;
 
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;
 
@XmlRootElement(name = "getHelloWorldAsStringResponse",
 namespace = "http://ws.amit.com/")
@XmlAccessorType(XmlAccessType.FIELD)
@XmlType(name = "getHelloWorldAsStringResponse"
namespace = "http://ws.amit.com/")
public class GetHelloWorldAsStringResponse {
 
    @XmlElement(name = "return", namespace = "")
    private String _return;
 
    /**
     * 
     * @return
     *     returns String
     */
    public String getReturn() {
        return this._return;
    }
 
    /**
     * 
     * @param _return
     *     the value for the _return property
     */
    public void setReturn(String _return) {
        this._return = _return;
    }
 
}
 

5. Done

Done, publish it and test it via URL : http://localhost:8080/ws/hello?wsdl.


TO BE CONTINUED..........
                                                                          THANKS
                                                                         @Amit Rawat