Part 2 of this four-part series on Java SE Web services showed how to use the JAX-WS API to develop SOAP-based Web services. JAX-WS also supports RESTful-based Web services, which this article shows how to develop. It first defines and then builds and runs a library Web service, and next defines, builds, and runs a simple client that accesses this service.
Defining a library web service
The library Web service, which I’ve named Library, manages a library of books with their authors. It consists of a main Library class along with supporting Book and Author classes.
Exploring the Library class
The Library class manages the four HTTP operations (DELETE, GET, POST, and PUT) that are the hallmark of a RESTful Web service and which, in this example, handle requests to delete a specific book (identified via its ISBN) or all books, get a specific book (identified via its ISBN) or the ISBNs of all books, insert a new book, or update an existing book. Listing 1 presents this class’s source code.
Listing 1 relies on various Java XML APIs such as DOM and XPath. If you’re unfamiliar with these APIs, you might want to check out my Java XML and JSON book (advertised at the end of this post).
Listing 1 reveals that the Library class is prefixed with @WebServiceProvider, @ServiceMode, and @Binding annotations.
@WebServiceProvider specifies that Library is a Web service endpoint class implementing the javax.xml.ws.Provider interface (an alternative to a Service Endpoint Interface [SEI] for services that need to work at the XML message level) in terms of its T invoke(T request) method. The actual type argument that you pass to type parameter T identifies the source of request and response data, and is one of the following types: javax.xml.transform.Source, javax.activation.DataSource, or javax.xml.soap.SOAPMessage. For a RESTful Web service provider, you would specify Source or DataSource for T.
When a request is made to the RESTful Web service, the provider class’s invoke() method is called with a source of bytes, such as a POST request’s XML document. The invoke() method responds to the request in some appropriate way, returning a source of bytes in XML format that form the service’s response. This method throws an instance of the javax.xml.ws.WebServiceException runtime exception class or one of its descendent classes (e.g., javax.xml.ws.http.HTTPException) when something goes wrong.
@ServiceMode specifies that Library‘s invoke() method receives entire protocol messages (instead of message payloads) by having its value() element initialized to javax.xml.ws.Service.Mode.MESSAGE. When this annotation isn’t present, value() defaults to javax.xml.ws.Service.Mode.PAYLOAD.