Thursday, February 16, 2012

JAX WS Webservice Example

In this article, we will see an example of creating traditional webservice using JAX WS in webspere. The approach used here is Top down approach, where we will write/have a WSDL file from which we will generate the Java code. Here we have WSDL for simple webservice, which will send message appended with the string argument that we pass. Below is the WSDL file.

<?xml version="1.0" encoding="UTF-8"?>
<definitions name="HelloService"
      targetNamespace="http://www.training.com/wsdl/HelloService.wsdl" xmlns="http://schemas.xmlsoap.org/wsdl/"
      xmlns:soap="http://schemas.xmlsoap.org/wsdl/soap/" xmlns:tns="http://www.training.com/wsdl/HelloService.wsdl"
      xmlns:xsd="http://www.w3.org/2001/XMLSchema">

      <message name="SayHelloRequest">
            <part name="firstName" type="xsd:string" />
      </message>
      <message name="SayHelloResponse">
            <part name="greeting" type="xsd:string" />
      </message>

      <portType name="Hello_PortType">
            <operation name="sayHello">
                  <input message="tns:SayHelloRequest" />
                  <output message="tns:SayHelloResponse" />
            </operation>
      </portType>

      <binding name="Hello_Binding" type="tns:Hello_PortType">
            <soap:binding style="rpc"
                  transport="http://schemas.xmlsoap.org/soap/http" />
            <operation name="sayHello">
                  <soap:operation soapAction="sayHello" />
                  <input>
                        <soap:body encodingStyle="http://schemas.xmlsoap.org/soap/encoding/"
                              namespace="urn:examples:helloservice" use="literal" />
                  </input>
                  <output>
                        <soap:body encodingStyle="http://schemas.xmlsoap.org/soap/encoding/"
                              namespace="urn:examples:helloservice" use="literal" />
                  </output>
            </operation>
      </binding>

      <service name="Hello_Service">
            <documentation>WSDL File for HelloService</documentation>
            <port binding="tns:Hello_Binding" name="Hello_Port">
                  <soap:address location="http://localhost:9080/TestWS/Hello_Service" />
            </port>
      </service>
</definitions>
So now we need to generate our Java Classes and Interfaces using JAX-WS, You can either use the tool in IBM RSA or Eclipse or you can do it using the ant task. The generated files would be like the one below.

//
// Generated By:JAX-WS RI IBM 2.0_03-01/12/2008 07:02 PM(foreman)-fcs (JAXB RI IBM 2.0.5-08/16/2007 01:18 PM(foreman)-fcs)
//


import javax.jws.WebMethod;
import javax.jws.WebParam;
import javax.jws.WebResult;
import javax.jws.WebService;
import javax.jws.soap.SOAPBinding;

@WebService(name = "Hello_PortType", targetNamespace = "http://www.examples.com/wsdl/HelloService.wsdl")
@SOAPBinding(style = SOAPBinding.Style.RPC)
public interface HelloPortType {

                /**
                 *
                 * @param firstName
                 * @return returns java.lang.String
                 */
                @WebMethod(action = "sayHello")
                @WebResult(name = "greeting", partName = "greeting")
                public String sayHello(
                                                @WebParam(name = "firstName", partName = "firstName") String firstName);

}


@javax.jws.WebService(endpointInterface = "com.examples.wsdl.helloservice.HelloPortType",
                                targetNamespace = "http://www.examples.com/wsdl/HelloService.wsdl",
                                serviceName = "Hello_Service",
                                portName = "Hello_Port",
                                wsdlLocation = "WEB-INF/wsdl/test.wsdl")
public class HelloServiceWS {

                public String sayHello(String firstName) {
                               
                                return "message from web service" + firstName;
                }

}

Now it’s time to package the files in Jar, War and Ear files.  Make sure the WSDL file is located in the WSDL directory within WEB-INF directory. Deploy the archive files in the server. I have used IBM WAS 6.1.
Once you deploy the application, hit the URL to check whether the WS has been deployed correctly.
To access the webservice from the client, the client should contain following piece of code, Here I have used Dynamic Invocation Interface (DII) pattern to access web service. Make sure you have IBM WAS version 6.1.0.35 or more, as lower version of WAS doesn’t support webservice call, unless you have patch for it.
The request and response object type that are used in the webservice should be serializable,  To make it we need to use the Serializer and De-Serializer factory and register it to  the Type Mapping registry via Type mapping. Find the Highlighted ones in the below java code


import java.net.MalformedURLException;
import java.rmi.RemoteException;

import javax.xml.namespace.QName;
import javax.xml.rpc.Call;
import javax.xml.rpc.ParameterMode;
import javax.xml.rpc.Service;
import javax.xml.rpc.ServiceException;
import javax.xml.rpc.ServiceFactory;
import javax.xml.rpc.encoding.DeserializerFactory;
import javax.xml.rpc.encoding.SerializerFactory;
import javax.xml.rpc.encoding.TypeMapping;
import javax.xml.rpc.encoding.TypeMappingRegistry;
import javax.xml.rpc.encoding.XMLType;

import com.ibm.ws.webservices.engine.encoding.ser.BeanDeserializerFactory;
import com.ibm.ws.webservices.engine.encoding.ser.BeanSerializerFactory;

public class WebServiceTester {

                public static void main(String[] args) throws ServiceException,
                                                MalformedURLException, RemoteException {

                                try {

                                                // create the Service client object
                                                // using the wsdl and his service name
                                                String wsdlURL = "http://localhost:9080/TestWS/Hello_Service?wsdl";
                                                String serviceN = "Hello_Service";
                                                QName serviceName = new QName(wsdlURL, serviceN);
                                                ServiceFactory factory = ServiceFactory.newInstance();
                                                Service service = factory.createService(serviceName);
                                                System.out.println("" + service.getServiceName());
                                                // System.out.println(""+service.getPorts().next());
                                                // Call object
                                                Call call = service.createCall();

                                                // operation name
                                                String endPointURL = "http://localhost:9080/TestWS/Hello_Service";
                                                String operationNameString = "sayHello";
                                                QName operationName = new QName(endPointURL, operationNameString);
                                                call.setOperationName(operationName);

                                                call
                                                                                .addParameter("firstName", XMLType.XSD_STRING,
                                                                                                                ParameterMode.IN);

                                                // setting return type
                                                call.setReturnType(XMLType.XSD_STRING);

                                                TypeMappingRegistry vTMR = service.getTypeMappingRegistry();
                                                TypeMapping vTM = vTMR.createTypeMapping();
                                                vTMR.register("", vTM);
                                                SerializerFactory vSerializerFactory = BeanSerializerFactory
                                                                                .createFactory(BeanSerializerFactory.class, String.class,
                                                                                                                XMLType.XSD_STRING);
                                                DeserializerFactory vDeserializerFactory = BeanDeserializerFactory
                                                                                .createFactory(BeanDeserializerFactory.class, String.class,
                                                                                                                XMLType.XSD_STRING);
                                                System.out
                                                                                .println("vDeserializerFactory : " + vDeserializerFactory);
                                                System.out.println("vSerializerFactory : " + vSerializerFactory);
                                                vTM.register(String.class, operationName, vSerializerFactory,
                                                                                vDeserializerFactory);

                                                // specify the RPC-style operation.
                                                call.setProperty(Call.OPERATION_STYLE_PROPERTY, "rpc");
                                                // and the encoding style

                                                // the target endpoint
                                                call.setTargetEndpointAddress(endPointURL);

                                                // Invoke the method readLSpercent
                                                String s = " XXX";
                                                Object[] myArgs = { s };
                                                System.out.println("call.getReturnType():" + call.getReturnType());
                                                // call.invokeOneWay(myArgs);
                                                Object lsVal = call.invoke(myArgs);
                                                System.out.println("Webservice Message::  " + lsVal.toString());
                                } catch (Throwable th) {
                                                th.printStackTrace();
                                }
                }

}