Chapter 24. Bottom-Up Service Development

Abstract

There are many instances where you have Java code that already implements a set of functionality that you want to expose as part of a service oriented application. You may also simply want to avoid using WSDL to define your interface. Using JAX-WS annotations, you can add the information required to service enable a Java class. You can also create a Service Endpoint Interface (SEI) that can be used in place of a WSDL contract. If you want a WSDL contract, Apache CXF provides tools to generate a contract from annotated Java code.

24.1. Introduction to JAX-WS Service Development

To create a service starting from Java you must do the following:

  1. Section 24.2, “Creating the SEI” a Service Endpoint Interface (SEI) that defines the methods you want to expose as a service.

    Note

    You can work directly from a Java class, but working from an interface is the recommended approach. Interfaces are better suited for sharing with the developers who are responsible for developing the applications consuming your service. The interface is smaller and does not provide any of the service’s implementation details.

  2. Section 24.3, “Annotating the Code” the required annotations to your code.
  3. Section 24.4, “Generating WSDL” the WSDL contract for your service.

    Note

    If you intend to use the SEI as the service’s contract, it is not necessary to generate a WSDL contract.

  4. Chapter 31, Publishing a Service the service as a service provider.

24.2. Creating the SEI

Overview

The service endpoint interface (SEI) is the piece of Java code that is shared between a service implementation and the consumers that make requests on that service. The SEI defines the methods implemented by the service and provides details about how the service will be exposed as an endpoint. When starting with a WSDL contract, the SEI is generated by the code generators. However, when starting from Java, it is the developer’s responsibility to create the SEI. There are two basic patterns for creating an SEI:

  • Green field development — In this pattern, you are developing a new service without any existing Java code or WSDL. It is best to start by creating the SEI. You can then distribute the SEI to any developers that are responsible for implementing the service providers and consumers that use the SEI.

    Note

    The recommended way to do green field service development is to start by creating a WSDL contract that defines the service and its interfaces. See Chapter 26, A Starting Point WSDL Contract.

  • Service enablement — In this pattern, you typically have an existing set of functionality that is implemented as a Java class, and you want to service enable it. This means that you must do two things:

    1. Create an SEI that contains only the operations that are going to be exposed as part of the service.
    2. Modify the existing Java class so that it implements the SEI.

      Note

      Although you can add the JAX-WS annotations to a Java class, it is not recommended.

Writing the interface

The SEI is a standard Java interface. It defines a set of methods that a class implements. It can also define a number of member fields and constants to which the implementing class has access.

In the case of an SEI the methods defined are intended to be mapped to operations exposed by a service. The SEI corresponds to a wsdl:portType element. The methods defined by the SEI correspond to wsdl:operation elements in the wsdl:portType element.

Note

JAX-WS defines an annotation that allows you to specify methods that are not exposed as part of a service. However, the best practice is to leave those methods out of the SEI.

Example 24.1, “Simple SEI” shows a simple SEI for a stock updating service.

Example 24.1. Simple SEI

package com.fusesource.demo;

public interface quoteReporter
{
  public Quote getQuote(String ticker);
}

Implementing the interface

Because the SEI is a standard Java interface, the class that implements it is a standard Java class. If you start with a Java class you must modify it to implement the interface. If you start with the SEI, the implementation class implements the SEI.

Example 24.2, “Simple Implementation Class” shows a class for implementing the interface in Example 24.1, “Simple SEI”.

Example 24.2. Simple Implementation Class

package com.fusesource.demo;

import java.util.*;

public class stockQuoteReporter implements quoteReporter
{
  ...
public Quote getQuote(String ticker)
  {
    Quote retVal = new Quote();
    retVal.setID(ticker);
    retVal.setVal(Board.check(ticker));[1]
    Date retDate = new Date();
    retVal.setTime(retDate.toString());
    return(retVal);
  }
}

24.3. Annotating the Code

24.3.1. Overview of JAX-WS Annotations

The JAX-WS annotations specify the metadata used to map the SEI to a fully specified service definition. Among the information provided in the annotations are the following:

  • The target namespace for the service.
  • The name of the class used to hold the request message
  • The name of the class used to hold the response message
  • If an operation is a one way operation
  • The binding style the service uses
  • The name of the class used for any custom exceptions
  • The namespaces under which the types used by the service are defined
Note

Most of the annotations have sensible defaults and it is not necessary to provide values for them. However, the more information you provide in the annotations, the better your service definition is specified. A well-specified service definition increases the likelihood that all parts of a distributed application will work together.

24.3.2. Required Annotations

Overview

In order to create a service from Java code you are only required to add one annotation to your code. You must add the @WebService annotation on both the SEI and the implementation class.

The @WebService annotation

The @WebService annotation is defined by the javax.jws.WebService interface and it is placed on an interface or a class that is intended to be used as a service. @WebService has the properties described in Table 24.1, “@WebService Properties”

Table 24.1. @WebService Properties

PropertyDescription

name

Specifies the name of the service interface. This property is mapped to the name attribute of the wsdl:portType element that defines the service’s interface in a WSDL contract. The default is to append PortType to the name of the implementation class. [a]

targetNamespace

Specifies the target namespace where the service is defined. If this property is not specified, the target namespace is derived from the package name.

serviceName

Specifies the name of the published service. This property is mapped to the name attribute of the wsdl:service element that defines the published service. The default is to use the name of the service’s implementation class.

wsdlLocation

Specifies the URL where the service’s WSDL contract is stored. This must be specified using a relative URL. The default is the URL where the service is deployed.

endpointInterface

Specifies the full name of the SEI that the implementation class implements. This property is only specified when the attribute is used on a service implementation class.

portName

Specifies the name of the endpoint at which the service is published. This property is mapped to the name attribute of the wsdl:port element that specifies the endpoint details for a published service. The default is the append Port to the name of the service’s implementation class.

[a] When you generate WSDL from an SEI the interface’s name is used in place of the implementation class' name.
Note

It is not necessary to provide values for any of the @WebService annotation’s properties. However, it is recommended that you provide as much information as you can.

Annotating the SEI

The SEI requires that you add the @WebService annotation. Because the SEI is the contract that defines the service, you should specify as much detail as possible about the service in the @WebService annotation’s properties.

Example 24.3, “Interface with the @WebService Annotation” shows the interface defined in Example 24.1, “Simple SEI” with the @WebService annotation.

Example 24.3. Interface with the @WebService Annotation

package com.fusesource.demo;

import javax.jws.*;

@WebService(name="quoteUpdater",
            targetNamespace="http:\\demos.redhat.com",
	        serviceName="updateQuoteService",
            wsdlLocation="http:\\demos.redhat.com\quoteExampleService?wsdl",
            portName="updateQuotePort")
public interface quoteReporter
{
  public Quote getQuote(String ticker);
}

The @WebService annotation in Example 24.3, “Interface with the @WebService Annotation” does the following:

Specifies that the value of the name attribute of the wsdl:portType element defining the service interface is quoteUpdater.

Specifies that the target namespace of the service is http:\\demos.redhat.com.

Specifies that the value of the name of the wsdl:service element defining the published service is updateQuoteService.

Specifies that the service will publish its WSDL contract at http:\\demos.redhat.com\quoteExampleService?wsdl.

Specifies that the value of the name attribute of the wsdl:port element defining the endpoint exposing the service is updateQuotePort.

Annotating the service implementation

In addition to annotating the SEI with the @WebService annotation, you also must annotate the service implementation class with the @WebService annotation. When adding the annotation to the service implementation class you only need to specify the endpointInterface property. As shown in Example 24.4, “Annotated Service Implementation Class” the property must be set to the full name of the SEI.

Example 24.4. Annotated Service Implementation Class

package org.eric.demo;

import javax.jws.*;

@WebService(endpointInterface="com.fusesource.demo.quoteReporter")
public class stockQuoteReporter implements quoteReporter
{
public Quote getQuote(String ticker)
  {
  ...
  }
}

24.3.3. Optional Annotations

Abstract

While the @WebService annotation is sufficient for service enabling a Java interface or a Java class, it does not fully describe how the service will be exposed as a service provider. The JAX-WS programming model uses a number of optional annotations for adding details about your service, such as the binding it uses, to the Java code. You add these annotations to the service’s SEI.

The more details you provide in the SEI the easier it is for developers to implement applications that can use the functionality it defines. It also makes the WSDL documents generated by the tools more specific.

Overview

Defining the Binding Properties with Annotations

If you are using a SOAP binding for your service, you can use JAX-WS annotations to specify a number of the bindings properties. These properties correspond directly to the properties you can specify in a service’s WSDL contract. Some of the settings, such as the parameter style, can restrict how you implement a method. These settings can also effect which annotations can be used when annotating method parameters.

The @SOAPBinding annotation

The @SOAPBinding annotation is defined by the javax.jws.soap.SOAPBinding interface. It provides details about the SOAP binding used by the service when it is deployed. If the @SOAPBinding annotation is not specified, a service is published using a wrapped doc/literal SOAP binding.

You can put the @SOAPBinding annotation on the SEI and any of the SEI’s methods. When it is used on a method, setting of the method’s @SOAPBinding annotation take precedence.

Table 24.2, “@SOAPBinding Properties” shows the properties for the @SOAPBinding annotation.

Table 24.2. @SOAPBinding Properties

PropertyValuesDescription

style

Style.DOCUMENT (default)

Style.RPC

Specifies the style of the SOAP message. If RPC style is specified, each message part within the SOAP body is a parameter or return value and appears inside a wrapper element within the soap:body element. The message parts within the wrapper element correspond to operation parameters and must appear in the same order as the parameters in the operation. If DOCUMENT style is specified, the contents of the SOAP body must be a valid XML document, but its form is not as tightly constrained.

use

Use.LITERAL (default)

Use.ENCODED[a]

Specifies how the data of the SOAP message is streamed.

parameterStyle [b]

ParameterStyle.BARE

ParameterStyle.WRAPPED (default)

Specifies how the method parameters, which correspond to message parts in a WSDL contract, are placed into the SOAP message body. If BARE is specified, each parameter is placed into the message body as a child element of the message root. If WRAPPED is specified, all of the input parameters are wrapped into a single element on a request message and all of the output parameters are wrapped into a single element in the response message.

[a] Use.ENCODED is not currently supported.
[b] If you set the style to RPC you must use the WRAPPED parameter style.

Document bare style parameters

Document bare style is the most direct mapping between Java code and the resulting XML representation of the service. When using this style, the schema types are generated directly from the input and output parameters defined in the operation’s parameter list.

You specify you want to use bare document\literal style by using the @SOAPBinding annotation with its style property set to Style.DOCUMENT, and its parameterStyle property set to ParameterStyle.BARE.

To ensure that an operation does not violate the restrictions of using document style when using bare parameters, your operations must adhere to the following conditions:

  • The operation must have no more than one input or input/output parameter.
  • If the operation has a return type other than void, it must not have any output or input/output parameters.
  • If the operation has a return type of void, it must have no more than one output or input/output parameter.
Note

Any parameters that are placed in the SOAP header using the @WebParam annotation or the @WebResult annotation are not counted against the number of allowed parameters.

Document wrapped parameters

Document wrapped style allows a more RPC like mapping between the Java code and the resulting XML representation of the service. When using this style, the parameters in the method’s parameter list are wrapped into a single element by the binding. The disadvantage of this is that it introduces an extra-layer of indirection between the Java implementation and how the messages are placed on the wire.

To specify that you want to use wrapped document\literal style use the @SOAPBinding annotation with its style property set to Style.DOCUMENT, and its parameterStyle property set to ParameterStyle.WRAPPED.

You have some control over how the wrappers are generated by using the the section called “The @RequestWrapper annotation” annotation and the the section called “The @ResponseWrapper annotation” annotation.

Example

Example 24.5, “Specifying a Document Bare SOAP Binding with the SOAP Binding Annotation” shows an SEI that uses document bare SOAP messages.

Example 24.5. Specifying a Document Bare SOAP Binding with the SOAP Binding Annotation

package org.eric.demo;

import javax.jws.*;
import javax.jws.soap.*;
import javax.jws.soap.SOAPBinding.*;

@WebService(name="quoteReporter")
@SOAPBinding(parameterStyle=ParameterStyle.BARE)
public interface quoteReporter
{
  ...
}

Overview

Defining Operation Properties with Annotations

When the runtime maps your Java method definitions into XML operation definitions it provides details such as:

  • What the exchanged messages look like in XML
  • If the message can be optimized as a one way message
  • The namespaces where the messages are defined

The @WebMethod annotation

The @WebMethod annotation is defined by the javax.jws.WebMethod interface. It is placed on the methods in the SEI. The @WebMethod annotation provides the information that is normally represented in the wsdl:operation element describing the operation to which the method is associated.

Table 24.3, “@WebMethod Properties” describes the properties of the @WebMethod annotation.

Table 24.3. @WebMethod Properties

PropertyDescription

operationName

Specifies the value of the associated wsdl:operation element’s name. The default value is the name of the method.

action

Specifies the value of the soapAction attribute of the soap:operation element generated for the method. The default value is an empty string.

exclude

Specifies if the method should be excluded from the service interface. The default is false.

The @RequestWrapper annotation

The @RequestWrapper annotation is defined by the javax.xml.ws.RequestWrapper interface. It is placed on the methods in the SEI. The @RequestWrapper annotation specifies the Java class implementing the wrapper bean for the method parameters of the request message starting a message exchange. It also specifies the element names, and namespaces, used by the runtime when marshalling and unmarshalling the request messages.

Table 24.4, “@RequestWrapper Properties” describes the properties of the @RequestWrapper annotation.

Table 24.4. @RequestWrapper Properties

PropertyDescription

localName

Specifies the local name of the wrapper element in the XML representation of the request message. The default value is either the name of the method, or the value of the the section called “The @WebMethod annotation” annotation’s operationName property.

targetNamespace

Specifies the namespace under which the XML wrapper element is defined. The default value is the target namespace of the SEI.

className

Specifies the full name of the Java class that implements the wrapper element.

Note

Only the className property is required.

Important

If the method is also annotated with the @SOAPBinding annotation, and its parameterStyle property is set to ParameterStyle.BARE, this annotation is ignored.

The @ResponseWrapper annotation

The @ResponseWrapper annotation is defined by the javax.xml.ws.ResponseWrapper interface. It is placed on the methods in the SEI. The @ResponseWrapper specifies the Java class implementing the wrapper bean for the method parameters in the response message in the message exchange. It also specifies the element names, and namespaces, used by the runtime when marshaling and unmarshalling the response messages.

Table 24.5, “@ResponseWrapper Properties” describes the properties of the @ResponseWrapper annotation.

Table 24.5. @ResponseWrapper Properties

PropertyDescription

localName

Specifies the local name of the wrapper element in the XML representation of the response message. The default value is either the name of the method with Response appended, or the value of the the section called “The @WebMethod annotation” annotation’s operationName property with Response appended.

targetNamespace

Specifies the namespace where the XML wrapper element is defined. The default value is the target namespace of the SEI.

className

Specifies the full name of the Java class that implements the wrapper element.

Note

Only the className property is required.

Important

If the method is also annotated with the @SOAPBinding annotation and its parameterStyle property is set to ParameterStyle.BARE, this annotation is ignored.

The @WebFault annotation

The @WebFault annotation is defined by the javax.xml.ws.WebFault interface. It is placed on exceptions that are thrown by your SEI. The @WebFault annotation is used to map the Java exception to a wsdl:fault element. This information is used to marshall the exceptions into a representation that can be processed by both the service and its consumers.

Table 24.6, “@WebFault Properties” describes the properties of the @WebFault annotation.

Table 24.6. @WebFault Properties

PropertyDescription

name

Specifies the local name of the fault element.

targetNamespace

Specifies the namespace under which the fault element is defined. The default value is the target namespace of the SEI.

faultName

Specifies the full name of the Java class that implements the exception.

Important

The name property is required.

The @Oneway annotation

The @Oneway annotation is defined by the javax.jws.Oneway interface. It is placed on the methods in the SEI that will not require a response from the service. The @Oneway annotation tells the run time that it can optimize the execution of the method by not waiting for a response and by not reserving any resources to process a response.

This annotation can only be used on methods that meet the following criteria:

  • They return void
  • They have no parameters that implement the Holder interface
  • They do not throw any exceptions that can be passed back to a consumer

Example

Example 24.6, “SEI with Annotated Methods” shows an SEI with its methods annotated.

Example 24.6. SEI with Annotated Methods

package com.fusesource.demo;

import javax.jws.*;
import javax.xml.ws.*;

@WebService(name="quoteReporter")
public interface quoteReporter
{
  @WebMethod(operationName="getStockQuote")
  @RequestWrapper(targetNamespace="http://demo.redhat.com/types",
                  className="java.lang.String")
  @ResponseWrapper(targetNamespace="http://demo.redhat.com/types",
                   className="org.eric.demo.Quote")
  public Quote getQuote(String ticker);
}

Overview

Defining Parameter Properties with Annotations

The method parameters in the SEI correspond to the wsdl:message elements and their wsdl:part elements. JAX-WS provides annotations that allow you to describe the wsdl:part elements that are generated for the method parameters.

The @WebParam annotation

The @WebParam annotation is defined by the javax.jws.WebParam interface. It is placed on the parameters of the methods defined in the SEI. The @WebParam annotation allows you to specify the direction of the parameter, if the parameter will be placed in the SOAP header, and other properties of the generated wsdl:part.

Table 24.7, “@WebParam Properties” describes the properties of the @WebParam annotation.

Table 24.7. @WebParam Properties

PropertyValuesDescription

name

 

Specifies the name of the parameter as it appears in the generated WSDL document. For RPC bindings, this is the name of the wsdl:part representing the parameter. For document bindings, this is the local name of the XML element representing the parameter. Per the JAX-WS specification, the default is argN, where N is replaced with the zero-based argument index (i.e., arg0, arg1, etc.).

targetNamespace

 

Specifies the namespace for the parameter. It is only used with document bindings where the parameter maps to an XML element. The default is to use the service’s namespace.

mode

Mode.IN (default)[a]

Mode.OUT

Mode.INOUT

Specifies the direction of the parameter.

header

false (default)

true

Specifies if the parameter is passed as part of the SOAP header.

partName

 

Specifies the value of the name attribute of the wsdl:part element for the parameter. This property is used for document style SOAP bindings.

[a] Any parameter that implements the Holder interface is mapped to Mode.INOUT by default.

The @WebResult annotation

The @WebResult annotation is defined by the javax.jws.WebResult interface. It is placed on the methods defined in the SEI. The @WebResult annotation allows you to specify the properties of the wsdl:part that is generated for the method’s return value.

Table 24.8, “@WebResult Properties” describes the properties of the @WebResult annotation.

Table 24.8. @WebResult Properties

PropertyDescription

name

Specifies the name of the return value as it appears in the generated WSDL document. For RPC bindings, this is the name of the wsdl:part representing the return value. For document bindings, this is the local name of the XML element representing the return value. The default value is return.

targetNamespace

Specifies the namespace for the return value. It is only used with document bindings where the return value maps to an XML element. The default is to use the service’s namespace.

header

Specifies if the return value is passed as part of the SOAP header.

partName

Specifies the value of the name attribute of the wsdl:part element for the return value. This property is used for document style SOAP bindings.

Example

Example 24.7, “Fully Annotated SEI” shows an SEI that is fully annotated.

Example 24.7. Fully Annotated SEI

package com.fusesource.demo;

import javax.jws.*;
import javax.xml.ws.*;
import javax.jws.soap.*;
import javax.jws.soap.SOAPBinding.*;
import javax.jws.WebParam.*;

@WebService(targetNamespace="http://demo.redhat.com",
            name="quoteReporter")
@SOAPBinding(style=Style.RPC, use=Use.LITERAL)
public interface quoteReporter
{
  @WebMethod(operationName="getStockQuote")
  @RequestWrapper(targetNamespace="http://demo.redhat.com/types",
                  className="java.lang.String")
  @ResponseWrapper(targetNamespace="http://demo.redhat.com/types",
                   className="org.eric.demo.Quote")
  @WebResult(targetNamespace="http://demo.redhat.com/types",
             name="updatedQuote")
  public Quote getQuote(
                        @WebParam(targetNamespace="http://demo.redhat.com/types",
                                  name="stockTicker",
                                  mode=Mode.IN)
                        String ticker
  );
}

24.3.4. Apache CXF Annotations

24.3.4.1. WSDL Documentation

@WSDLDocumentation annotation

The @WSDLDocumentation annotation is defined by the org.apache.cxf.annotations.WSDLDocumentation interface. It can be placed on the SEI or the SEI methods.

This annotation enables you to add documentation, which will then appear within wsdl:documentation elements after the SEI is converted to WSDL. By default, the documentation elements appear inside the port type, but you can specify the placement property to make the documentation appear at other locations in the WSDL file. Section 24.3.4.2, “@WSDLDocumentation properties” shows the properties supported by the @WSDLDocumentation annotation.

24.3.4.2. @WSDLDocumentation properties

PropertyDescription

value

(Required) A string containing the documentation text.

placement

(Optional) Specifies where in the WSDL file this documentation is to appear. For the list of possible placement values, see the section called “Placement in the WSDL contract”.

faultClass

(Optional) If the placement is set to be FAULT_MESSAGE, PORT_TYPE_OPERATION_FAULT, or BINDING_OPERATION_FAULT, you must also set this property to the Java class that represents the fault.

@WSDLDocumentationCollection annotation

The @WSDLDocumentationCollection annotation is defined by the org.apache.cxf.annotations.WSDLDocumentationCollection interface. It can be placed on the SEI or the SEI methods.

This annotation is used to insert multiple documentation elements at a single placement location or at various placement locations.

Placement in the WSDL contract

To specify where the documentation should appear in the WSDL contract, you can specify the placement property, which is of type WSDLDocumentation.Placement. The placement can have one of the following values:

  • WSDLDocumentation.Placement.BINDING
  • WSDLDocumentation.Placement.BINDING_OPERATION
  • WSDLDocumentation.Placement.BINDING_OPERATION_FAULT
  • WSDLDocumentation.Placement.BINDING_OPERATION_INPUT
  • WSDLDocumentation.Placement.BINDING_OPERATION_OUTPUT
  • WSDLDocumentation.Placement.DEFAULT
  • WSDLDocumentation.Placement.FAULT_MESSAGE
  • WSDLDocumentation.Placement.INPUT_MESSAGE
  • WSDLDocumentation.Placement.OUTPUT_MESSAGE
  • WSDLDocumentation.Placement.PORT_TYPE
  • WSDLDocumentation.Placement.PORT_TYPE_OPERATION
  • WSDLDocumentation.Placement.PORT_TYPE_OPERATION_FAULT
  • WSDLDocumentation.Placement.PORT_TYPE_OPERATION_INPUT
  • WSDLDocumentation.Placement.PORT_TYPE_OPERATION_OUTPUT
  • WSDLDocumentation.Placement.SERVICE
  • WSDLDocumentation.Placement.SERVICE_PORT
  • WSDLDocumentation.Placement.TOP
Example of @WSDLDocumentation

Section 24.3.4.3, “Using @WSDLDocumentation” shows how to add a @WSDLDocumentation annotation to the SEI and to one of its methods.

24.3.4.3. Using @WSDLDocumentation

@WebService
@WSDLDocumentation("A very simple example of an SEI")
public interface HelloWorld {
    @WSDLDocumentation("A traditional form of greeting")
    String sayHi(@WebParam(name = "text") String text);
}

When WSDL, shown in Section 24.3.4.4, “WSDL generated with documentation”, is generated from the SEI in Section 24.3.4.3, “Using @WSDLDocumentation”, the default placements of the documentation elements are, respectively, PORT_TYPE and PORT_TYPE_OPERATION.

24.3.4.4. WSDL generated with documentation

<wsdl:definitions ... >
  ...
  <wsdl:portType name="HelloWorld">
    <wsdl:documentation>A very simple example of an SEI</wsdl:documentation>
    <wsdl:operation name="sayHi">
      <wsdl:documentation>A traditional form of greeting</wsdl:documentation>
      <wsdl:input name="sayHi" message="tns:sayHi">
    </wsdl:input>
      <wsdl:output name="sayHiResponse" message="tns:sayHiResponse">
    </wsdl:output>
    </wsdl:operation>
  </wsdl:portType>
  ...
</wsdl:definitions>
Example of @WSDLDocumentationCollection

Section 24.3.4.5, “Using @WSDLDocumentationCollection” shows how to add a @WSDLDocumentationCollection annotation to an SEI.

24.3.4.5. Using @WSDLDocumentationCollection

@WebService
@WSDLDocumentationCollection(
    {
        @WSDLDocumentation("A very simple example of an SEI"),
        @WSDLDocumentation(value = "My top level documentation",
                           placement = WSDLDocumentation.Placement.TOP),
        @WSDLDocumentation(value = "Binding documentation",
                           placement = WSDLDocumentation.Placement.BINDING)
    }
)
public interface HelloWorld {
    @WSDLDocumentation("A traditional form of Geeky greeting")
    String sayHi(@WebParam(name = "text") String text);
}

24.3.4.6. Schema Validation of Messages

@SchemaValidation annotation

The @SchemaValidation annotation is defined by the org.apache.cxf.annotations.SchemaValidation interface. It can be placed on the SEI and on individual SEI methods.

This annotation turns on schema validation of the XML messages sent to this endpoint. This can be useful for testing purposes, when you suspect there is a problem with the format of incoming XML messages. By default, validation is disabled, because it has a significant impact on performance.

Schema validation type

The schema validation behaviour is controlled by the type parameter, whose value is an enumeration of org.apache.cxf.annotations.SchemaValidation.SchemaValidationType type. Section 24.3.4.7, “Schema Validation Type Values” shows the list of available validation types.

24.3.4.7. Schema Validation Type Values

TypeDescription

IN

Apply schema validation to incoming messages on client and server.

OUT

Apply schema validation to outgoing messages on client and server.

BOTH

Apply schema validation to both incoming and outgoing messages on client and server.

NONE

All schema validation is disabled.

REQUEST

Apply schema validation to Request messages—that is, causing validation to be applied to outgoing client messages and to incoming server messages.

RESPONSE

Apply schema validation to Response messages—that is, causing validation to be applied to incoming client messages, and outgoing server messages.

Example

The following example shows how to enable schema validation of messages for endpoints based on the MyService SEI. Note how the annotation can be applied to the SEI as a whole, as well as to individual methods in the SEI.

@WebService
@SchemaValidation(type = SchemaValidationType.BOTH)
public interface MyService {
    Foo validateBoth(Bar data);

    @SchemaValidation(type = SchemaValidationType.NONE)
    Foo validateNone(Bar data);

    @SchemaValidation(type = SchemaValidationType.IN)
    Foo validateIn(Bar data);

    @SchemaValidation(type = SchemaValidationType.OUT)
    Foo validateOut(Bar data);

    @SchemaValidation(type = SchemaValidationType.REQUEST)
    Foo validateRequest(Bar data);

    @SchemaValidation(type = SchemaValidationType.RESPONSE)
    Foo validateResponse(Bar data);
}

24.3.4.8. Specifying the Data Binding

@DataBinding annotation

The @DataBinding annotation is defined by the org.apache.cxf.annotations.DataBinding interface. It is placed on the SEI.

This annotation is used to associate a data binding with the SEI, replacing the default JAXB data binding. The value of the @DataBinding annotation must be the class that provides the data binding, ClassName.class.

Supported data bindings

The following data bindings are currently supported by Apache CXF:

  • org.apache.cxf.jaxb.JAXBDataBinding

    (Default) The standard JAXB data binding.

  • org.apache.cxf.sdo.SDODataBinding

    The Service Data Objects (SDO) data binding is based on the Apache Tuscany SDO implementation. If you want to use this data binding in the context of a Maven build, you need to add a dependency on the cxf-rt-databinding-sdo artifact.

  • org.apache.cxf.aegis.databinding.AegisDatabinding

    If you want to use this data binding in the context of a Maven build, you need to add a dependency on the cxf-rt-databinding-aegis artifact.

  • org.apache.cxf.xmlbeans.XmlBeansDataBinding

    If you want to use this data binding in the context of a Maven build, you need to add a dependency on the cxf-rt-databinding-xmlbeans artifact.

  • org.apache.cxf.databinding.source.SourceDataBinding

    This data binding belongs to the Apache CXF core.

  • org.apache.cxf.databinding.stax.StaxDataBinding

    This data binding belongs to the Apache CXF core.

Example

Section 24.3.4.9, “Setting the data binding” shows how to associate the SDO binding with the HelloWorld SEI

24.3.4.9. Setting the data binding

@WebService
@DataBinding(org.apache.cxf.sdo.SDODataBinding.class)
public interface HelloWorld {
    String sayHi(@WebParam(name = "text") String text);
}

24.3.4.10. Compressing Messages

@GZIP annotation

The @GZIP annotation is defined by the org.apache.cxf.annotations.GZIP interface. It is placed on the SEI.

Enables GZIP compression of messages. GZIP is a negotiated enhancement. That is, an initial request from a client will not be gzipped, but an Accept header will be added and, if the server supports GZIP compression, the response will be gzipped and any subsequent requests will be also.

Section 24.3.4.11, “@GZIP Properties” shows the optional properties supported by the @GZIP annotation.

24.3.4.11. @GZIP Properties

PropertyDescription

threshold

Messages smaller than the size specified by this property are not gzipped. Default is -1 (no limit).

@FastInfoset

The @FastInfoset annotation is defined by the org.apache.cxf.annotations.FastInfoset interface. It is placed on the SEI.

Enables the use of FastInfoset format for messages. FastInfoset is a binary encoding format for XML, which aims to optimize both the message size and the processing performance of XML messages. For more details, see the following Sun article on Fast Infoset.

FastInfoset is a negotiated enhancement. That is, an initial request from a client will not be in FastInfoset format, but an Accept header will be added and, if the server supports FastInfoset, the response will be in FastInfoset and any subsequent requests will be also.

Section 24.3.4.12, “@FastInfoset Properties” shows the optional properties supported by the @FastInfoset annotation.

24.3.4.12. @FastInfoset Properties

PropertyDescription

force

A boolean property that forces the use of FastInfoset format, instead of negotiating. When true, force the use of FastInfoset format; otherwise, negotiate. Default is false.

Example of @GZIP

Section 24.3.4.13, “Enabling GZIP” shows how to enable GZIP compression for the HelloWorld SEI.

24.3.4.13. Enabling GZIP

@WebService
@GZIP
public interface HelloWorld {
    String sayHi(@WebParam(name = "text") String text);
}
Exampe of @FastInfoset

Section 24.3.4.14, “Enabling FastInfoset” shows how to enable the FastInfoset format for the HelloWorld SEI.

24.3.4.14. Enabling FastInfoset

@WebService
@FastInfoset
public interface HelloWorld {
    String sayHi(@WebParam(name = "text") String text);
}

24.3.4.15. Enable Logging on an Endpoint

@Logging annotation

The @Logging annotation is defined by the org.apache.cxf.annotations.Logging interface. It is placed on the SEI.

This annotation enables logging for all endpoints associated with the SEI. Section 24.3.4.16, “@Logging Properties” shows the optional properties you can set in this annotation.

24.3.4.16. @Logging Properties

PropertyDescription

limit

Specifies the size limit, beyond which the message is truncated in the logs. Default is 64K.

inLocation

Specifies the location to log incoming messages. Can be either <stderr>, <stdout>, <logger>, or a filename. Default is <logger>.

outLocation

Specifies the location to log outgoing messages. Can be either <stderr>, <stdout>, <logger>, or a filename. Default is <logger>.

Example

Section 24.3.4.17, “Logging configuration using annotations” shows how to enable logging for the HelloWorld SEI, where incoming messages are sent to <stdout> and outgoing messages are sent to <logger>.

24.3.4.17. Logging configuration using annotations

@WebService
@Logging(limit=16000, inLocation="<stdout>")
public interface HelloWorld {
    String sayHi(@WebParam(name = "text") String text);
}

24.3.4.18. Adding Properties and Policies to an Endpoint

Abstract

Both properties and policies can be used to associate configuration data with an endpoint. The essential difference between them is that properties are a Apache CXF specific configuration mechanism whereas policies are a standard WSDL configuration mechanism. Policies typically originate from WS specifications and standards and they are normally set by defining wsdl:policy elements that appear in the WSDL contract. By contrast, properties are Apache CXF-specific and they are normally set by defining jaxws:properties elements in the Apache CXF Spring configuration file.

It is also possible, however, to define property settings and WSDL policy settings in Java using annotations, as described here.

24.3.4.19. Adding properties

@EndpointProperty annotation

The @EndpointProperty annotation is defined by the org.apache.cxf.annotations.EndpointProperty interface. It is placed on the SEI.

This annotation adds Apache CXF-specific configuration settings to an endpoint. Endpoint properties can also be specified in a Spring configuration file. For example, to configure WS-Security on an endpoint, you could add endpoint properties using the jaxws:properties element in a Spring configuration file as follows:

<beans xmlns="http://www.springframework.org/schema/beans"
   xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
   xmlns:jaxws="http://cxf.apache.org/jaxws"
   ... >

   <jaxws:endpoint
      id="MyService"
      address="https://localhost:9001/MyService"
      serviceName="interop:MyService"
      endpointName="interop:MyServiceEndpoint"
      implementor="com.foo.MyService">

      <jaxws:properties>
         <entry key="ws-security.callback-handler" value="interop.client.UTPasswordCallback"/>
         <entry key="ws-security.signature.properties" value="etc/keystore.properties"/>
         <entry key="ws-security.encryption.properties" value="etc/truststore.properties"/>
         <entry key="ws-security.encryption.username" value="useReqSigCert"/>
      </jaxws:properties>

   </jaxws:endpoint>
</beans>

Alternatively, you could specify the preceding configuration settings in Java by adding @EndpointProperty annotations to the SEI, as shown in Section 24.3.4.20, “Configuring WS-Security Using @EndpointProperty Annotations”.

24.3.4.20. Configuring WS-Security Using @EndpointProperty Annotations

@WebService
@EndpointProperty(name="ws-security.callback-handler" value="interop.client.UTPasswordCallback")
@EndpointProperty(name="ws-security.signature.properties" value="etc/keystore.properties")
@EndpointProperty(name="ws-security.encryption.properties" value="etc/truststore.properties")
@EndpointProperty(name="ws-security.encryption.username" value="useReqSigCert")
public interface HelloWorld {
    String sayHi(@WebParam(name = "text") String text);
}
@EndpointProperties annotation

The @EndpointProperties annotation is defined by the org.apache.cxf.annotations.EndpointProperties interface. It is placed on the SEI.

This annotation provides a way of grouping multiple @EndpointProperty annotations into a list. Using @EndpointProperties, it is possible to re-write Section 24.3.4.20, “Configuring WS-Security Using @EndpointProperty Annotations” as shown in Section 24.3.4.21, “Configuring WS-Security Using an @EndpointProperties Annotation”.

24.3.4.21. Configuring WS-Security Using an @EndpointProperties Annotation

@WebService
@EndpointProperties(
  {
  @EndpointProperty(name="ws-security.callback-handler" value="interop.client.UTPasswordCallback"),
  @EndpointProperty(name="ws-security.signature.properties" value="etc/keystore.properties"),
  @EndpointProperty(name="ws-security.encryption.properties" value="etc/truststore.properties"),
  @EndpointProperty(name="ws-security.encryption.username" value="useReqSigCert")
})
public interface HelloWorld {
    String sayHi(@WebParam(name = "text") String text);
}

24.3.4.22. Adding policies

@Policy annotation

The @Policy annotation is defined by the org.apache.cxf.annotations.Policy interface. It can be placed on the SEI or the SEI methods.

This annotation is used to associate a WSDL policy with an SEI or an SEI method. The policy is specified by providing a URI that references an XML file containing a standard wsdl:policy element. If a WSDL contract is to be generated from the SEI (for example, using the java2ws command-line tool), you can specify whether or not you want to include this policy in the WSDL.

Section 24.3.4.23, “@Policy Properties” shows the properties supported by the @Policy annotation.

24.3.4.23. @Policy Properties

PropertyDescription

uri

(Required) The location of the file containing the policy definition.

includeInWSDL

(Optional) Whether to include the policy in the generated contract, when generating WSDL. Default is true.

placement

(Optional) Specifies where in the WSDL file this documentation is to appear. For the list of possible placement values, see the section called “Placement in the WSDL contract”.

faultClass

(Optional) If the placement is set to be BINDING_OPERATION_FAULT or PORT_TYPE_OPERATION_FAULT, you must also set this property to specify which fault this policy applies to. The value is the Java class that represents the fault.

@Policies annotation

The @Policies annotation is defined by the org.apache.cxf.annotations.Policies interface. It can be placed on the SEI or thse SEI methods.

This annotation provides a way of grouping multiple @Policy annotations into a list.

Placement in the WSDL contract

To specify where the policy should appear in the WSDL contract, you can specify the placement property, which is of type Policy.Placement. The placement can have one of the following values:

Policy.Placement.BINDING
Policy.Placement.BINDING_OPERATION
Policy.Placement.BINDING_OPERATION_FAULT
Policy.Placement.BINDING_OPERATION_INPUT
Policy.Placement.BINDING_OPERATION_OUTPUT
Policy.Placement.DEFAULT
Policy.Placement.PORT_TYPE
Policy.Placement.PORT_TYPE_OPERATION
Policy.Placement.PORT_TYPE_OPERATION_FAULT
Policy.Placement.PORT_TYPE_OPERATION_INPUT
Policy.Placement.PORT_TYPE_OPERATION_OUTPUT
Policy.Placement.SERVICE
Policy.Placement.SERVICE_PORT
Example of @Policy

The following example shows how to associate WSDL policies with the HelloWorld SEI and how to associate a policy with the sayHi method. The policies themselves are stored in XML files in the file system, under the annotationpolicies directory.

@WebService
@Policy(uri = "annotationpolicies/TestImplPolicy.xml",
        placement = Policy.Placement.SERVICE_PORT),
@Policy(uri = "annotationpolicies/TestPortTypePolicy.xml",
        placement = Policy.Placement.PORT_TYPE)
public interface HelloWorld {
    @Policy(uri = "annotationpolicies/TestOperationPTPolicy.xml",
            placement = Policy.Placement.PORT_TYPE_OPERATION),
    String sayHi(@WebParam(name = "text") String text);
}
Example of @Policies

You can use the @Policies annotation to group multiple @Policy annotations into a list, as shown in the following example:

@WebService
@Policies({
    @Policy(uri = "annotationpolicies/TestImplPolicy.xml",
            placement = Policy.Placement.SERVICE_PORT),
    @Policy(uri = "annotationpolicies/TestPortTypePolicy.xml",
            placement = Policy.Placement.PORT_TYPE)
})
public interface HelloWorld {
    @Policy(uri = "annotationpolicies/TestOperationPTPolicy.xml",
            placement = Policy.Placement.PORT_TYPE_OPERATION),
    String sayHi(@WebParam(name = "text") String text);
}

24.4. Generating WSDL

Using Maven

Once your code is annotated, you can generate a WSDL contract for your service using the java2ws Maven plug-in’s -wsdl option. For a detailed listing of options for the java2ws Maven plug-in see Section 44.3, “java2ws”.

Example 24.8, “Generating WSDL from Java” shows how to set up the java2ws Maven plug-in to generate WSDL.

Example 24.8. Generating WSDL from Java

<plugin>
  <groupId>org.apache.cxf</groupId>
  <artifactId>cxf-java2ws-plugin</artifactId>
  <version>${cxf.version}</version>
  <executions>
    <execution>
      <id>process-classes</id>
      <phase>process-classes</phase>
      <configuration>
        <className>className</className>
        <genWsdl>true</genWsdl>
      </configuration>
      <goals>
        <goal>java2ws</goal>
      </goals>
    </execution>
  </executions>
</plugin>
Note

Replace the value of className with the qualified className.

Example

Example 24.9, “Generated WSDL from an SEI shows the WSDL contract that is generated for the SEI shown in Example 24.7, “Fully Annotated SEI”.

Example 24.9. Generated WSDL from an SEI

<?xml version="1.0" encoding="UTF-8"?>
<wsdl:definitions targetNamespace="http://demo.eric.org/"
          xmlns:tns="http://demo.eric.org/"
		  xmlns:ns1=""
		  xmlns:xsd="http://www.w3.org/2001/XMLSchema"
		  xmlns:ns2="http://demo.eric.org/types"
		  xmlns:soap="http://schemas.xmlsoap.org/wsdl/soap/"
		  xmlns:wsdl="http://schemas.xmlsoap.org/wsdl/">
  <wsdl:types>
    <xsd:schema>
      <xs:complexType name="quote">
        <xs:sequence>
          <xs:element name="ID" type="xs:string" minOccurs="0"/>
          <xs:element name="time" type="xs:string" minOccurs="0"/>
          <xs:element name="val" type="xs:float"/>
        </xs:sequence>
      </xs:complexType>
    </xsd:schema>
  </wsdl:types>
  <wsdl:message name="getStockQuote">
    <wsdl:part name="stockTicker" type="xsd:string">
    </wsdl:part>
  </wsdl:message>
  <wsdl:message name="getStockQuoteResponse">
    <wsdl:part name="updatedQuote" type="tns:quote">
    </wsdl:part>
  </wsdl:message>
  <wsdl:portType name="quoteReporter">
    <wsdl:operation name="getStockQuote">
      <wsdl:input name="getQuote" message="tns:getStockQuote">
    </wsdl:input>
      <wsdl:output name="getQuoteResponse" message="tns:getStockQuoteResponse">
    </wsdl:output>
    </wsdl:operation>
  </wsdl:portType>
  <wsdl:binding name="quoteReporterBinding" type="tns:quoteReporter">
    <soap:binding style="rpc" transport="http://schemas.xmlsoap.org/soap/http" />
    <wsdl:operation name="getStockQuote">
      <soap:operation style="rpc" />
      <wsdl:input name="getQuote">
        <soap:body use="literal" />
      </wsdl:input>
      <wsdl:output name="getQuoteResponse">
        <soap:body use="literal"/>
      </wsdl:output>
    </wsdl:operation>
  </wsdl:binding>
  <wsdl:service name="quoteReporterService">
    <wsdl:port name="quoteReporterPort" binding="tns:quoteReporterBinding">
      <soap:address location="http://localhost:9000/quoteReporterService" />
    </wsdl:port>
  </wsdl:service>
</wsdl:definitions>


[1] Board is an assumed class whose implementation is left to the reader.