Red Hat Application Server: JOnAS User Guide | ||
---|---|---|
Prev | Chapter 3. Getting Started with WebServices and JOnAS 3.X | Next |
When you want to expose business methods, such as web services, you have to use a servlet container such as Tomcat to hold the Axis servlet that receives the SOAP messages from clients.
You have a choice of Axis configurations. You must write a .wsdd file that stores the Axis-specific configuration parameters. This file can be of two forms:
A simple WSDD that contains only information about the web services you want to expose (see the example at sample-deploy.wsdd)
A complete WSDD that contains exposed web services information and the Axis base configuration (see the example at sample-server-config.wsdd).
The first form is preferred for development purposes because you can easily change configuration values and submit them again to the Axis servlet (the Axis servlet will merge the current WEB-INF/server-config.wsdd with this new configuration file). It is usually named deploy.wsdd (its location is free).
The second form is appropriate when used in production environment where configuration changes are minor (the two forms result in the same Axis WSDD file). The file must be named server-config.wsdd and it must be located in WEB-INF directory of the servlet.
To expose a Stateless Session Bean:
Create a simple WebApp containing minimal Axis definitions, such as a WEB-INF/web.xml that declares the Axis servlet and a servlet mapping (see the example at ./ws/sample-web.xml).
Create a WSDD file (use either of the forms described in Section 3.3.1 Endpoint Creation).
Add a service with a unique name (this is used to find the appropriate service to invoke from the URL String).
Set a provider for the service:
java:EJB |
Add mandatory parameters for EJB exposition:
beanJndiName: A name used in Axis lookup. (If you add an ejb-ref or ejb-local-ref in the web-app descriptor, you can set a java:comp/env name here.)
homeInterfaceName: EJB Home interface (a fully qualified class name).
remoteInterfaceName: EJB Remote interface (a fully qualified class name).
localHomeInterfaceName: Local EJB Home interface (a fully qualified class name).
localInterfaceName: Local EJB interface (a fully qualified class name).
allowedMethods: a comma-separated list of method names that are accessible through the web service.
You must set at least local or remote interface names. If local and remote interfaces are specified, Axis chooses to use REMOTE interface, even if they are different.
See Section 3.3.3 Using an Axis WSDD Configuration file for more information.
JAX-RPC classes are just normal classes, with no particular inheritance needs, that are exposed as a web service.
Add the Axis servlet declaration in your web-app descriptor with a servlet mapping (see an example at ./ws/sample-web.xml).
Create a WSDD file (use the form you prefer).
Add a service with a unique name (this is used to find an appropriate service to invoke from the URL String).
Set a provider for the service:
java:RPC |
Add mandatory parameters for JAX-RPC classes exposition:
className: The fully qualified name of the class you want to expose as web service.
allowedMethods: A comma-separated list of method names accessible via the web service.
Creation of a web services client is heavily based on WSDL knowledge, even if it is not mandatory.
WSDL is the easiest way to create a web service client. You just need to generate all files needed to access the web service, compile them, and add them to your component archive. You can do this from the command line using the org.apache.axis.wsdl.WSDL2Java tool. For example:
jclient org.apache.axis.wsdl.WSDL2Java --output destination directory --NStoPkg namespace=package wsdl_url |
The --NStoPkg option places generated classes in a convenient package, according to the namespace of the WSDL Definition and the namespaces of the XML Schemas.
Axis provides an Ant Task (http://ws.apache.org/axis/java/ant/ant.html) for automated builds:
<taskdef name="axis-wsdl2java" classname="org.apache.axis.tools.ant.wsdl.Wsdl2javaAntTask"> <!-- classpath holds jonas.jar, webservices_axis.jar, ... --> <classpath refid="base.classpath"/> </taskdef> <axis-wsdl2java url="${ws.google.wsdl}/GoogleSearch.wsdl" output="${src.dir}"> <mapping namespace="urn:GoogleSearch" package="org.objectweb.wssample.gen.google"/> </axis-wsdl2java> |
Code sample:
import path.to.your.generated.classes.*; [...] <ServiceInterface> service = new <Service>Locator(); <PortInterface> port = service.get<PortName>(); <ObjectType> result = port.<methodName>(<arguments>); |
When the client does not have the WSDL of the service to access, you have to use Service-agnostic interfaces.
With Axis, you have to instantiate an org.apache.axis.client.Service class (http://ws.apache.org/axis/java/apiDocs/org/apache/axis/client/Service.html) implementation of javax.xml.rpc.Service (http://java.sun.com/j2ee/1.4/docs/api/javax/xml/rpc/Service.html), create a javax.xml.rpc.Call instance (http://java.sun.com/j2ee/1.4/docs/api/javax/xml/rpc/Call.html) from the Service, configure it manually, and invoke the Call.
javax.xml.rpc.Call Example
import javax.xml.rpc.Call; import javax.xml.rpc.Service; import javax.xml.namespace.QName; import javax.xml.rpc.encoding.TypeMappingRegistry; import javax.xml.rpc.encoding.TypeMapping; import org.apache.axis.encoding.ser.BeanSerializerFactory; import org.apache.axis.encoding.ser.BeanDeserializerFactory; [...] // create a Service instance (other constructor usable, see the doc) Service service = new org.apache.axis.client.Service(); // configure mappings if web service uses Complex types // first get the mapping registry instance TypeMappingRegistry tmr = service.getTypeMappingRegistry(); // create a QName representing the fully qualified name of the // XML type to serialize/deserialize (namespace+locapart pair) QName xmlType = new QName("namespace-of-complex-type", "complex-type-name"); // get a TypeMapping (default for axis is SOAP encoding TypeMapping) TypeMapping tm = tmr.getDefaultTypeMapping(); // register the XML type with a Java class by specifying // Serializer/Deserializer factories to use. tm.register(your.java.Type.class, xmlType, new BeanSerializerFactory(your.java.Type.class, xmlType), new BeanDeserializerFactory(your.java.Type.class, xmlType)); // get a Call instance from the Service // specify port to use and operation name to be invoked // see the doc for other createCall methods usage Call call = service.createCall(new QName("port-name", new QName("operation-name"))); // where is the web service? call.setTargetEndpointAddress("url-address-of-the-endpoint"); // now, invoke the web service with its parameters String result = call.invoke(new Object[] {"Hello, World!"}); |
This section covers the basic functions of the wsdd configuration files. For detailed information, refer to the Axis User Guide http://ws.apache.org/axis/java/user-guide.html and Axis Reference Guide http://ws.apache.org/axis/java/reference.html.
<service> is the tag used to declare a web service. attributes:
name: the unique name of the service
provider: the bridge used by Axis to invoke different objects: EJB, normal classes, CORBA objects, ...
provider can take the following values:
java:EJB (used to expose EJB Stateless Session Bean)
java:RPC (used to expose Simple classes)
java:MSG
style: Defines the global format of the SOAP Message.
style can take the values document or rpc.
With rpc, SOAP Messages must have as their first soap:body element, an element named as the operation to be invoked.
With document, SOAP Messages must not have a first element that has the operation name.
use: a SOAP-encoded message or a message enclosing classic XML Elements (depends on the style attributes).
use can take the values encoded or literal.
With encoded, SOAP references can be used in the SOAP Message.
With literal, no SOAP references are permitted in the SOAP Message.
![]() | Note |
---|---|
A SOAP reference is something like a pointer; in an XML SOAP Message, an Element is defined with an ID that can be referenced from somewhere else in the SOAP Message. |
The following descriptions show different style and use combinations.
The first element of the SOAP body is the operation. The operation contains elements describing the parameters, which are serialized as encoded (possibly multi-ref).
<soap:body> <operation> <arg1>...</arg1> <arg2>...</arg2> </operation> |
The first element of the SOAP body is the operation. The operation contains elements describing the parameters, which are serialized as encoded (no multi-ref).
<soap:body> <operation> <arg1>...</arg1> <arg2>...</arg2> </operation> |
Elements of the SOAP body are the names of the parameters (there is no wrapper operation...no multi-ref).
<soap:body> <arg1>...</arg1> <arg2>...</arg2> |
Special case of DOCLIT where there is only one parameter and it has the same qname as the operation. In such cases, there is no actual type with the name—the elements are treated as parameters to the operation.
<soap:body> <one-arg-same-name-as-operation> <elemofarg1>...</elemofarg1> <elemofarg2>...</elemofarg2> |
There is not an enclosing operation-name element, but the parameters are encoded using SOAP encoding. This mode is not (well?) supported by Axis.
<parameter> is the tag used to configure a service. It is basically a name-value pair.
name: parameter name (key)
value: parameter value
className: fully qualified class name of service class (only used for provider RPC & MSG)
beanJndiName: name used in Axis lookup. (If you add ejb-ref or ejb-local-ref in the web-app descriptor, you can set a java:comp/env name here.)
localHomeInterfaceName: Local EJB Home interface fully qualified class name.
localInterfaceName: Local EJB interface fully qualified class name.
homeInterfaceName: EJB Home interface fully qualified class name.
remoteInterfaceName: Remote EJB interface fully qualified class name.
allowedMethods: comma-separated list of method names accessible via the web service (for all providers).
scope: scope of the web service:
Request: create a new Object for each request
Session: keep the same Object for a given Session ID
Application: keep the same Object for the entire application run.
Other options can be specified to a service without parameter tags:
wsdlFile: specify the static wsdl file to be served when a ?WSDL request comes to the endpoint.
namespace: specify the web service namespace (override default namespace created from URL location of the service). With this tag you can handle the namespace value.
By default, a namespace will look like this: http://ws.servlets.wssample.objectweb.org (for a JAX-RPC class named org.objectweb.wssample.servlets.ws)! You can write a shorter and better namespace as you wish: urn:JaxRpcWsSample for example.
operation: used to describe the operation exposed (avoid Axis to use reflection to discover the service interface). See the Axis documentation for details.
Mappings in WSDD can be set at different levels: mappings commons for all services are directly children of the deployment tag, and mappings specific for a given web service are children of the service tag.
You can specify to sort mappings in the WSDD configuration file: beanMapping and typeMapping. beanMapping is a write shortcut for typeMapping that you can use when mapping bean types. It is used to register a Java type, with an XML QName and a serializer/deserializer pair.
<typeMapping xmlns:ns="urn:my.namespace" serializer="your.java.serializer.factory" deserializer="your.java.deserializer.factory" qname="ns:my-xml-type-name" type="java:your.java.classname" encodingStyle="encoding-namespace"/> |
![]() | Note |
---|---|
|
<beanMapping xmlns:ns="urn:my.namespace" languageSpecificType="java:your.java.classname" qname="ns:my-xml-type-name"/> |
![]() | Note |
---|---|
|
Deployment is the root Element of any Axis WSDD file. It holds commons namespace definition.
A normal deployment Element looks like this:
<deployment xmlns="http://xml.apache.org/axis/wsdd/" xmlns:java="http://xml.apache.org/axis/wsdd/providers/java"> <!-- ... services definitions here ... --> </deployment> |
The deployment of the web service in JOnAS depends of the form of your wsdd file:
If you are using full wsdd configuration files, just add it in the WEB-INF/ directory of the servlet with the name server-config.wsdd. Deployment will be done automatically by Axis when the first client will attempt to connect.
If you are using simpler wsdd configuration files, you have to deploy your web-app (or ear) into JOnAS (normal process). Then, use the Axis AdminClient tool:
jclient org.apache.axis.client.AdminClient -lhttp://<hostname>:<port>/<web-app-context>/<servlet-mapping-to-Axis-Servlet> <your-deploy>.wsdd |