Web Services with JOnAS
Starting with JOnAS 3.3, Web Services can be used within EJBs and/or
servlets/JSPs. This integration conforms to the JSR 921(Web Service for J2EE
v1.1) specification.
1. Web Services
A. Some Definitions
WSDL:
WSDL (Web Service Description Language
v1.1) is an XML-based format for specifying the interface to a web
service. The WSDL details the service's available methods and parameter
types, as well as the actual SOAP endpoint for the service. In essence, WSDL
is the "user's manual" for the web service.
SOAP:
SOAP (Simple Object Access Protocol
v1.2) is an XML-based protocol for sending requests and responses to and
from web services. It consists of three parts: an envelope defining message
contents and processing, encoding rules for application-defined data types,
and a convention for representing remote procedure calls and responses.
JAX-RPC:
JAX-RPC (Java Api for XML
RPC v1.1) is the Java API for XML-based RPC. RPC (Remote Procedure
Call) allows a client to execute procedures on other systems. The RPC
mechanism is often used in a distributed client/server model in which the
server defines a service as a collection of procedures that may be called by
remote clients. In the context of Web services, RPCs are represented by the
XML- based protocol SOAP when transmitted across systems.
In addition to defining envelope structure and encoding rules, the SOAP
specification defines a convention for representing remote procedure calls
and responses. An XML-based RPC server application can define, describe and
export a web service as an RPC-based service. WSDL (Web Service Description
Language) specifies an XML format for describing a service as a set of
endpoints operating on messages. With the JAX-RPC API, developers can
implement clients and services described by WSDL.
B. Overview of a Web Service
Strictly speaking, a Web Service is a well-defined, modular, encapsulated
function used for loosely coupled integration between applications' or
systems' components. It is based on standard technologies, such as XML, SOAP,
and UDDI.
Web Services are generally exposed and discovered through a standard
registry service. With these standards, Web Services consumers (whether they
be users or other applications) can access a broad range of information --
personal financial data, news, weather, and enterprise documents -- through
applications that reside on servers throughout the network.
Web Services use a WSDL Definition (refer to www.w3.org/TR/WSDL) as a contract
between client and server (also called endpoint). WSDL defines the types to
serialize through the network (described with XMLSchema), the messages to
send and receive (composition, parameters), the portTypes (abstract view of a
Port), the bindings (concrete description of PortType: SOAP, GET, POST, ...),
the services (set of Ports), and the Port (the port is associated with a
unique endpoint URL that defines the location of the Web Service).
A Web Service for J2EE is a component with some methods exposed and
accessible by HTTP (through servlet(s)). Web Services can be implemented as
Stateless Session Beans or as JAXRPC classes (a simple Java class, no
inheritance needed).
Figure 1. Web Services endpoints deployed within JOnAS (an external client
code can access the endpoint via AxisServlet)
Figure 2. Web Services client deployed within JOnAS (can access external Web
Services)
The servlet is used to respond to a client request and dispatch the call
to the designated instance of servant (the SSB or JAXRPC class exposed as Web
Service). It handles the deserialization of incoming SOAP messages to
transform SOAP XML into a Java Object, perform the call, and serialize the
call result (or the thrown exception) into SOAP XML before sending the
response message to the client.
2. Exposing a J2EE Component as
a Web Service
There are two types of J2EE components that can be exposed as Web Services
endpoints: StateLess Session Beans and JAX-RPC classes. Web Services'
Endpoints must not contain state information.
A new standard Deployment Descriptor has been created to describe Web
Services endpoints. This Descriptor is named "webservices.xml" and can be
used in a webapp (in WEB-INF/) or in an EjbJar (in META-INF/). This
Descriptor has its JOnAS-specific Deployment Descriptor
(jonas-webservices.xml is optional).
Refer to the webServices sample for example files.
A. JAX-RPC Endpoint
A JAX-RPC endpoint is a simple class running in the servlet container (Tomcat
or Jetty). SOAP requests are dispatched to an instance of this class and the
response is serialized and sent back to the client.
A JAX-RPC endpoint must be in a WebApp (the WAR file must contain a
"WEB-INF/webservices.xml").
B. Stateless Session Bean
Endpoint
An SSB is an EJB that will be exposed (all or some of its methods) as a Web
Service endpoint.
In the ejb-jar.xml standard descriptor, a session bean, exposed as a web
service, must now use the new service-endpoint tag. Here the developer
defines the fully-qualified interface name of the web service. Notice that no
other interfaces (home, remote, localhome, local) are needed with a session
bean exposed as web service.
Typically, an SSB must be in an EjbJar, and a "META-INF/webservices.xml" is
located in the EjbJar file.
C. Usage
In this Descriptor, the developer describes the components that will be
exposed as Web Services' endpoints; these are called the port-component(s). A
set of port-components defines a webservice-description, and a
webservice-description uses a WSDL Definition file for a complete description
of the Web Services' endpoints.
Each port-component is linked to the J2EE component that will respond to
the request (service-impl-bean with a servlet-link or ejb-link child element)
and to a WSDL port (wsdl-port defining the port's QName). A list of JAX-RPC
Handlers is provided for each port-component. The optional
service-endpoint-interface defines the methods of the J2EE components that
will be exposed (no inheritance needed).
A JAX-RPC Handler is a class used to read and/or modify the SOAP Message
before transmission and/or after reception (refer to the JAX-RPC v1.1 spec.
chap#12 "SOAP Message Handlers").The Session Handler is a simple example that
will read/write SOAP session information in the SOAP Headers. Handlers are
identified with a unique name (within the application unit), are initialized
with the init-param(s), and work on processing a list of SOAP Headers defined
with soap-headers child elements. The Handler is run as the SOAP actor(s)
defined in the list of soap-roles.
A webservice-description defines a set of port-components, a WSDL
Definition (describing the Web Service) and a mapping file (WSDL-2-Java
bindings). The wsdl-file element and the jaxrpc-mapping-file element must
specify a path to a file contained in the module unit (i.e., the war/jar
file). Note that a URL cannot be set here. The specification also requires
that the WSDLs be placed in a wsdl subdirectory (i.e., WEB-INF/wsdl or
META-INF/wsdl); there is no such requirement for the jaxrpc-mapping-file. All
the ports defined in the WSDL must be linked to a port-component. This is
essential because the WSDL is a contract between the endpoint and a client
(if the client uses a port not implemented/linked with a component, the
client call will systematically fail).
As for all other Deployment Descriptors, a standard
XML Schema is used to constrain the XML.
D. Simple Example (expose a JAX-RPC Endpoint) of webservices.xml
<?xml version="1.0"?>
<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">
<display-name>Simple Web Service Endpoint
DeploymentDesc</display-name>
<webservice-description>
<!-- name must be unique in an Application unit
-->
<!--
Should not contain spaces !!! -->
<webservice-description-name>
SimpleWebServiceEndpoint
</webservice-description-name>
<!-- Link to the WSDL file describing the
endpoint -->
<wsdl-file>WEB-INF/wsdl/warendpoint.wsdl</wsdl-file>
<!-- Link to the mapping file describing
binding between WSDL and Java -->
<jaxrpc-mapping-file>WEB-INF/warEndpointMapping.xml</jaxrpc-mapping-file>
<!-- The list of endpoints -->
<port-component>
<!-- Unique name of
the port-component -->
<!-- Should not contain spaces !!!
-->
<port-component-name>WebappPortComp1</port-component-name>
<!-- The QName of the WSDL Port the
J2EE port-component is linked to -->
<!-- Must Refers to a port in
associated WSDL document -->
<wsdl-port
xmlns:ns=" http://wsendpoint.servlets.ws.objectweb.org ">
ns:wsendpoint1
</wsdl-port>
<!-- The endpoint
interface defining methods exposed -->
<!-- for the
endpoint
-->
<service-endpoint-interface>
org.objectweb.ws.servlets.wsendpoint.WSEndpointSei
</service-endpoint-interface>
<!-- Link to the J2EE
component (servlet/EJB) -->
<!-- implementing methods of the
SEI
-->
<service-impl-bean>
<!-- name of the
servlet defining the JAX-RPC endpoint -->
<!-- can
be ejb-link if SSB is used (only in EjbJar!)
-->
<servlet-link>WSEndpoint</servlet-link>
</service-impl-bean>
<!-- The list of
optional JAX-RPC Handlers -->
<handler>
<handler-name>MyHandler</handler-name>
<handler-class>org.objectweb.ws.handlers.SimpleHandler</handler-class>
<!-- A
list of init-param for Handler configuration -->
<init-param>
<param-name>param1</param-name>
<param-value>value1</param-value>
</init-param>
<init-param>
<param-name>param2</param-name>
<param-value>value2</param-value>
</init-param>
</handler>
</port-component>
</webservice-description>
</webservices> |
E. The optional jonas-webservices.xml
The jonas-webservices.xml
file is an optional deployment descriptor. This descriptor
is used by WsGen to set some specifics for the generated webapp that is in charge of
the SOAP request dispatching. Its role is to allow for the specifications of the
webapp's name, context root, security settings and endpoint URL customization.
Some parameters are only used if the web service is implemented by a Session Bean:
jonas:jonas-webservices/jonas:war
: specify the filename of the webapp
frontend generated for this EjbJar
jonas:jonas-webservices/jonas:context-root
: specify the context root of the webapp
frontend generated for this EjbJar
War Name: Specifies the name of the generated
WAR. Setting the <war> element is optional; if it is not specified, then the
default naming convention is used to retrieve the WAR name from the ejbjar's name.
Default Naming:
<ejbjar-name>.jar will have an
<ejbjar-name>.war WebApp.
Context Root: Specifies the context root of the
generated WAR. Setting the <context-root> element is optional; if it is not specified,
then the default naming convention is used and the context root will be the same as the WAR's name.
Default Naming:
<webapp-name>.war will have a
<webapp-name> context root.
Endpoint URL Customization: Specifies the endpoint URL
of a given jonas-port-component. Setting the <endpoint-url> element is optional; if it is not specified,
then the default naming convention is used and the URL will look like /<context-root>/<port-component-name>/<wsdl:port-name>.
Security: The security settings specify which
security settings, if any, the generated webapp should use. Setting up security within this
file is very similar to how security would be set up in a regular web.xml.
NOTE:
When using the <endpoint-security-constraint>,
<endpoint-login-config>, or
<endpoint-security-role> elements, the j2ee namespace
must be included in the jonas-webservices element (that is,
xmlsn:j2ee="http://java.sun.com/xml/j2ee"
), and the namespace
for all elements within these tags (that is, the 'j2ee
'
in the example below) must be specified.
Security Constraint:
the <endpoint-security-constraint> specifies the <security-constraint>
in the web.xml
of the generated webapp.
Login Config: the
<endpoint-login-config> specifies
the <login-config> in the web.xml of the generated webapp.
Security Role: the
<endpoint-security-role> specifies
the <security-role> in the web.xml
of the generated webapp.
Realm: the
<endpoint-realm> specifies the security
realm for the generated webapp.
Realm Name: the
<endpoint-realm-name> specifies the
name of the security realm for the generated webapp.
Example:
<?xml version="1.0"?>
<jonas-webservices xmlns="http://www.objectweb.org/jonas/ns"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:j2ee:"http://java.sun.com/xml/ns/j2ee"
xsi:schemaLocation="http://www.objectweb.org/jonas/ns http://www.objectweb.org/jonas/ns/jonas_j2ee_web_services_4_5.xsd">
<!-- the name of the webapp in the EAR -->
<!-- (it is the same as the one in application.xml) -->
<war>dispatchingWebApp.war</war>
<!-- the context root the webapp should use -->
<context-root>endpoint</context-root>
<jonas-port-component>
<port-component-name>ssbEndpoint</port-component-name>
<!-- We can specify with endpoint-uri the URL we want to have for the given port. -->
<!-- Will be something like : http://<host>:<port>/<context-root>/services1/webservice -->
<endpoint-uri>/services1/webservice</endpoint-uri>
</jonas-port-component>
<!-- everthing in this element will appear in the security-constraint -->
<!-- element in the web.xml of the generated webapp -->
<endpoint-security-constraint>
<j2ee:web-resouce-collection>
<j2ee:web-resource-name>Stateless Session Bean Endpoint</j2ee:web-resource-name>
<j2ee:url-pattern>/*</j2ee:url-pattern>
</j2ee:web-resource-collection>
<j2ee:auth-constraint>
<j2ee:role-name>admin</j2ee:role-name>
</j2ee:auth-constraint>
</endpoint-security-constraint>
<!-- everything in this element will appear in the login-config -->
<!-- element in the web.xml of the generated webapp -->
<endpoint-login-config>
<j2ee:auth-method>BASIC</j2ee:auth-method>
<j2ee:realm-name>Endpoint Authentication Area</j2ee:realm-name>
</endpoint-login-config>
<!-- everything in this element will appear in the security-role -->
<!-- element in the web.xml of the generated webapp -->
<endpoint-security-role>
<j2ee:role-name>admin</j2ee:role-name>
</endpoint-security-role>
<!-- the realm the generated webapp should use -->
<endpoint-realm>memrlm_1</endpoint-realm>
<!-- the name of the realm the generated webapp should use -->
<endpoint-realm-name>Endpoint Authentication Area</endpoint-realm-name>
</jonas-webservices>
|
F. Changes to jonas-web.xml
JOnAS allows the developer to fully configure an application by setting the
hostname, the context-root, and the port used to access the Web Services.
This is done in the jonas-web.xml of the dispatching WebApp.
host: configure the hostname to use
in URL (must be an available web container host).
port: configure the port number to
use in URL (must be an available HTTP/HTTPS connector port number).
When these values are not set, JOnAS will attempt to determine the default
values for host and port.
Limitations:
- The host can only be determined when only one host is set for the web
container.
- The port can only be determined when only one connector is used by the web
container.
3. The client of a Web
Service
An EJB or a servlet that wants to use a Web Service (as client) must declare
a dependency on the Web Service with a service-ref element (same principle as for
all *-ref elements).
A. The service-ref element
The service-ref element declares reference to a Web Service used by a J2EE
component in the web, EJB and Client application Deployment Descriptor.
The component uses a logical name called a service-ref-name to lookup the
service instance. Thus, any component that performs a lookup on a Web Service
must declare a dependency (the service-ref element) in the standard
deployment descriptor (web.xml, ejb-jar.xml or application-client.xml).
Example of service-ref:
<service-ref>
<!-- (Optional) A Web services
description that can be used
in administration
tool. -->
<description>Sample WebService
Client</description>
<!-- (Optional) The WebService
reference name -->
<display-name>WebService Client
1</display-name>
<!-- (Optional) An icon for this
WebService. -->
<icon> <!-- ... --> </icon>
<!-- The logical name for the reference
that is used in the client source
code. It is recommended, but not
required that the name begin with
'services/' -->
<service-ref-name>services/myService</service-ref-name>
<!-- Defines the class name of the
JAX-RPC Service interface that
the client depends on. In most
cases, the value will be:
javax.xml.rpc.Service but a
generated specific Service Interface
class may be specified (requires
WSDL knowledge and thus
the wsdl-file element).
-->
<service-interface>javax.xml.rpc.Service</service-interface>
<!-- (Optional) Contains the location
(relative to the root of
the module) of the web service WSDL
description.
- needs to be in the wsdl
directory.
- required if generated interface
and sei are declared. -->
<wsdl-file>WEB-INF/wsdl/stockQuote.wsdl</wsdl-file>
<!--
(Optional) A file specifying the
correlation of the WSDL definition
to the interfaces (Service Endpoint
Interface, Service Interface).
- required if generated
interface and sei (Service Endpoint
Interface) are
declared. -->
<jaxrpc-mapping-file>WEB-INF/myMapping.xml</jaxrpc-mapping-file>
<!-- (Optional) Declares the specific
WSDL service element that is being
referred to. It is not specified if
no wsdl-file is declared or if
WSDL contains only 1 service
element. A service-qname is composed
of a namespaceURI and a localpart.
It must be defined if more than 1
service is declared in
the WSDL. -->
<service-qname
xmlns:ns=" http://beans.ws.objectweb.org ">
ns:MyWSDLService
</service-qname>
<!-- Declares a client dependency on
the container for resolving a Service
Endpoint Interface to a WSDL port.
It optionally associates the
Service Endpoint Interface with a
particular port-component. -->
<port-component-ref>
<service-endpoint-interface>
org.objectweb.ws.beans.ssbendpoint.MyService
</service-endpoint-interface>
<!-- Defines a link to a port component
declared in another unit
of the
application -->
<!-- link is only used when an application module wants to access
a -->
<!-- web service colocated in the same application
unit
-->
<port-component-link>ejb_module.jar#PortComponentName </port-component-link>
</port-component-ref>
<!--A list of Handlers to use for this
service-ref -->
<handler>
<!-- Must be unique
within the module. -->
<handler-name>MyHandler</handler-name>
<handler-class>org.objectweb.ws.handlers.myHandler</handler-class>
<!-- A list of init-params (couple
name/value) for Handler
initialization -->
<init-param>
<param-name>param_1</param-name>
<param-value>value_1</param-value>
</init-param>
<!-- A list of QNames specifying the
SOAP Headers the handler
will work on. Namespace and
locapart values must be found
inside the WSDL. -->
<soap-header
xmlns:ns=" http://ws.objectweb.org ">
ns:MyWSDLHeader
</soap-header>
<!-- A list of SOAP actor
definitions that the Handler will play
as a role. A soap-role is a
namespace URI. -->
<soap-role>http://actor.soap.objectweb.org</soap-role>
<!-- A list
of port-name elements that defines the WSDL
port-name that
a handler should be
associated with. If no port-name is specified,
the handler is assumed to
be associated with all ports of the
service-ref.
-->
<port-name>myWSDLPort</port-name>
</handler>
</service-ref> |
B. The jonas-service-ref element
A jonas-service-ref must be specified for each service-ref declared in the
standard Deployment Descriptor. The jonas-service-ref adds JOnAS-specific
(and Web Service engine-specific) information to service-ref elements.
Example of jonas-service-ref:
<jonas-service-ref>
<!-- Define the service-ref
contained in the component
deployment descriptor
(web.xml, ejb-jar.xml, application-client.xml).
used as a key to associate a
service-ref to its correspondent
jonas-service-ref-->
<service-ref-name>services/myService</service-ref-name>
<!-- Define the physical
name of the resource. -->
<jndi-name>webservice_1</jndi-name>
<!-- A list of init-param used for specific
configuration of
the service -->
<jonas-init-param>
<param-name>param</param-name>
<param-value>name</param-value>
</jonas-init-param>
</jonas-service-ref> |
4. WsGen
WsGen is a new JOnAS tool that works in the same way as GenIC. It takes
archive files (EJB-JAR, WAR, JAR client, EAR) and generates all the necessay
components related to web services:
- Creates vendor-specific web-services deployment files for the server
side and, when needed, the client side (Axis will use its own wsdd
format).
- Creates a WebApp for each EJB-JAR exposing web services.
- Generates and compiles client side artifacts (Services and Port
Bindings implementations classes).
For example, to provide an EJB-exposing method as a web service, a
developer creates a webservices.xml file packaged in EjbJar's
META-INF directory. WsGen automatically creates a configured webapp (using an
Axis servlet) and wraps it (ejbjar + webapp) in an EAR file.
With a JaxRpc class, WsGen adds a servlet (an Axis servlet) inside the
existing web deployment descriptor and generates an Axis-specific
configuration file.
When using service-ref (from ejbjars, web applications, or clients), WsGen
automatically generates a Stub from WSDL (if a generated service interface
name is provided).
Usage
WsGen is used typically from an ant build file. Simply add this taskdef
under the ejbjar taskdef:
<taskdef name="wsgen" classname="org.objectweb.jonas.ant.WsGenTask"
classpath="${jonas.root}/lib/common/ow_jonas_ant.jar" />
<wsgen srcdir="${temp.dir}"
destdir="${dist.dir}"
verbose="false"
debug="false">
<include name="webapps/wswarsample.war"/>
</wsgen>
See the $JONAS_ROOT/examples/webservices samples for complete
build scripts.
Note that the ejbjar/webapp/client archive must include WSDL,
jax-rpc-mappings used in service-ref, or webservices.xml. When these
files are used from a service-ref, they are added into the generic ejb-jar
with the ejbjar ant task of JOnAS; you must ensure that they have been placed
inside the srcdir given to the ejbjar task (otherwise, the ejbjar task cannot
find them and will produce an error).
This task is a directory-based
task and, as such, forms an implicit Fileset. This
defines which files, relative to the srcdir, will be processed. The
wsgen task supports all the attributes of Fileset to refine the set of files
to be included in the implicit fileset.
Attribute |
Description |
Required |
srcdir |
Directory where file archive (EjbJar, War, Client, Ear) is
located |
Yes |
destdir |
Directory where generated files will be placed |
No |
verbose |
Verbose mode (Defaults to false) |
No |
debug |
Debug mode (Defaults to false) |
No |
javacopts |
List of options given to the java compiler |
No |
jonasroot |
Directory where JOnAS is installed |
No |
jonasbase |
Directory where JOnAS configuration is stored |
No |
Wsgen is also usable from the command line with WsGen script (available on
*nix and Windows).