Show Table of Contents

Chapter 11. Web Services
The biggest new feature of J2EE 1.4 is the ability of J2EE components to act both as web service providers and consumers. J2EE applications can expose a web service from the EJB tier using a stateless session bean or from the web tier using a plain Java object. Additionally,J2EE components have a standard way of declaring references to external web services.
11.1. JAX-RPC Service Endpoints
JAX-RPC service endpoints (JSEs) provide web services from the web tier. They take the form of a simple Java objects that masquerade as servlets. To show how simple they are, we'll jump right in with a trivial hello web service implementation class.
package org.jboss.ws.hello;
public class HelloPojo
{
public String hello(String name)
{
return "Hello " + name + "!";
}
}
There is nothing remarkable about
HelloPojo. It doesn't implement any special interfaces nor does it need any methods besides the business methods it decides to provide. The hello method is the operation that we will expose as a web service, and it does nothing but respond with a friendly greeting to the person passed in.
That is our web service implementation. In addition to this, we need a service endpoint interface (SEI) that defines the interface of the web service. That is shown here as the
Hello interface.
package org.jboss.ws.hello;
import java.rmi.Remote;
import java.rmi.RemoteException;
public interface Hello
extends Remote
{
public String hello(String name)
throws RemoteException;
}
The service endpoint interface is declared
Remote and the methods must throw RemoteException. Beyond this, it is a simple expression of the interface to our web service. This is all the code we need to write to expose a J2EE web service. Deploying it, however, does require a few additional deployment descriptors.
Although a JSE doesn't bears any direct resemblance to a servlet, it is nonetheless deployed as a servlet in the
web.xml file. We'll need to declare the web service implementation class as a servlet and provide a servlet mapping that will respond to the web service invocations. Here is the definition required to deploy the hello web service.
<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns="http://java.sun.com/xml/ns/"Whats_new_in_JBoss_4-J2EE_Certification_and_Standards_Compliance"
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>HelloWorldWS</servlet-name>
<servlet-class>org.jboss.ws.hello.HelloPojo</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>HelloWorldWS</servlet-name>
<url-pattern>/Hello</url-pattern>
</servlet-mapping>
</web-app>
The URL pattern in the servlet mapping is the only externally visible configuration element. It controls what URL the web service lives at. This will be primarily noticed as the location of the WSDL file for this service.
The
web.xml file doesn't contain any web service related configuration. A new deployment descriptor, webservices.xml, is needed to instruct JBoss to treat this servlet as a web service and not as a normal servlet. We'll need two additional configuration files, a WSDL file and a JAX-RPC mapping file. All of these files can be generated using the wstool generator that ships with JBoss.
wstool can be run from from the command line or as an Ant task. The JBossWS guide explains in more detail how to run the tool. In both cases, wstool needs to be pointed to the code and to a configuration file which describes the files to generate and the endpoint to generate them for. Here is the configuration file for the hello web service.
<configuration xmlns="http://www.jboss.org/jbossws-tools">
<java-wsdl>
<service name="HelloService"
style="rpc"
endpoint="org.jboss.ws.hello.Hello"/>
<namespaces target-namespace="http://hello.ws.jboss.org/"
type-namespace="http://hello.ws.jboss.org/types"/>
<mapping file="jaxrpc-mapping.xml"/>
<webservices servlet-link="HelloWorldWS"/>
</java-wsdl>
</configuration>
For a complete description of this file, see the JBossWS documentation.
The WSDL file that wscompile generated for our
config.xml file is shown below. Note that the SOAP address isn't provided in the WSDL file. JBoss will insert the correct URL for the WSDL when it deploys the web service.
<definitions name="HelloService"
targetNamespace="http://hello.ws.jboss.org/"
xmlns="http://schemas.xmlsoap.org/wsdl/"
xmlns:soap="http://schemas.xmlsoap.org/wsdl/soap/"
xmlns:tns="http://hello.ws.jboss.org/"
xmlns:xsd="http://www.w3.org/2001/XMLSchema">
<types/>
<message name="Hello_hello">
<part name="String_1" type="xsd:string"/>
</message>
<message name="Hello_helloResponse">
<part name="result" type="xsd:string"/>
</message>
<portType name="Hello">
<operation name="hello" parameterOrder="String_1">
<input message="tns:Hello_hello"/>
<output message="tns:Hello_helloResponse"/>
</operation>
</portType>
<binding name="HelloBinding" type="tns:Hello">
<soap:binding style="rpc" transport="http://schemas.xmlsoap.org/soap/http"/>
<operation name="hello">
<soap:operation soapAction=""/>
<input>
<soap:body namespace="http://hello.ws.jboss.org/" use="literal"/>
</input>
<output>
<soap:body namespace="http://hello.ws.jboss.org/" use="literal"/>
</output>
</operation>
</binding>
<service name="HelloService">
<port binding="tns:HelloBinding" name="HelloPort">
<soap:address location="REPLACE_WITH_ACTUAL_URL"/>
</port>
</service>
</definitions>
We also asked wscompile to generate a JAX-RPC mapping file. This is shown below.
<?xml version='1.0' encoding='UTF-8'?>
<java-wsdl-mapping version="1.1"
xmlns="http://java.sun.com/xml/ns/"Whats_new_in_JBoss_4-J2EE_Certification_and_Standards_Compliance"
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_jaxrpc_mapping_1_1.xsd">
<package-mapping>
<package-type>org.jboss.ws.hello</package-type>
<namespaceURI>http://hello.ws.jboss.org/types</namespaceURI>
</package-mapping>
<service-interface-mapping>
<service-interface>org.jboss.ws.hello.HelloService</service-interface>
<wsdl-service-name xmlns:serviceNS="http://hello.ws.jboss.org/">
serviceNS:HelloService
</wsdl-service-name>
<port-mapping>
<port-name>HelloPort</port-name>
<java-port-name>HelloPort</java-port-name>
</port-mapping>
</service-interface-mapping>
<service-endpoint-interface-mapping>
<service-endpoint-interface>org.jboss.ws.hello.Hello</service-endpoint-interface>
<wsdl-port-type xmlns:portTypeNS="http://hello.ws.jboss.org/">
portTypeNS:Hello
</wsdl-port-type>
<wsdl-binding xmlns:bindingNS="http://hello.ws.jboss.org/">
bindingNS:HelloBinding
</wsdl-binding>
<service-endpoint-method-mapping>
<java-method-name>hello</java-method-name>
<wsdl-operation>hello</wsdl-operation>
<method-param-parts-mapping>
<param-position>0</param-position>
<param-type>java.lang.String</param-type>
<wsdl-message-mapping>
<wsdl-message xmlns:wsdlMsgNS="http://hello.ws.jboss.org/">
wsdlMsgNS:Hello_hello
</wsdl-message>
<wsdl-message-part-name>String_1</wsdl-message-part-name>
<parameter-mode>IN</parameter-mode>
</wsdl-message-mapping>
</method-param-parts-mapping>
<wsdl-return-value-mapping>
<method-return-value>java.lang.String</method-return-value>
<wsdl-message xmlns:wsdlMsgNS="http://hello.ws.jboss.org/">
wsdlMsgNS:Hello_helloResponse
</wsdl-message>
<wsdl-message-part-name>result</wsdl-message-part-name>
</wsdl-return-value-mapping>
</service-endpoint-method-mapping>
</service-endpoint-interface-mapping>
</java-wsdl-mapping>
Finally, we generates a
webservices.xml file. This file links to our WSDL file with the wsdl-file element and to the mapping file using the jaxrpc-mapping-file element.
In addition to this, a
port-component element is needed that maps a port in the WSDL file to a particular service implementation. For our JSE, this is done with a servlet-link inside the service-impl-bean element. The servlet link must be the same as the name of the pseudo-servlet we declared in the web.xml file.
<webservices version="1.1"
xmlns="http://java.sun.com/xml/ns/"Whats_new_in_JBoss_4-J2EE_Certification_and_Standards_Compliance" xmlns:impl="http://hello.ws.jboss.org/"
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">
<webservice-description>
<webservice-description-name>HelloService</webservice-description-name>
<wsdl-file>WEB-INF/wsdl/HelloService.wsdl</wsdl-file>
<jaxrpc-mapping-file>WEB-INF/jaxrpc-mapping.xml</jaxrpc-mapping-file>
<port-component>
<port-component-name>HelloPort</port-component-name>
<wsdl-port>impl:HelloPort</wsdl-port>
<service-endpoint-interface>org.jboss.ws.hello.Hello</service-endpoint-interface>
<service-impl-bean>
<servlet-link>HelloWorldWS</servlet-link>
</service-impl-bean>
</port-component>
</webservice-description>
</webservices>
With these completed we can deploy the WAR file containing our web service. All the deployment descriptors go in the
WEB-INF directory, as shown in Figure 11.1, “The structure of hello-servlet.war”. It's important to note that the WSDL file is required to be in the wsdl subdirectory.

Figure 11.1. The structure of hello-servlet.war
To deploy and test the hello web service, run the following from the examples directory:
[examples]$ ant -Dchap=ws -Dex=1 run-example
...
run-example1:
[echo] Waiting for 5 seconds for deploy...
[java] Contacting webservice at http://localhost:8080/hello-servlet/Hello?wsdl
[java] hello.hello(JBoss user)
[java] output:Hello JBoss user!
The server log will contain information about the deployment including the temporary location of the generated WSDL and wsdd files. It also shows the full URL of the web service.
Note the URL the JBoss publishes the WSDL file at. Our web application name is
hello-servlet and we mapped the servlet to /Hello in the web.xml file so the web service is mappend to /hello-servlet/Hello. The ?wsdl query returns the WSDL file.
If you aren't sure what the URL of the WSDL file will be, JBoss provides a way to list the web services available on the system at
/jbossws/services. Figure 11.2, “The web services list” shows a view of the services list.

Figure 11.2. The web services list
The services list shows all of the deployed web services along with the name of the deployment unit and a link to the WSDL file for that service.

Where did the comment section go?
Red Hat's documentation publication system recently went through an upgrade to enable speedier, more mobile-friendly content. We decided to re-evaluate our commenting platform to ensure that it meets your expectations and serves as an optimal feedback mechanism. During this redesign, we invite your input on providing feedback on Red Hat documentation via the discussion platform.