Wednesday, February 07, 2007

Web Services

server
RPC Server Endpoint
Developing Web Services
Developing Web Services from WSDL
wscompile ant task
wscompile ant init
Model Packaging with Namespace var
wscompile server

(now it's a example of a document end point)


C:\projects\workspace\cal-ws>wscompile -cp ./WebContent/WEB-INF/classes -gen:server -f:documentliteral -mapping ./WebContent/META-INF/jaxrpc-mapping.xml -keep -d ./WebContent/WEB-INF/classes -s ./src -nd ./WebContent/WEB-INF/wsdl config.xml


wscompile needs a configuration file for its operation, we use



<configuration
xmlns="http://java.sun.com/xml/ns/jax-rpc/ri/config">

<service name="HelloWorldService"
targetNamespace="http://com.comira.cal.ws/samples"
typeNamespace="http://com.comira.cal.ws/samples/types"
packageName="com.comira.cal.ws">
<interface name="com.comira.cal.ws.IHelloWorldWS"/>
</service>

</configuration>

Need the web.xml



<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns="http://java.sun.com/xml/ns/j2ee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation = "http://java.sun.com/xml/ns/j2ee http://java.sun.com/xml/ns/j2ee/web-app_2_4.xsd"
version="2.4">
<servlet>
<servlet-name>HelloWorldService</servlet-name>
<servlet-class>com.comira.cal.ws.HelloWorldWS</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>HelloWorldService</servlet-name>
<url-pattern>/HelloWorldService</url-pattern>
</servlet-mapping>
</web-app>

One more descriptor is needed that glues everything together. It is called webservices.xml, is placed in WEB-INF, and must also be coded by hand. Here it is:



<webservices
xmlns="http://java.sun.com/xml/ns/j2ee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://java.sun.com/xml/ns/j2ee http://www.ibm.com/webservices/xsd/j2ee_web_services_1_1.xsd"
version="1.1">

<webservice-description>
<webservice-description-name>HelloWorldServiceJSE</webservice-description-name>
<wsdl-file>WEB-INF/wsdl/HelloWorldService.wsdl</wsdl-file>
<jaxrpc-mapping-file>WEB-INF/jaxrpc-mapping.xml</jaxrpc-mapping-file>
<port-component>
<port-component-name>PortComponent</port-component-name>
<wsdl-port>IHelloWorldWSPort</wsdl-port>
<service-endpoint-interface>com.comira.cal.ws.IHelloWorldWS</service-endpoint-interface>
<service-impl-bean>
<servlet-link>HelloWorldService</servlet-link>
</service-impl-bean>
</port-component>
</webservice-description>
</webservices>


Then we package everything together and deploy to JBoss. On the server we should see messages like this



23:12:56,515 INFO [TomcatDeployer] deploy, ctxPath=/ws4ee-samples-server-jse, warUrl=file:/.../ws4ee-samples-server-jse-exp.war/
23:12:57,125 INFO [WSDLFilePublisher] WSDL published to: file:/.../data/wsdl/ws4ee-samples-server-jse.war/OrganizationService.wsdl
23:12:57,546 INFO [AxisService] WSDD published to: ...\data\wsdl\ws4ee-samples-server-jse.war\PortComponent.wsdd
23:12:58,328 INFO [AxisService] Web Service deployed: http://TDDELL:8080/ws4ee-samples-server-jse/Organization


A potential client can access the WSDL from this address

http://zimbob:8080/calws/HelloWorldService?wsdl
This just basically shows the xml rpc config file:



<?xml version="1.0" encoding="UTF-8"?>
<definitions name="HelloWorldService" targetNamespace="http://com.comira.cal.ws/samples" xmlns="http://schemas.xmlsoap.org/wsdl/" xmlns:soap="http://schemas.xmlsoap.org/wsdl/soap/" xmlns:tns="http://com.comira.cal.ws/samples" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
<types>
</types>
<message name="IHelloWorldWS_sayHelloResponse">
<part name="result" type="xsd:string"/>
</message>
<message name="IHelloWorldWS_sayHello">
<part name="String_1" type="xsd:string"/>
</message>

<portType name="IHelloWorldWS">
<operation name="sayHello" parameterOrder="String_1">
<input message="tns:IHelloWorldWS_sayHello"/>
<output message="tns:IHelloWorldWS_sayHelloResponse"/>
</operation>
</portType>
<binding name="IHelloWorldWSBinding" type="tns:IHelloWorldWS">
<soap:binding style="rpc" transport="http://schemas.xmlsoap.org/soap/http"/>
<operation name="sayHello">

<soap:operation soapAction=""/>
<input>
<soap:body namespace="http://com.comira.cal.ws/samples" use="literal"/>
</input>
<output>
<soap:body namespace="http://com.comira.cal.ws/samples" use="literal"/>
</output>
</operation>
</binding>

<service name="HelloWorldService">
<port binding="tns:IHelloWorldWSBinding" name="IHelloWorldWSPort">
<soap:address location="http://zimbob:8080/calws/HelloWorldService"/>
</port>
</service>
</definitions>


client
RPC Clent

wscompile client
(now it's a example of a document end point)


C:\projects\workspace\cal-ws\client>wscompile -gen:client -f:documentliteral -mapping ./WebContent/META-INF/jaxrpc-mapping.xml -keep -d ./WebContent/WEB-INF/classes -s ./src -nd ./WebContent/WEB-INF/wsdl config.xml


wscompile needs a config file:



<configuration
xmlns="http://java.sun.com/xml/ns/jax-rpc/ri/config">

<wsdl location="http://zimbob:8080/calws/HelloWorldService?wsdl"
packageName="com.comira.cal.ws">
</wsdl>

</configuration>


JAX-RPC Mapping Files
The web service client must have access to the same mapping information as described for the EJB service endpoint or the Java service endpoint. The jaxrpc mapping file must be part of the deployment, it cannot be obtained at runtime.

The standard deployment descriptor for web components web.xml, declares the service reference.



<web-app xmlns="http://java.sun.com/xml/ns/j2ee" version="2.4"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://java.sun.com/xml/ns/j2ee http://java.sun.com/xml/ns/j2ee/web-app_2_4.xsd">

<servlet>
<servlet-name>HelloWorldWSServlet</servlet-name>
<servlet-class>com.comira.cal.client.ws.HelloWorldWSServlet</servlet-class>
</servlet>

<servlet-mapping>
<servlet-name>HelloWorldWSServlet</servlet-name>
<url-pattern>/hello</url-pattern>
</servlet-mapping>

<service-ref>
<service-ref-name>service/HelloWorldServiceJSE</service-ref-name>
<service-interface>com.comira.cal.ws.HelloWorldService</service-interface>
<wsdl-file>META-INF/HelloWorldService.wsdl</wsdl-file>
<jaxrpc-mapping-file>META-INF/jaxrpc-mapping.xml</jaxrpc-mapping-file>
</service-ref>

</web-app>


Here is a simple example, that shows how a servlet does a lookup of the service interface, then obtains the desired port, and finally invokes sayHello on the service endpoint interface.



/**
* $Header: Exp$
* (c) CATSTesting 2007
*
* Created by: graham
* Feb 7, 2007
*/
package com.comira.cal.client.ws;

import java.io.IOException;
import java.io.PrintWriter;

import javax.naming.InitialContext;
import javax.naming.NamingException;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.apache.log4j.Logger;

import com.comira.cal.ws.HelloWorldService;
import com.comira.cal.ws.IHelloWorldWS;

public class HelloWorldWSServlet extends HttpServlet {
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
processRequest(req, resp);
}

protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
processRequest(req, resp);
}

protected void processRequest(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
String name = req.getParameter("name");
String info = getSayHello(name);

PrintWriter out = resp.getWriter();
out.print(info);
out.close();
}

/** Get the contact info from the JSE service */
public String getSayHello(String name) throws ServletException
{
try
{
InitialContext iniCtx = new InitialContext();
HelloWorldService service = (HelloWorldService)iniCtx.lookup("java:comp/env/service/HelloWorldServiceJSE");
IHelloWorldWS endpoint = service.getIHelloWorldWSPort();
String info = endpoint.sayHello(name);
return info;
}
catch (NamingException e)
{
throw new ServletException(e);
}
catch (Exception e)
{
throw new ServletException("Cannot invoke webservice", e);
}
}
}



The client jar breaks down like so:



|---- META-INF
| |
| |- HelloWorldService.wsdl
| |- jaxrpc-mapping.xml
|
|---- WEB-INF
|
|- web.xml
|- /classes


The jaxrpc-mapping.xml is exactly the same as the server endpoint's one and the HelloWorldService.wsdl required the changing of the location of the service.

A call to: http://zimbob:8080/calclientws/hello?name=jay
Resulted in:



Hello World: jay on Wed Feb 07 15:25:52 PST 2007

No comments: