Chapter 12.  Use WS-Addressing with a SOAP web service

In a moderately complex system, a receiver of a message must know information about the sender. With an asynchronous request-response implementation model, the receiver must know at least the sender’s address to send back responses that are disconnected from the request channel that was previously used by the Web services client to issue the request.

The purpose of the WS-Addressing specification is to provide an interoperable way of communicating between senders and receivers by providing a transport-neutral mechanism to address Web services and messages. The WS-Addressing specification defines XML elements to identify the web services endpoints and to secure end-to-end endpoint identification in messages. This specification enables messaging systems to support message transmission through networks that include processing nodes, such as endpoint managers, firewalls, and gateways.

WS-Addressing is a World Wide Web Consortium (W3C) specification that aid interoperability between web services by defining a standard way to address web services and to provide addressing information in messages. The WS-Addressing specification introduces two primary concepts:

For JAX-WS applications, you can enable WS-Addressing support in several ways, such as configuring policy sets or using annotations in code. You can now use JAX-WS 2.1 annotations and feature classes to do the following tasks:

The following additional features are related to the JAX-WS enhancements:

12.1.  Use Addressing on the service

12.1.1.  Use @Addressing annotation with a web service

javax.xml.ws.soap.Addressing


package javax.xml.ws.soap;
@Target({ElementType.TYPE, ElementType.METHOD, ElementType.FIELD})
@Retention(RetentionPolicy.RUNTIME)
@Documented
@WebServiceFeatureAnnotation(id=AddressingFeature.ID,bean=AddressingFeature.class)
public @interface Addressing {
    /**
     * Specifies if this feature is enabled or disabled. If enabled, it means
     * the endpoint supports WS-Addressing but does not require its use.
     * Corresponding Addressing Assertion must be generated in the generated WSDL.
     */
    boolean enabled() default true;

    /**
     * If addressing is enabled, this property determines whether the endpoint
     * requires WS-Addressing. If required is true, the endpoint requires
     * WS-Addressing and WS-Addressing headers MUST
     * be present on incoming messages. A corresponding Addressing Assertion
     * must be generated in the WSDL.
     */
    boolean required() default false;

    /**
     * If addressing is enabled, this property determines whether endpoint
     * requires the use of anonymous responses, or non-anonymous responses,
     * or all.
     *
     * Responses.ALL supports all response types and this is the default value.
     *
     * Responses.ANONYMOUS requires the use of only anonymous
     * responses. It will result into wsam:AnonymousResponses nested assertion
     * as specified in AnonymousResponses Assertion in the generated WSDL.
     *
     * Responses.NON_ANONYMOUS requires the use of only non-anonymous
     * responses. It will result into wsam:NonAnonymousResponses nested assertion
     * as specified in NonAnonymousResponses Assertion in the generated WSDL.
     *
     * @since JAX-WS 2.2
     */
    Responses responses() default Responses.ALL;
}

						

This annotation represents the use of WS-Addressing with either the SOAP 1.1/HTTP or SOAP 1.2/HTTP binding. Using this annotation with any other binding is undefined.

This annotation MUST only be used in conjunction with the WebService, WebServiceProvider, and WebServiceRef annotations. When used with a javax.jws.WebService annotation, this annotation MUST only be used on the service endpoint implementation class. When used with a WebServiceRef annotation, this annotation MUST only be used when a proxy instance is created. The injected SEI proxy, and endpoint MUST honor the values of the @Addressing annotation.

The required property can be used to specify if WS-Addressing headers MUST be present on incoming messages. By default the required property is false.

This annotation's behaviour is defined by the corresponding feature AddressingFeature.

The Addressing specification is wrapped into the JAX-WS 2.1 specification, so any vendor implementing JAX-WS 2.1 will make the Addressing feature available.

In your Java web service class, use the javax.xml.ws.soap.Addressing annotation along with the javax.xml.ws.Action annotation:

import javax.xml.ws.Action;

import javax.xml.ws.soap.Addressing;

/**
 * @author Mikalai Zaikin
 */
@WebService()
@Addressing(enabled=true, required=true)
public class CalculatorWS {
						

This enables Addressing generally in your service; you must then apply the @Action annotation to your operations, like this:

    /**
     * Web service operation
     */
    @WebMethod(operationName = "add")
    @Action(
        input="http://addnumbers.org/input",
        output="http://addnumbers.org/output")
    public int add(@WebParam(name = "i") int i, @WebParam(name = "j") int j) {
        return i + j;
    }
    					

Let's unpack the code a little bit to see how this works. Adding addressing to your simple Calculator service as you did earlier makes the following changes to the resulting WSDL:


<portType name="CalculatorWS">
	<operation name="add">
		<input wsaw:Action="http://addnumbers.org/input" message="tns:add"/>
		<output wsaw:Action="http://addnumbers.org/output" message="tns:addResponse"/>
	</operation>
</portType>

...

<binding name="CalculatorWSPortBinding" type="tns:CalculatorWS">
	<wsaw:UsingAddressing/>
	...
</binding>

						

First, the annotation's attributes map clearly to the input and output of the operation they modify. The values specified in the Java file are added to the addressing Action attribute. Then, in the binding, the WSDL now indicates that it is set up for WS-Addressing so that clients are free to use Addressing if they would like to, via the <wsaw:UsingAddressing/> element. This element also has a required attribute that indicates if you want the service to force clients to use addressing. By default, it is set to false. But you could just write <wsaw:UsingAddressing required="true"/> to force clients to use Addressing, if you had started from WSDL. To generate that from Java, use the following code:

@Addressing(required=true)
						

To make sure that your endpoint and its client are portable, the endpoint must use the @Action annotation to indicate their WS-Addressing actions, and it should use the @FaultAction annotation for creating WS-Addressing-compliant SOAP faults.

12.1.2.  Use wsam:Addressing policy in WSDL

If the endpoint enables Addressing, that can be indicated in the generated WSDL as per the Addressing 1.0 - Metadata.

Endpoint's use of addressing, if any, MUST be indicated in the wsdl:binding or wsdl:port sections of the WSDL 1.1 as per WS-Addressing 1.0 - Metadata.

Example 1: Possible Policy assertion for @Addressing in the generated WSDL:

@WebService()
@Addressing
public class CalculatorWS {
						


<wsam:Addressing wsp:Optional="true">
	<wsp:Policy/>
</wsam:Addressing>

						

Example 2: Possible Policy assertion for @Addressing(required=true) in the generated WSDL:

@WebService()
@Addressing(required=true)
public class CalculatorWS {
						


<wsam:Addressing>
	<wsp:Policy/>
</wsam:Addressing>

						

Example 3: Possible Policy assertion for @Addressing(responses=Responses.NON_ANONYMOUS) in the generated WSDL:

@WebService()
@Addressing(responses=Responses.NON_ANONYMOUS)
public class CalculatorWS {
						


<wsam:Addressing wsp:Optional="true">
	<wsp:Policy>
		<wsam:NonAnonymousResponses/>
	</wsp:Policy>
</wsam:Addressing>

						

12.1.3.  Use Addressing in the deployment descriptors

Deployment descriptors are standard text files, formatted using XML and packaged in a web services application. You can optionally use the webservices.xml deployment descriptor to augment or override application metadata specified in annotations within Java API for XML-Based Web Services (JAX-WS) Web services.

For JAX-WS web services, the use of the webservices.xml deployment descriptor is optional because you can use annotations to specify all of the information that is contained within the deployment descriptor file. You can use the deployment descriptor file to augment or override existing JAX-WS annotations. Any information that you define in the webservices.xml deployment descriptor overrides any corresponding information that is specified by annotations.

The deployment descriptor must be named "META-INF/webservices.xml" in the web services' jar file.

http://java.sun.com/xml/ns/javaee/javaee_web_services_1_3.xsd XSD:


<xsd:element name="addressing"
             type="javaee:addressingType"
             minOccurs="0"
             maxOccurs="1">
    <xsd:annotation>
        <xsd:documentation>
            This specifies the WS-Addressing requirements for a JAX-WS
            web service. It corresponds to javax.xml.ws.soap.Addressing
            annotation or its feature javax.xml.ws.soap.AddressingFeature.

            See the addressingType for more information.
        </xsd:documentation>
    </xsd:annotation>
</xsd:element>


						

12.1.4.  Use AddressingFeature with javax.xml.ws.Endpoint API.

JAX-WS 2.1 introduces the notion of features. A feature is associated with a particular functionality or behavior. Some features may only have meaning when used with certain bindings while other features may be generally useful. These features can be used while creating service and proxy instances. JAX-WS 2.1 introduces three standard features for creating proxy instances, AddressingFeature, MTOMFeature and RespectBindingFeature as well as the base WebServiceFeature class.

The AddressingFeature is used to control the use of WS-Addressing by JAX-WS. This feature MUST be supported with the SOAP 1.1/HTTP or SOAP 1.2/HTTP bindings. Using this feature with any other binding is undefined. This feature corresponds to the @Addressing annotation.

Enabling this feature on the server will result in the runtime being capable of consuming and responding to WS-Addressing headers.

Enabling this feature on the client will cause the JAX-WS runtime to include WS-Addressing headers in SOAP messages as specified by WS-Addressing.

Disabling this feature will prevent a JAX-WS runtime from processing or adding WS-Addressing headers from/to SOAP messages even if the associated WSDL specifies otherwise. This may be necessary if a client or endpoint needs to implement Addressing themselves. For example, a client that desires to use non-anonymous ReplyTo can do so by disabling the AddressingFeature and by using Dispatch<Source> with Message mode.

The AddressingFeature's required property can be configured to control whether all incoming messages MUST contain Addressing headers.

The AddressingFeature's responses property can be configured to control whether the endpoint requires the use of anonymous, non-anonymous and all responses.

This feature is automatically enabled if the WSDL indicates the use of addressing as per the WS-Addressing 1.0 - Metadata. Developers may choose to prevent this from happening by explicitly disabling the AddressingFeature.

To write a portable endpoint and its corresponding client with this version of JAX-WS, an endpoint MUST explicitly specify what WS-Addressing Actions are to be used via the Action and FaultAction annotations. The client MUST explicitly enable addresssing via this AddressingFeature, and for each invocation, the client MUST explicitly set the BindingProvider.SOAPACTION_URI_PROPERTY. After the W3C WG on WS-Addressing has specified how the use of WS-Addressing is specified in the WSDL, and what the default value must be for Action headers, a future version of JAX-WS will remove these requirements.

The following describes the effects of this feature with respect to be enabled or disabled:

  • ENABLED

    In this Mode, WS-Addressing will be enabled. At runtime, WS-Addressing headers MUST be consumed by the receiver and produced by the sender even if the WSDL declares otherwise. The mustUnderstand="0" attribute MUST be used on the WS-Addressing headers.

  • DISABLED

    In this Mode, WS-Addressing will be disabled even if an associated WSDL specifies otherwise. At runtime, WS-Addressing headers MUST NOT be used. WS-Addressing may be explicitly disabled to prevent a JAX-WS implementation from consuming and producing WS-Addressing headers. If an application has implemented WS-Addressing itself, it MUST explicitly disable this feature. Not doing so may break compatibility with future versions of JAX-WS.

The required property can be used to specify if WS-Addressing headers MUST be present on incoming messages. This property only has meaning when used on the endpoint and has no affect when used on the client. By default the required property is false.

Constructor summary:

AddressingFeature()

AddressingFeature(boolean enabled)

AddressingFeature(boolean enabled, boolean required)
			          

The Endpoint class can be used to create and publish web service endpoints.

An endpoint consists of an object that acts as the web service implementation (called here implementor) plus some configuration information, e.g. a Binding. Implementor and binding are set when the endpoint is created and cannot be modified later. Their values can be retrieved using the getImplementor and getBinding methods respectively. Other configuration information may be set at any time after the creation of an Endpoint but before its publication.

Endpoints can be created using the following static methods on Endpoint:

  • create(Object implementor)

    Creates and returns an Endpoint for the specified implementor. If the implementor specifies a binding using the javax.xml.ws.BindingType annotation it MUST be used else a default binding of SOAP 1.1 / HTTP binding MUST be used.

  • create(Object implementor, WebServiceFeature ... features)

    Same as the above create() method. The created Endpoint is configured with the web service features. These features override the corresponding features that are specified in WSDL, if present.

  • create(String bindingID, Object implementor)

    Creates and returns an Endpoint for the specified binding and implementor. If the bindingID is null and no binding information is specified via the javax.xml.ws.BindingType annotation then a default SOAP 1.1 / HTTP binding MUST be used.

  • create(String bindingID, Object implementor, WebServiceFeature ... features)

    Same as the above create() method. The created Endpoint is configured with the web service features. These features override the corresponding features that are specified in WSDL, if present.

  • publish(String address, Object implementor)

    Creates and publishes an Endpoint for the given implementor. The binding is chosen by default based on the URL scheme of the provided address (which must be a URL). If a suitable binding if found, the endpoint is created then published as if the Endpoint.publish(String address) method had been called. The created Endpoint is then returned as the value of the method.

  • publish(String address, Object implementor, WebServiceFeature ... features)

    Same as the above publish() method. The created Endpoint is configured with the web service features. These features override the corresponding features that are specified in WSDL, if present.

These methods MUST delegate the creation of Endpoint to the javax.xml.ws.spi.Provider SPI class by calling the createEndpoint and createAndPublishEndpoint methods respectively.

An implementor object MUST be either an instance of a class annotated with the @WebService annotation or an instance of a class annotated with the @WebServiceProvider annotation and implementing the Provider interface.

The publish(String,Object) method is provided as a shortcut for the common operation of creating and publishing an Endpoint. The following code provides an example of its use:

// assume Test is an endpoint implementation class annotated with @WebService
Test test = new Test();
Endpoint e = Endpoint.publish("http://localhost:8080/test", test);
						

12.1.5.  Use @Action and @FaultAction on the service methods.

javax.xml.ws.Action

The @Action annotation is applied to the methods of a SEI. It is used to specify the input, output, fault WS-Addressing Action values associated with the annotated method.

For such a method, the mapped operation in the generated WSDL's wsam:Action attribute on the WSDL input, output and fault messages of the WSDL operation is based upon which attributes of the @Action annotation have been specified.

public @interface Action {
    /**
     * Explicit value of the WS-Addressing Action message addressing property for the input
     * message of the operation.
     */
    String input() default "";

    /**
     * Explicit value of the WS-Addressing Action message addressing property for the output
     * message of the operation.
     */
    String output() default "";

    /**
     * Explicit value of the WS-Addressing Action message addressing property for the fault
     * message(s) of the operation. Each exception that is mapped to a fault and requires an explicit WS-Addressing
     * Action message addressing property, needs to be specified as a value in this property
     * using @FaultAction annotation.
     */
    FaultAction[] fault() default { };
}
						

javax.xml.ws.FaultAction

The @FaultAction annotation is used within the @Action annotation to specify the WS-Addressing Action of a service specific exception.

The wsam:Action attribute value in the fault message in the generated WSDL operation mapped for an exception class is equal to the corresponding value in the FaultAction.

public @interface FaultAction {
    /**
     * Name of the exception class
     */
    Class className();

    /**
     * Value of WS-Addressing Action message addressing property for the exception
     */
    String value() default "";
}
						

JAX-WS 2.1 defines javax.xml.ws.Action and javax.xml.ws.FaultAction annotations to explicitly associate an Action with input, output, and fault messages of the mapped WSDL operation. For example:

@Action(
    input = "http://example.com/input3",
    output = "http://example.com/output3",
    fault = {
        @FaultAction(className = AddNumbersException.class, value = "http://example.com/fault3")
    })
public int addNumbers3(int number1, int number2) throws AddNumbersException {
	...
}
						

The generated WSDL fragment looks like:


<operation name="addNumbers3">
  <input wsaw:Action="http://example.com/input3" message="tns:addNumbers3"/>
  <output wsaw:Action="http://example.com/output3" message="tns:addNumbers3Response"/>
  <fault message="tns:AddNumbersException" name="AddNumbersException" wsaw:Action="http://example.com/fault3"/>
</operation>

						

12.1.6.  Use WebServiceContext.getEndpointReference()

An endpoint implementation can retrieve an javax.xml.ws.EndpointReference for the endpoint using getEndpointReference(List<Element> referenceParameters), and getEndpointReference(Class<T> clazz, List<Element> referenceParameters) methods. These methods have the same semantics as the Endpoint.getEndpointReference() methods.

The following methods can be used on a published Endpoint to retrieve an javax.xml.ws.EndpointReference for the Endpoint instance:

  • getEndpointReference(List<Element> referenceParameters)

    Creates and returns javax.xml.ws.EndpointReference for a published Endpoint. If the binding is SOAP 1.1/HTTP or SOAP 1.2/HTTP, then a javax.xml.ws.wsaddressing.W3CEndpointReference MUST be returned. A returned W3CEndpointReference MUST also contain the specified referenceParameters.

  • getEndpointReference(Class<T> clazz, List<Element> referenceParameters)

    Creates and returns and javax.xml.ws.EndpointReference of type clazz for a published Endpoint instance. If clazz is of type javax.xml.ws.wsaddressing.W3CEndpointReference, then the returned W3CEndpointReference MUST contain the specified referenceParameters.

javax.xml.ws.W3CEndpointReference

The W3CEndpointReference class is a concrete implementation of the javax.xml.ws.EndpointReference class and is used to reference endpoints that are compliant with the W3C Web Services Addressing 1.0 - Core recommendation. Applications may use this class to pass EndpointReference instancess as method parameters or return types. JAXB 2.1 will bind the W3CEndpointReference class to the W3C EndpointReference XML Schema in the WSDL.

Professional hosting         'Oracle Certified Expert Web Services Developer 6' Quiz     Free SCDJWS 5.0 Guide