More Books
JBoss 4.0 The Official Guide
JBoss® 4.0 The Official Guide
Table of Contents
Copyright
About the Authors
We Want to Hear from You!
Introduction
What This Book Covers
About JBoss
About Open Source
About Professional Open Source
What's New in JBoss 4.0
Chapter 1.  Installing and Building the JBoss Server
Getting the Binary Files
Installing the Binary Package
Basic Installation Testing
Booting from a Network Server
Building the Server from Source Code
Chapter 2.  The JBoss JMX Microkernel
JMX
The JBoss JMX Implementation Architecture
Connecting to the JMX Server
Using JMX as a Microkernel
The JBoss Deployer Architecture
Exposing MBean Events via SNMP
Remote Access to Services, Detached Invokers
Chapter 3.  Naming on JBoss
An Overview of JNDI
The JBossNS Architecture
Chapter 4.  Transactions on JBoss
Transaction and JTA Overview
JBoss Transaction Internals
Chapter 5.  EJBs on JBoss
The EJB Client-Side View
The EJB Server-Side View
The EJB Container
Entity Bean Locking and Deadlock Detection
Chapter 6.  Messaging on JBoss
JMS Examples
JBossMQ Overview
JBossMQ Configuration and MBeans
Specifying the MDB JMS Provider
Chapter 7.  Connectors on JBoss
JCA Overview
An Overview of the JBossCX Architecture
Configuring JDBC Datasources
Configuring Generic JCA Adaptors
Chapter 8.  Security on JBoss
J2EE Declarative Security Overview
An Introduction to JAAS
The JBoss Security Model
The JBossSX Architecture
The Secure Remote Password (SRP) Protocol
Running JBoss with a Java 2 Security Manager
Using SSL with JBoss and JSSE
Configuring JBoss for Use Behind a Firewall
Securing the JBoss Server
Chapter 9.  Web Applications
The Tomcat Service
The Tomcat server.xml File
The Engine Element
The Host Element
Using SSL with the JBoss/Tomcat Bundle
Setting the Context Root of a Web Application
Setting Up Virtual Hosts
Serving Static Content
Using Apache with Tomcat
Using Clustering
Integrating Third-Party Servlet Containers
Chapter 10.  MBean Services Miscellany
System Properties Management
Property Editor Management
Services Binding Management
Scheduling Tasks
The Log4j Service MBean
RMI Dynamic Class Loading
Chapter 11.  The CMP Engine
Example Code
The jbosscmp-jdbc Structure
Entity Beans
CMP Fields
Container-Managed Relationships
Declaring Queries
Optimized Loading
The Loading Process
Transactions
Optimistic Locking
Entity Commands and Primary Key Generation
JBoss Global Defaults
Datasource Customization
Chapter 12.  Web Services
JAX-RPC Service Endpoints
Enterprise JavaBean Endpoints
Web Services ClientsA JAX-RPC Client
Service References
Chapter 13.  Hibernate
The Hibernate MBean
Hibernate Archives
Using Hibernate Objects
Using a HAR File Inside an EAR File
The HAR Deployer
Chapter 14.  Aspect-Oriented Programming (AOP) Support
JBoss AOP: EJB-Style Services for Plain Java Objects
Why AOP?
Basic Concepts of AOP
Building JBoss AOP Applications
The JBoss AOP Deployer
Packaging and Deploying AOP Applications to JBoss
Appendix A.  The GNU Lesser General Public License (LGPL)
GNU General Public License
Appendix B.  Example Installation
Index
SYMBOL
A
B
C
D
E
F
G
H
I
J
K
L
M
N
O
P
Q
R
S
T
U
V
W
X

JAX-RPC Service Endpoints

JAX-RPC service endpoints (JSE) provide web services from the web tier. They take the form of simple Java objects that masquerade as servlets. A trivial hello web service implementation class shows how simple they are:

package org.jboss.chap12.hello;

public class HelloServlet
{

    public String hello(String name)
    {

        return "Hello " + name + "!";
    }
}

There is nothing remarkable about HelloServlet. 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 exposed as a web service, and it does nothing but respond with a friendly greeting to the person passed in.

That is your web service implementation. In addition to this, you need a service endpoint class that defines the interface of the web service. That is shown here as the Hello interface:

package org.jboss.chap12.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 method must throw RemoteException. Beyond this, it is a simple expression of the interface to the web service. This is all the code you need to write to expose a J2EE web service. Deploying it, however, does require a few additional deployment descriptors.

Although a JSE doesn't bear any direct resemblance to a servlet, it is nonetheless deployed as a servlet in the web.xml file. You need to declare the web service implementation class as a servlet and provide a servlet mapping that responds 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/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>HelloWorldServlet</servlet-name>
        <servlet-class>org.jboss.chap12.hello.HelloServlet</servlet-class>
    </servlet>
    <servlet-mapping>
        <servlet-name>HelloWorldServlet</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 is 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. But before discussing that, you need two additional configuration files, a WSDL file and a JAX-RPC mapping file. Both of these files can be generated using the wscompile tool that ships as part of the Java Web Services Developer Pack (WSDP).

wscompile -classpath <classpath> -gen:server -f:rpcliteral -mapping mapping.xml config.xml

This generates a WSDL file and a JAX-RPC mapping file based on the supplied config.xml and the corresponding classes found on the class path. The config.xml file for the hello web service is shown below:

<?xml version="1.0" encoding="UTF-8"?>

<configuration xmlns="http://java.sun.com/xml/ns/jax-rpc/ri/config">
    <service name="HelloService"
             targetNamespace="http://hello.chap12.jboss.org/"
             typeNamespace="http://hello.chap12.jboss.org/types"
             packageName="org.jboss.chap12.hello">
        <interface name="org.jboss.chap12.hello.Hello"/>
    </service>
</configuration>

The service element defines the interface your web service provides. The following attributes are required:

  • name This is the name of the web service.

  • targetNamespace Web services require namespaces just like Java classes do. It's a common practice to use a URL namespace that corresponds to the Java namespace given.

  • typeNamespace This specifies the namespace to use for custom types.

  • packageName This is the base package name your web services' classes live under.

Additionally, you need an interface element that tells wscompile what the Java interface for the web service is. This interface declares the operations the web service provides.

The WSDL file wscompile generated for our config.xml file is shown below. Note that the SOAP address isn't provided in the WSDL file. JBoss inserts the correct URL for the WSDL when it deploys the web service.

<?xml version="1.0" encoding="UTF-8"?>
<definitions name="HelloService"
targetNamespace="http://hello.chap12.jboss.org/"
xmlns:tns="http://hello.chap12.jboss.org/"
xmlns="http://schemas.xmlsoap.org/wsdl/"
xmlns:xsd="http://www.w3.org/2001/XMLSchema"
    xmlns:soap="http://schemas.xmlsoap.org/wsdl/soap/">
    <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 transport="http://schemas.xmlsoap.org/soap/http" style="rpc"/>
        <operation name="hello">
            <soap:operation soapAction=""/>
            <input>
               <soap:body use="literal" namespace="http://hello.chap12.jboss.org/"/>
            </input>
            <output>
                <soap:body use="literal" namespace="http://hello.chap12.jboss.org/"/>
            </output>
        </operation>
    </binding>
    <service name="HelloService">
        <port name="HelloPort" binding="tns:HelloBinding">
            <soap:address location="REPLACE_WITH_ACTUAL_URL"/>
        </port>
    </service>
</definitions>

You 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/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_jaxrpc_mapping_1_1.xsd">
    <package-mapping>
        <package-type>org.jboss.chap12.hello</package-type>
        <namespaceURI>http://hello.chap12.jboss.org/types</namespaceURI>
    </package-mapping>
    <package-mapping>
        <package-type>org.jboss.chap12.hello</package-type>
        <namespaceURI>http://hello.chap12.jboss.org/</namespaceURI>
    </package-mapping>
    <service-interface-mapping>
        <service-interface>org.jboss.chap12.hello.HelloService</service-interface>
        <wsdl-service-name xmlns:serviceNS="http://hello.chap12.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.chap12.hello.Hello</service-endpoint-interface>
        <wsdl-port-type xmlns:portTypeNS="http://hello.chap12.jboss.org/">
            portTypeNS:Hello
        </wsdl-port-type>
        <wsdl-binding xmlns:bindingNS="http://hello.chap12.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.chap12.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.chap12.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>

After the extra files are generated, you need to bundle them up in a webservices.xml file. This file links to the WSDL file using the wsdl-file element and links 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 declared in the web.xml file.


<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>HelloService</webservice-description-name>
        <wsdl-file>WEB-INF/wsdl/HelloService.wsdl</wsdl-file>
        <jaxrpc-mapping-file>WEB-INF/mapping.xml</jaxrpc-mapping-file>
        <port-component>
            <port-component-name>Hello</port-component-name>
            <wsdl-port>HelloPort</wsdl-port>
            <service-endpoint-interface>org.jboss.chap12.hello.Hello<
/service-endpoint-interface>
            <service-impl-bean>
                <servlet-link>HelloWorldServlet</servlet-link>
            </service-impl-bean>
        </port-component>
    </webservice-description>
</webservices>

With these completed, you can deploy the WAR file containing the web service. All the deployment descriptors go in the WEB-INF directory, as shown in Figure 12.1. It's important to note that the WSDL file is required to be in the wsdl subdirectory.

Figure 12.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=chap12 -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!

Note the URL where JBoss publishes the WSDL file. Your web application name is hello-servlet and you mapped the servlet to /Hello in the web.xml file, so the web service is mapped to /hello-servlet/Hello. The ?wsdl query returns the WSDL file.

If you aren't sure what the URL of the WSDL file is, JBoss provides a way to list the web services available on the system at /ws4ee/services. Figure 12.2 shows a view of the services list.

Figure 12.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.