Ce contenu n'est pas disponible dans la langue sélectionnée.
Chapter 27. Top-Down Service Development
Abstract
In the top-down method of developing a service provider you start from a WSDL document that defines the operations and methods the service provider will implement. Using the WSDL document, you generate starting point code for the service provider. Adding the business logic to the generated code is done using normal Java programming APIs.
27.1. Overview of JAX-WS Service Provider Development
Once you have a WSDL document, the process for developing a JAX-WS service provider is as follows:
- Section 27.2, “Generating the Starting Point Code” starting point code.
- Implement the service provider’s operations.
- Chapter 31, Publishing a Service the implemented service.
27.2. Generating the Starting Point Code
Overview
JAX-WS specifies a detailed mapping from a service defined in WSDL to the Java classes that will implement that service as a service provider. The logical interface, defined by the wsdl:portType
element, is mapped to a service endpoint interface (SEI). Any complex types defined in the WSDL are mapped into Java classes following the mapping defined by the Java Architecture for XML Binding (JAXB) specification. The endpoint defined by the wsdl:service
element is also generated into a Java class that is used by consumers to access service providers implementing the service.
The cxf-codegen-plugin
Maven plug-in generates this code. It also provides options for generating starting point code for your implementation. The code generator provides a number of options for controlling the generated code.
Running the code generator
Example 27.1, “Service Code Generation” shows how to use the code generator to generate starting point code for a service.
Example 27.1. Service Code Generation
<plugin> <groupId>org.apache.cxf</groupId> <artifactId>cxf-codegen-plugin</artifactId> <version>${cxf.version}</version> <executions> <execution> <id>generate-sources</id> <phase>generate-sources</phase> <configuration> <sourceRoot>outputDir</sourceRoot> <wsdlOptions> <wsdlOption> <wsdl>wsdl</wsdl> <extraargs> <extraarg>-server</extraarg> <extraarg>-impl</extraarg> </extraargs> </wsdlOption> </wsdlOptions> </configuration> <goals> <goal>wsdl2java</goal> </goals> </execution> </executions> </plugin>
This does the following:
-
The
-impl
option generates a shell implementation class for eachwsdl:portType
element in the WSDL contract. -
The
-server
option generates a simplemain()
to run your service provider as a stand alone application. -
The
sourceRoot
specifies that the generated code is written to a directory called outputDir. -
wsdl
element specifies the WSDL contract from which code is generated.
For a complete list of the options for the code generator see Section 44.2, “cxf-codegen-plugin”.
Generated code
Table 27.1, “Generated Classes for a Service Provider” describes the files generated for creating a service provider.
File | Description |
---|---|
The SEI. This file contains the interface your service provider implements. You should not edit this file. | |
| The endpoint. This file contains the Java class consumers use to make requests on the service. |
The skeleton implementation class. Modify this file to build your service provider. | |
| A basic server mainline that allows you to deploy your service provider as a stand alone process. For more information see Chapter 31, Publishing a Service. |
In addition, the code generator will generate Java classes for all of the types defined in the WSDL contract.
Generated packages
The generated code is placed into packages based on the namespaces used in the WSDL contract. The classes generated to support the service (based on the wsdl:portType
element, the wsdl:service
element, and the wsdl:port
element) are placed in a package based on the target namespace of the WSDL contract. The classes generated to implement the types defined in the types
element of the contract are placed in a package based on the targetNamespace
attribute of the types
element.
The mapping algorithm is as follows:
-
The leading
http://
orurn://
are stripped off the namespace. -
If the first string in the namespace is a valid Internet domain, for example it ends in
.com
or.gov
, then the leadingwww.
is stripped off the string, and the two remaining components are flipped. -
If the final string in the namespace ends with a file extension of the pattern
.xxx
or.xx
, then the extension is stripped. - The remaining strings in the namespace are appended to the resulting string and separated by dots.
- All letters are made lowercase.
27.3. Implementing the Service Provider
Generating the implementation code
You generate the implementation class used to build your service provider with the code generator’s -impl
flag.
If your service’s contract includes any custom types defined in XML Schema, you must ensure that the classes for the types are generated and available.
For more information on using the code generator see Section 44.2, “cxf-codegen-plugin”.
Generated code
The implementation code consists of two files:
-
portTypeName.java
— The service interface(SEI) for the service. -
portTypeNameImpl.java
— The class you will use to implement the operations defined by the service.
Implement the operation’s logic
To provide the business logic for your service’s operations complete the stub methods in portTypeNameImpl.java
. You usually use standard Java to implement the business logic. If your service uses custom XML Schema types, you must use the generated classes for each type to manipulate them. There are also some Apache CXF specific APIs that can be used to access some advanced features.
Example
For example, an implementation class for the service defined in Example 26.1, “HelloWorld WSDL Contract” may look like Example 27.2, “Implementation of the Greeter Service”. Only the code portions highlighted in bold must be inserted by the programmer.
Example 27.2. Implementation of the Greeter Service
package demo.hw.server; import org.apache.hello_world_soap_http.Greeter; @javax.jws.WebService(portName = "SoapPort", serviceName = "SOAPService", targetNamespace = "http://apache.org/hello_world_soap_http", endpointInterface = "org.apache.hello_world_soap_http.Greeter") public class GreeterImpl implements Greeter { public String greetMe(String me) { System.out.println("Executing operation greetMe"); System.out.println("Message received: " + me + "\n"); return "Hello " + me; } public void greetMeOneWay(String me) { System.out.println("Executing operation greetMeOneWay\n"); System.out.println("Hello there " + me); } public String sayHi() { System.out.println("Executing operation sayHi\n"); return "Bonjour"; } public void pingMe() throws PingMeFault { FaultDetail faultDetail = new FaultDetail(); faultDetail.setMajor((short)2); faultDetail.setMinor((short)1); System.out.println("Executing operation pingMe, throwing PingMeFault exception\n"); throw new PingMeFault("PingMeFault raised by server", faultDetail); } }