Tuesday, August 16, 2011

JAX-WS(Java Api For Xml Based Web Service) Integration With Web Application

In previous post JAX-WS Tutorial we discussed about how to create web service using JAX-WS API and create a Simple SEI(Service Endpoint) and publish that service end point using simple java program on existing running web application, Now i am going to discussed with you,"How to integrate JAX-WS enabled service with your simple web application".

Often times, JAX-WS always be part of your Java web application. Here i show you how to integrate JAX-WS into Java web application easily,only some basic step which are as follows.

 1:-Directory structure of your web application
 

2:-create a simple Endpoint
package com.amit.ws;
 
import javax.jws.WebMethod;
import javax.jws.WebService;
 
@WebService
public class HelloWorld{
 
 @WebMethod(operationName="getHelloWorld")
 public String getHelloWorld(String name) {
  return "Hello World JAX-WS " + name;
 }
 
}
 

3:-create we service deployment descriptor(sun-jaxws.xml) in your WEB-INF folder

<?xml version="1.0" encoding="UTF-8"?>
<endpoints
  xmlns="http://java.sun.com/xml/ns/jax-ws/ri/runtime"
  version="2.0">
  <endpoint
      name="HelloWorldWs"
      implementation="com.amit.ws.HelloWorld"
      url-pattern="/hello"/>
</endpoints>
 
4:-Make following entries on your web.xml file
  
1:-Defines “com.sun.xml.ws.transport.http.servlet.WSServletContextListener” as listener class.  
2:-Defines “com.sun.xml.ws.transport.http.servlet.WSServlet” as your web service (hello) servlet. 
      here is content of web.xml file,

<!DOCTYPE web-app PUBLIC
 "-//Sun Microsystems, Inc.//DTD Web Application 2.3//EN"
 "http://java.sun.com/dtd/web-app_2_3.dtd" >
 
<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>hello</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>hello</servlet-name>
  <url-pattern>/hello</url-pattern>
 </servlet-mapping>
 
</web-app>
 
5:-Done
   The integration between JAX-WS and web application is done. Deploy it and access 
   via URL : http://localhost:8080/WebServicesExample/hello 
  
   here is the output look like this on your web browser,
Web Services


Endpoint Information
Service Name: {http://ws.amit.com/}HelloWorldImplService
Port Name: {http://ws.amit.com/}HelloWorldImplPort
Address: http://localhost:8090/HelloWorld-20110808/hello
WSDL: http://localhost:8090/HelloWorld-20110808/hello?wsdl
Implementation class: com.amit.ws.HelloWorldImpl


And when you click on http://localhost:8090/HelloWorld-20110808/hello?wsdl (wsdl uri) it will show you wsdl generated xml,here it is the generated wsdl code.



This XML file does not appear to have any style information associated with it. The document tree is shown below.
<!--
Published by JAX-WS RI at http://jax-ws.dev.java.net. RI's version is JAX-WS RI 2.2.1-b01-.
-->
<!--
Generated by JAX-WS RI at http://jax-ws.dev.java.net. RI's version is JAX-WS RI 2.2.1-b01-.
-->
<types/>
<message name="getHelloWorldAsString"/>
<message name="getHelloWorldAsStringResponse">
<part name="return" type="xsd:string"/>
</message>
<portType name="HelloWorld">
<operation name="getHelloWorldAsString">
<input wsam:Action="http://ws.amit.com/HelloWorld/getHelloWorldAsStringRequest" message="tns:getHelloWorldAsString"/>
<output wsam:Action="http://ws.amit.com/HelloWorld/getHelloWorldAsStringResponse" message="tns:getHelloWorldAsStringResponse"/>
</operation>
</portType>
<binding name="HelloWorldImplPortBinding" type="tns:HelloWorld">
<soap:binding transport="http://schemas.xmlsoap.org/soap/http" style="rpc"/>
<operation name="getHelloWorldAsString">
<soap:operation soapAction=""/>
<input>
<soap:body use="literal" namespace="http://ws.amit.com/"/>
</input>
<output>
<soap:body use="literal" namespace="http://ws.amit.com/"/>
</output>
</operation>
</binding>
<service name="HelloWorldImplService">
<port name="HelloWorldImplPort" binding="tns:HelloWorldImplPortBinding">
</port>
</service>
</definitions>



                                @Amit Rawat























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













Sunday, February 20, 2011

Spring DI

Java components / classes should be as independent as possible of other Java classes. This increases the possibility to reuse these classes and to test them independently of other classes(Unit Testing).
To decouple Java components from other Java components the dependency to a certain other class should get injected into them rather that the class itself creates / finds this object.
A class A has a dependency to class B if class uses class B as a variable.
If dependency injection is used then the class B is given to class A via
  • the constructor of the class A - this is then called construction injection
  • a setter - this is then called setter injection
The general concept between dependency injection is called Inversion of Control.
A class should not configure itself but should be configured from outside.
A design based on independent classes / components increases the re-usability and possibility to test the software. For example if a class A expects a Dao (Data Access object) for receiving the data from a database you can easily create another test object which mocks the database connection and
inject this object into A to test A without having an actual database connection.
A software design based on dependency injection is possible with standard Java.
Spring just add some simplifications in using dependency injection by providing a standard way
of providing the configuration and by managing the reference to the created objects.

example of DI u can try it out:-
A helper class with a setter method.
package com.amit.output;
 
import com.amit.output.IOutputGenerator;
 
public class OutputHelper
{
 IOutputGenerator outputGenerator;
 
 public void setOutputGenerator(IOutputGenerator outputGenerator){
  this.outputGenerator = outputGenerator;
 }
 
}
A bean configuration file to declare the beans and set the dependency 
via setter injection (property tag).
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-2.5.xsd">
 
 <bean id="OutputHelper" class="com.amit.output.OutputHelper">
  <property name="outputGenerator">
   <ref bean="CsvOutputGenerator" />
  </property>
 </bean>
 
<bean id="CsvOutputGenerator" class="com.amit.output.impl.
CsvOutputGenerator" />
<bean id="JsonOutputGenerator" class="com.amit.output.impl.
JsonOutputGenerator" />
 
</beans>
 that is output generator is out put generator gernal class that is injected by
 any input generator dependancy.....
                                    @amit rawat