Chapter 8 JAX-WS Web Services
8.1. Introduction to Web Services
8.2. WSDL
8.3. SOAP
8.4 Your First Web Service
8.5 Accessing Web Services
8.6 Web Services, Session Beans, and State
8.7 RESTful Web Services
8.8 Practice Labs
8.9 Summary
8.10 Chapter Review
8.11 Exercises
In This Chapter:
JAX-WS Web Services
WSDL
SOAP
Accessing Web Services
REST/RESTful Web Service Concepts
Practice Labs
8.1 Introduction to Web Services
What is a web service? If you asked some people on the street they would probably say things like “DSL,” “dial-up,” or even start naming their favorite websites or browsing program. But web services aren't something that people use directly. A web service is a service meant for consumption by another application or component, much in the same way that session beans are meant to be used by other application components. The Internet connects millions of computers across the world together to allow people to communicate and access services provided by other people. Web services work in much the same way, using the standard technologies already in place to allow applications to communicate and provide services to other applications.
Business logic can be put into session beans for enterprise applications and accessed remotely as we learned earlier. But there may be some situations in which it is undesirable or even impossible to allow this level of access to an enterprise application's session beans. What if you don't control the network that the other components are on? What if you don't have control over any aspect of the code that needs your business logic (including the language it is written in)?
Let's say that you have a business idea to create an authentication service. Customers will be able to pass a username and password to your application from their client applications and get a boolean value of true if the authentication succeeds, or false if it does not. This would free developers from having to write authentication logic into their applications, managing security policies, and maintaining a database of user information. This would be easy to implement using session beans. But some customers may be behind a firewall and unable to make a direct connection to the application server hosting the session bean. Other customers might not be using Java in the client application.
If you were able to use a ubiquitous protocol, one that is likely to be available even in restricted networks, you could use that protocol to communicate with the client application. Web services were designed for situations just like this. Rather than limiting potential clients to only those using Java, web services allow applications to communicate over the widely used HTTP protocol, the same protocol that powers the World Wide Web. Most networks are Internet-accessible and it is increasingly unlikely that HTTP traffic will be blocked. In addition, the technologies involved are accessible from a wide variety of programming languages. This is just what Web Services do – allow communication between two applications using standard technologies like HTTP and XML.
Web services use existing Internet application protocols like HTTP as a carrier for messages between the web service and the client. The HTTP protocol becomes a sort of box for shipping web services messages back and forth between applications. The basic transport protocol that provides Internet connectivity is TCP/IP, without which there would be no Web for the web services to be part of. Dependent upon that protocol is the application protocol that wraps up the web service message. Normally, this would be the end of the line – it is the protocol that web browsers and web servers use to communicate. HTTP wasn't designed to carry information about remote method calls, however, so another layer is needed to allow such information to be communicated. In the case of web services this other layer is called SOAP (originally an acronym for Simple Object Access Protocol), a protocol that defines the messages that are sent between applications so that they can communicate useful messages to each other, like “run this method,” or “here is the result of your message request.” The following diagram shows how the different levels of protocols work together.
Figure 8.1: Web Service Messages
8.2 WSDL
Java's web service API is called JAX-WS, for Java API for XML Web Services. It uses the SOAP protocol (which in turn uses XML) to exchange messages between applications. The services are defined by a WSDL (Web Services Description Language) document. The WSDL document is yet another XML document that defines the capabilities of the web service and allows remote applications to see which methods the web service provides. One of the advantages of using NetBeans to develop web services in Java is that the creation is greatly simplified. While it is a worthwhile activity to learn XML, you will not have to write a single line of XML by hand to get a web service up and running. Here is a sample of a simple web service with one method:
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<!-- Generated by JAX-WS RI at RI's version is JAX-WS RI 2.1.3.1-hudson-417-SNAPSHOT. -->
<definitions targetNamespace=" name="NewWebServiceService" xmlns=" xmlns:tns=" xmlns:xsd=" xmlns:soap=" xmlns:wsu="
<types>
<xsd:schema>
<xsd:import namespace=" schemaLocation="NewWebServiceService_schema1.xsd"/>
</xsd:schema>
</types>
<message name="add">
<part name="parameters" element="tns:add"/>
</message>
<message name="addResponse">
<part name="parameters" element="tns:addResponse"/>
</message>
<portType name="NewWebService">
<operation name="add">
<input message="tns:add"/>
<output message="tns:addResponse"/>
</operation>
</portType>
<binding name="NewWebServicePortBinding" type="tns:NewWebService">
<soap:binding transport=" style="document"/>
<operation name="add">
<soap:operation soapAction=""/>
<input>
<soap:body use="literal"/>
</input>
<output>
<soap:body use="literal"/>
</output>
</operation>
</binding>
<service name="NewWebServiceService">
<port name="NewWebServicePort" binding="tns:NewWebServicePortBinding">
<soap:address location="REPLACE_WITH_ACTUAL_URL"/>
</port>
</service>
</definitions>
The types are defined in the following file, imported in the <xsd:import> element. It defines the messages “add” (the message from the client to the server) and “addResponse” (the return message from the server to the client) and the parameters each message contains. The “add” message takes two parameters of type “int” named “addend1” and “addend2.” The “addResponse” message returns a single parameter of type “int” named “return,” which is the sum of the two parameters received in the “add” message:
<xs:schema version="1.0" targetNamespace="
<xs:element name="add" type="tns:add"/>
<xs:element name="addResponse" type="tns:addResponse"/>
<xs:complexType name="add">
<xs:sequence>
<xs:element name="addend1" type="xs:int"/>
<xs:element name="addend2" type="xs:int"/>
</xs:sequence>
</xs:complexType>
<xs:complexType name="addResponse">
<xs:sequence>
<xs:element name="return" type="xs:int"/>
</xs:sequence>
</xs:complexType>
</xs:schema>
The WSDL document contains several important elements:
<types> -- The types element defines the acceptable types of data used in various parts of the web service messages that correspond to data types in regular Java programs, which define the type and range of values that can be stored in a variable. Types are defined with XML schema.
<message> -- The message element describes some communication between a web service and a client. Messages are used in web service operations and are analogous to parameters or return values in normal programs. A message could define some information that is sent to the web service by the client (like a parameter passed to a method) or information sent to the client from the web service (like the return value from a method). Messages are composed of parts, which are associated with the types defined in the WSDL document. For example, the message tag in the preceding example with the name=”addResponse” attribute defines a message that contains a part named “parameters.” The data that the “parameters” part can contain is defined by the XML schema in the <types> element.
<bindings> -- The bindings element describes the format of the message (like SOAP) and protocols that the web service will use. Web services are not restricted to the HTTP protocol. While HTTP is a very widespread protocol, it is not uncommon to bind a web service to SMTP (the protocol underlying e-mail) for some applications.
<operation> -- The operation element describes what the web service can do. It is like a method or function in a traditional programming language. An operation is described in terms of the messages that it sends and receives just as a Java method could be described in terms of the parameters it takes and the value it returns. The “add” operation in our example shows a request/response message pattern (a request is received by the web service and a response is sent). Operations are not limited to the request/response model. It is possible to send a request to a web service without getting a response back or even for a web service to send output without having received a request. Such messaging models often use the SMTP protocol, which does not rely on the request/response pattern that HTTP does.
<portType> -- The portType element describes the web service as a whole by describing the operations that are available. While it is not the top-level element in our example, it does the important work of tying together the operations and messages that define the web service's functionality.
Table 8.1: Web service parts and their corresponding Java parts
<portType> / Class<operation> / Method
<message> / Method parameter or return value
<types> / Data types (e.g., int, double, String, etc.)
Having NetBeans generate this file automatically from the code is a great benefit. It allows the programmer to concentrate on programming the logic for the web service instead of spending the majority of the time writing XML documents.
The most common transport for web service messages is the HTTP protocol. It is a well-defined protocol that has been around for years and isn't likely to change much in the near future. It is so ubiquitous that even PDAs and cell phones are using it now. In addition to its widespread adoption, it has another property that makes it useful for web services. HTTP is a response-request protocol. That is, when you send a request, you expect a response. When you type an address in your web browser and nothing comes back, you naturally assume something is wrong. This is somewhat analogous to the way we expect methods in programs to behave. Even if we don't know what the method's internal code looks like, we expect that if we call the method, it will return. In a sense we are making a request to the method and expecting a response (a return value).
8.3 SOAP
When some client application wants to use a web service it must create a port, or stub, for the methods that are implemented in the web service. When methods are called on the port, the application wraps up the method call in a SOAP request and sends it off to the server. SOAP is a protocol or standard for wrapping up these types of requests in XML to help facilitate communication. The server receives the request, executes the method with the parameters sent by the client, and then sends the return value in a SOAP response back to the client. Here is a sample SOAP request / response generated by the method call: port.add(3, 2):
SOAP Request:
<?xml version="1.0" encoding="UTF-8"?>
<S:Envelope xmlns:S="
<S:Header/>
<S:Body>
<ns2:add xmlns:ns2="
<addend1>3</addend1>
<addend2>2</addend2>
</ns2:add>
</S:Body>
</S:Envelope>
SOAP Response:
<?xml version="1.0" encoding="UTF-8"?>
<S:Envelope xmlns:S="
<S:Body>
<ns2:addResponse xmlns:ns2="
<return>5</return>
</ns2:addResponse>
</S:Body>
</S:Envelope>
As you can see from the sample, the request contains the method name (add) as an element in the <S:Body> tag. The parameters are passed as elements contained within the <ns2:add> element. The elements within the body element are defined by the web service's WSDL (since not every web service will use elements named “addend1” or “addend2”). The response contains the return value wrapped in the “return” tags. Once the response has been received by the client the return value is parsed and returned to the calling code as if it were a local method. We could write a program to generate and parse these SOAP requests and responses, but luckily we don't have to. Using NetBeans to create a web service in Java saves a great deal of time because neither the web service nor the client code has to parse the XML in the messages. That will all be handled by the API.
8.4 Your First Web Service
To get started with web services, we will create a simple “Hello World” web service that prints out a friendly message.
- Open the NetBeans IDE.
- Create a new project by choosing New → Project from the File menu to open the New Project Wizard dialog. In the dialog, choose Web from the category list on the left and choose Web Application from the Project list on the right. Click the Next button to continue.
- Enter a name for the web project and click Next to continue.
- Accept the defaults on the next dialog box and click Finish to create the project.
- Right-click on the project node and choose New → Web Service from the context menu.
- Name your web service HelloService and assign a package name. Click Finish to create the web service.
- A new node named Web Services appears under the web project and HelloService.java appears in the Editor pane. The Editor pane has a design view (the default view) and a source view. Click the source button at the top of the Editor pane to view the code.
- Click the Design button at the top of the Editor pane to switch back to the Design view.
- Click the Add Operation button in the upper left portion of the Design view.
- In the Add Operation wizard, change the name to sayHello and click OK to create the operation.
- Click on the Source button at the top of the Editor pane to switch to the source code.
- Edit the sayHello method and replace the default return statement to return the String “Hello! Welcome to the wonderful world of Web Services!”
- Click the Run button to start GlassFish. Additionally, you may need to choose Clean and Build Main Project from the Build menu or use the keyboard shortcut SHIFT + F11 to deploy the project to the web container.
- Expand the Web Services node in the project and right-click the HelloService web service. Choose Test Web Service from the context menu to test the web service you just created.
- Your web browser should automatically open to the web service tester. If it does not, open your favorite web browser and point it to
- Click the sayHello button to view the results of your web service.
8.5 Accessing Web Services
Now that we know what a web service is, what it is used for, and how it behaves, let's see what one actually looks like:
package com.datavikings.converter;
import javax.jws.WebMethod;
import javax.jws.WebService;
@WebService
public class Converter {
@WebMethod(operationName = "poundsToKilos")
public double poundsToKilos(@WebParam(name = "pounds") double pounds) {
return pounds / 2.2;
}
@WebMethod(operationName = "kilosToPounds")
public double kilosToPounds(@WebParam(name = "kilos") double kilos) {
return kilos * 2.2;
}
}
As you can see from the sample code, the @WebService annotation is used to signal to the container that this is a web service. The publicly accessible methods are decorated with the @WebMethod annotation. The @WebMethod annotation may take a parameter called operationName, which maps the method to a web service operation defined in the WSDL document. The parameters may additionally be dressed up with the @WebParam annotation that takes a name parameter, which would create a customized mapping of the parameter to a WSDL message part. The method signatures are automatically generated by NetBeans when creating a web service and will take care of putting the appropriate annotations in place as well.
NetBeans makes accessing a web service just as easy as creating one. Here is a simple example of a web service client:
package com.datavikings.converterclient;
public class WebServiceClient {
public static void main(String[] args) {
try {
com.datavikings.converter.ConverterService service = new com.datavikings.converter.ConverterService();
com.datavikings.converter.Converter port = service.getConverterPort();
double pounds = 180;
double result = port.poundsToKilos(pounds);
System.out.println(pounds + " pounds = " + result + " kilos");
}
catch (Exception e) {
e.printStackTrace();
}
}
}
The service is instantiated by creating a new object of the type defined by the web service. Remember earlier when we drew an analogy between a web service and a class? Now the analogy isn't just an analogy. The web service “object” reference can be used to create a port. The port is what will be used locally to call the web service operations. You can think of the port as a kind of remote control. When you push a button on your television remote the operation happens remotely as if you had pushed the same button on the television itself. The port is the remote control for the web service.
8.6 Web Services, Session Beans, and State
Web services can be created as part of a web application or an enterprise application. In fact, if you have business logic in a session bean already, you can turn it into a web service with very little work. When creating a new web service in NetBeans, the New Web Service wizard will ask if you want to create a new web service from scratch or from an existing session bean. If you point the wizard to an existing session bean it can automatically create the web service. The reason the conversion is so simple is that, aside from the annotations and some XML, session beans and web services are essentially just regular vanilla Java objects. A session bean can hide its implementation details behind a Java interface and the web service hides its implementation details behind the WSDL file. Once those details are worked out (generating the interface for session beans or the WSDL for web services) the same class can be used for both.