Table of Contents |
---|
Developing a Service using JAX-WS
...
Code Block | ||
---|---|---|
| ||
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 String sayHi()
{
System.out.println("Executing operation sayHi\n");
return "Bonjour";
}
}
|
...
To create a service starting from Java you need to do the following:
Create a Service Endpoint Interface (SEI) that defines the methods you wish to expose as a service.
Tip title Tip You can work directly from a Java class, but working from an interface is the recommended approach. Interfaces are better for sharing with the developers who will be responsible for developing the applications consuming your service. The interface is smaller and does not provide any of the service's implementation details.
- Add the required annotations to your code.
Generate the WSDL contract for your service.
Tip title Tip If you intend to use the SEI as the service's contract, it is not necessary to generate a WSDL contract
- Publish the service.
...
The service endpoint interface (SEI) is the piece of Java code that is shared between a service and the consumers that make requests on it. When starting with a WSDL contract, the SEI is generated by the code generators. However, when starting from Java, it is the up to a the developer to create the SEI.
There are two basic patterns for creating an SEI:
Green field development
You are developing a new service from the ground up. When starting fresh, it is best to start by creating the SEI first. You can then distribute the SEI to any developers that are responsible for implementing the services and consumers that use the SEI.Note title 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.
- 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 will need to do two things:- Create an SEI that contains only the operations that are going to be exposed as part of the service.
Modify the existing Java class so that it implements the SEI.
Note title Note You can add the JAX-WS annotations to a Java class, but that is not recommended.
...
Code Block | ||
---|---|---|
| ||
package org.apache.cxf;
public interface QuoteReporter
{
public Quote getQuote(String ticker);
}
|
...
Code Block | ||
---|---|---|
| ||
package org.apache.cxf; 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); } } |
Annotating the Code
JAX-WS relies on the annotation feature of Java 5. The JAX-WS annotations are used to 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.
Tip title Tip Most of the annotations have sensible defaults and do not need to be specified. However, the more information you provide in the annotations, the better defined your service definition. A solid service definition increases the likely hood that all parts of a distributed application will work together.
...
Code Block | ||
---|---|---|
| ||
package com.mycompany.demo;
import javax.jws.*;
@WebService(name="quoteUpdater",
targetNamespace="http://cxf.apache.org",
wsdlLocation="http://somewhere.com/quoteExampleService?wsdl")
public interface QuoteReporter
{
public Quote getQuote(@WebParam(name="ticker") String ticker);
}
|
...
Code Block | ||
---|---|---|
| ||
package org.apache.cxf;
import javax.jws.*;
@WebService(endpointInterface="org.apache.cxf.quoteReporter",
targetNamespace="http://cxf.apache.org",
portName="StockQuotePort",
serviceName="StockQuoteReporter",
)
public class StockQuoteReporter implements QuoteReporter
{
public Quote getQuote(String ticker)
{
...
}
}
|
...
Code Block | ||
---|---|---|
| ||
package org.eric.demo;
import javax.jws.*;
import javax.jws.soap.*;
import javax.jws.soap.SOAPBinding.*;
@WebService(name="quoteReporter")
@SOAPBinding(style=Style.RPC, use=Use.LITERAL)
public interface QuoteReporter
{
...
}
|
...
Code Block | ||
---|---|---|
| ||
package org.apache.cxf;
import javax.jws.*;
import javax.xml.ws.*;
@WebService(name="quoteReporter")
public interface QuoteReporter
{
@WebMethod(operationName="getStockQuote")
@RequestWrapper(targetNamespace="http://demo.mycompany.com/types",
className="java.lang.String")
@ResponseWrapper(targetNamespace="http://demo.mycompany.com/types",
className="org.eric.demo.Quote")
public Quote getQuote(String ticker);
}
|
...
Code Block | ||
---|---|---|
| ||
package org.apache.cxf;
import javax.jws.*;
import javax.xml.ws.*;
import javax.jws.soap.*;
import javax.jws.soap.SOAPBinding.*;
import javax.jws.WebParam.*;
@WebService(name="quoteReporter")
@SOAPBinding(style=Style.RPC, use=Use.LITERAL)
public interface QuoteReporter
{
@WebMethod(operationName="getStockQuote")
@RequestWrapper(targetNamespace="http://demo.mycompany.com/types",
className="java.lang.String")
@ResponseWrapper(targetNamespace="http://demo.mycompany.com/types",
className="org.eric.demo.Quote")
@WebResult(targetNamespace="http://demo.mycompany.com/types",
name="updatedQuote")
public Quote getQuote(
@WebParam(targetNamespace="http://demo.mycompany.com/types",
name="stockTicker",
mode=Mode.IN)
String ticker
);
}
|
...
Code Block | ||
---|---|---|
| ||
<?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>
|