Technical Article
GlassFish and MySQL, Part 3: Creating and Using a Web Service
By Ed Ort and Carol McDonald, January 2009
This is the third article in a series of articles on GlassFish and MySQL. Part 1 of the series describes the advantages of using GlassFish with MySQL and illustrates why the combination is a perfect choice for developing and deploying web applications.
Part 2 shows how to develop a create, read, update, and delete (CRUD) web application that uses GlassFish and MySQL. The application uses the Java Persistence API implemented in GlassFish to manage data persistence.
In Part 3, you'll learn how easy it is to convert the controller layer of the web application, that is, the layer of the application that performs the CRUD operations -- into a web service. You'll also learn how to create a client for the web service. As was the case for the web application discussed in Part 2, the web service discussed in Part 3 uses GlassFish, MySQL, and the Java Persistence API.
This article shows you how to use the NetBeans IDE with GlassFish and MySQL to create a web service and client.
This article shows you how to use the NetBeans IDE with GlassFish and MySQL to create the web service and client. Specifically, you'll take advantage of features in NetBeans IDE 6.5, GlassFish v2UR2, and MySQL 5.1 Community Server to build and deploy the web service and client.
If you're not familiar with web services, see the Web Services section. Otherwise, skip to The Updated Application section. You can examine the completed web service and client by downloading and expanding the CatalogService
and CatalogClient
packages.
Web Services
Web services are web-based application components that are widely available for integration into applications. |
Web services are web-based application components that are widely available for integration into applications. An important characteristic of web services is language and platform independence. This means that a web service written in one language for a specific platform can be incorporated into an application written in another language and platform. For example, a Java technology application running in one operating system can incorporate web services written in another language on another operating system. Similarly, web services written in the Java programming language can be incorporated into an application written in another language and platform.
Language and platform independence are possible because web services communicate with clients using standard protocols and technologies. These standards are implemented in platforms and products from all the major software vendors. This widespread support makes it possible for web services to communicate with clients in a consistent way.
Web services are attractive to developers because they provide a relatively easy way of adding function to an application. Developers don't have to code logic in an application to provide the function. Instead, they can simply access the pertinent web service using appropriate protocols and technologies. Web services also give developers a way of exposing application components they create so that the components can be used in many applications.
GlassFish and Web Services
The Metro stack of technologies in GlassFish simplifies developing and using web services and gives you flexibility in the style you use to develop web services. |
GlassFish, an open-source, enterprise-quality, Java EE 5-compliant application server, implements a set of Java technologies that simplify developing and using web services. This set or "stack" of technologies is collectively called Metro. Metro includes core web service technologies such as Java API for XML-Based Web Services (JAX-WS) and Java Architecture for XML Binding (JAXB) that enable you to develop and use web services. In addition, Metro includes technologies such as Web Services Interoperability Technologies (WSIT) that support secure, transactional web services that can interoperate between Java EE and Windows .NET environments. GlassFish also supports the Java API for RESTful Web Services (JAX-RS) and its reference implementation, Jersey.
With this spectrum of support, GlassFish gives you flexibility in the style you use to develop web services. You can use Metro technologies such as JAX-WS to develop and use web services that conform to the SOAP protocol, or you can use JAX-RS to develop and use web services that conform to the Representational State Transfer (REST) architectural style.
This article shows you how to develop a SOAP-based web service using JAX-WS. A future article will show you how to develop a RESTful web service using JAX-RS.
SOAP and JAX-WS
SOAP is an XML-based protocol that enables applications to exchange information over a transport protocol such as HTTP. It is frequently used for accessing web services. In a typical SOAP-based exchange, a client sends a SOAP request to a web service, and the service responds with a SOAP response. The SOAP request typically makes a call to a method exposed by the web service. For example, the following SOAP request calls the sayHello()
method in a service and passes a parameter, Joe
, in the method call:
<?xml version="1.0" encoding="UTF-8"?>
<S:Envelope xmlns:S="sayHello xmlns:ns2="http://helloservice/">
<S:Header/>
<S:Body>
<ns2:sayHello xmlns:ns2="http://service/">
<arg0>Joe</arg0>
</ns2:sayHello>
</S:Body>
</S:Envelope>
The following is an example of a SOAP response to the sayHello()
method call. Here, the response returns the string Hello, Joe
.
<?xml version="1.0" encoding="UTF-8"?>
<S:Envelope xmlns:S="http://schemas.xmlsoap.org/soap/envelope/">
<S:Body>
<ns2:sayHelloResponse xmlns:ns2="http://helloservice/">
<return>Hello, Joe.</return>
</ns2:sayHelloResponse>
</S:Body>
</S:Envelope>
For this exchange to happen, a number of additional actions must take place. For example, when the client makes a request, the request must be translated or serialized into a SOAP request. The SOAP request then must be encoded into a format compatible with the selected transport protocol such as HTTP. The encoded request is then sent to a target server. Additional processing such as decoding and deserialization happens in the target server before the web service can handle the request at a service endpoint.
The processing of the response from the web service to the client is equally complex.
JAX-WS handles the complexity that underlies SOAP exchanges. |
Fortunately, you don't have to handle the complexity that underlies SOAP exchanges. Instead, you can use JAX-WS to handle this processing for you. The current version of JAX-WS, JAX-WS 2.0, is an important part of the Java EE 5 platform. JAX-WS 2.0 simplifies the task of developing web services that use Java technology. It supports multiple protocols, such as SOAP 1.1, SOAP 1.2, XML, and HTTP; and provides a facility for supporting additional protocols. JAX-WS 2.0 uses JAXB 2.0 for binding XML schema -- a description of the structure and content of an XML document -- to a representation in Java code. With JAXB 2.0, you can easily incorporate XML data and processing functions in applications based on Java technology without having to know much about XML itself.
Developing a Web Service Using JAX-WS: There are two ways of developing a web service using JAX-WS. One way is based on the Java class programming model -- here, you create a web service that is implemented by a Java class that runs in a web container. The other way is based on the Enterprise JavaBeans (EJB) programming model -- here, you implement the web service as a stateless session bean that runs in an EJB container. This article shows you how to develop a web service using JAX-WS from a Java class.
Here, for example, is a web service implementation based on a Java class:
package helloservice;
import javax.jws.WebService;
@WebService()
public class Hello {
private String message = new String("Hello, ");
public void Hello() {}
@WebMethod()
public String sayHello(String name) {
return message + name + ".";
}
}
Using web service annotations in classes enables you to code these objects as Plain Old Java Objects (POJOs) and reduces the amount of code and configuration data you must write. |
The @WebService()
annotation in the web service implementation marks the Hello
class as a web service, and the @WebMethod()
annotation exposes the sayHello()
method as a web service method.
After you create and compile the web service implementation, you generate portable artifacts for web service execution. One of the artifacts is a Web Service Definition Language (WSDL) file that contains an XML description of the web service. The description includes information such as the endpoint address of the web service and the operations that the web service performs.
Here is part of the WSDL file for the HelloService
web service.
<definitions targetNamespace="http://endpoint.helloservice/"
name="HelloService">
...
<message name="sayHello">
<part name="parameters" element="tns:sayHello"/>
</message>
<message name="sayHelloResponse">
<part name="parameters" element="tns:sayHelloResponse"/>
</message>
<portType name="Hello">
<operation name="sayHello">
<input message="tns:sayHello"/>
<output message="tns:sayHelloResponse"/>
</operation>
</portType>
...
<service name="HelloService">
...
<port name="HelloPort" binding="tns:HelloPortBinding">
<soap:address location="http://localhost:8080/helloservice/hello"/>
</port>
</service>
</definitions>
The JAX-WS implementation in GlassFish includes a utility program called wsgen
to generate the portable artifacts and expose the WSDL file.
You then package and deploy the service. You can package a web service as a servlet or as a stateless session bean.
Developing a Web Service Client Using JAX-WS: A web service is available for access after you generate and expose its WSDL file and deploy the service. Anyone can then access the web service by creating a client based on the WSDL for the service.
Here is an example of a web service client:
package client;
import javax.xml.ws.WebServiceRef;
import helloservice.HelloService;
import helloservice.Hello;
public class HelloClient {
@WebServiceRef(wsdlLocation="http://localhost:8080/helloservice/hello?wsdl")
static HelloService service;
public static void main(String[] args) {
try {
HelloClient client = new HelloClient();
client.doTest(args);
} catch(Exception e) {
e.printStackTrace();
}
}
public void doTest(String[] args) {
try {
System.out.println("Retrieving the port from the following service: " + service);
Hello port = service.getHelloPort();
System.out.println("Invoking the sayHello operation on the port.");
String name;
if (args.length > 0) {
name = args[0];
} else {
name = "No Name";
}
String response = port.sayHello(name);
System.out.println(response);
} catch(Exception e) {
e.printStackTrace();
}
}
}
The @WebServiceRef
annotation in the client declares a reference to a web service. The value of the wsdlLocation
parameter in the @WebServiceRef
annotation is a URL pointing to the location of the WSDL file for the service being referenced.
In this example, the client retrieves the endpoint Hello
from the HelloService
service using port information in the WSDL file. After it retrieves the endpoint, the client invokes the sayHello()
method in the HelloService
service.
As is the case for a web service, portable artifacts must be generated for a web service client. The JAX-WS implementation in GlassFish includes a utility program called wsimport
to generate the portable artifacts for a web service client.
After you generate the artifacts, you build the client by compiling the client class and its artifacts.
REST and JAX-RS
Representational State Transfer (REST) is a style of software architecture. An important concept in REST is the existence of resources, each of which can be referred to using a global identifier, that is, a URI. In order to manipulate these resources, clients and servers communicate using a standardized interface such as HTTP and exchange representations of these resources.
RESTful web services are services built using the REST architectural style. Building web services using the RESTful approach is emerging as a popular alternative to using SOAP-based technologies, due to REST's lightweight nature and the ability to transmit data directly over HTTP.
JAX-RS provides a standardized API for Java developers to build RESTful web services, a popular alternative to SOAP-based web services. |
JAX-RS provides a standardized API for Java developers to build RESTful web services. The API basically provides a set of annotations and associated classes and interfaces. Applying the annotations to POJOs enables you to expose web resources.
Here, for example, is a class that uses JAX-RS annotations to expose a resource that represents a simple message:
package restservice;
import javax.ws.rs.GET;
import javax.ws.rs.Path;
import javax.ws.rs.Produces;
@Path("/myresource")
public class MyResource {
@GET
@Produces("text/plain")
public String getIt() {
return "Got it!";
}
}
The @Path
annotation identifies the URI path for which the MyResource
class will serve requests. The @GET
annotation indicates that the getIt()
method responds to HTTP GET
requests. The @Produces
annotation indicates that the getIt()
method returns plain text.
To communicate with a resource in REST, you specify its URI and one of the following HTTP methods: GET
, PUT
, POST
, DELETE
.
In the next article in this series, you'll learn more about REST and see an example of a web service and client that use JAX-RS.
The Updated Application
The web application discussed in this article is an updated version of the pet catalog application discussed in Part 2. The updated pet catalog application allows users to access an online catalog of pets. Users can do some of the same things that they could do using the initial version of the application. They can list and display the items in the catalog, as shown in Figure 1, and then display information about a selected item as shown in Figure 2. However, to simplify things, the updated pet catalog application reduces the number features that the initial version of the application offers. Recall that the initial version of the pet catalog application allows the user to search the catalog using additional criteria: by category, for example, dogs; or by product type, for example, medium dogs.
Figure 1. Listing Items in the Catalog
Figure 2. Item Detail
Notice that the updated application allows users to create a new item and add it to the catalog, edit an entry, or delete an entry.
Inside the Updated Application
Here are the major changes in the updated pet catalog application:
- The database schema and content of the catalog are simplified to contain only an
item
table. - The model is simplified to contain only
item
entities. - The controller layer and view layer are replaced by a web service and web service client.
Let's examine each of these changes. You can view the code by downloading and expanding the CatalogService
and CatalogClient
packages.
The Catalog
As was the case in the initial version of the pet catalog application, the catalog is contained in a MySQL database named petcatalog
. Recall that the petcatalog
database in the initial version of the application has four tables: category
, product
, item
, and address
. The catalog used in the updated version of the application has been simplified to contain one item
table. In addition, the schema and content of the item
table is slightly changed. For each item, the table contains an identification (ID) number, product ID, name, description, URL of the item's image, URL of the item's thumbnail image, and price.
Table 1 shows two rows in the item
table.
Table 1: The item
Table
id | productid | name | description | imageurl | imagethumburl | price |
---|---|---|---|---|---|---|
1 | feline01 | Friendly Cat | This black and white colored cat is super friendly. Anyone passing by your front yard will find him purring at their feet and trying to make a new friend. His name is Anthony, but I call him Ant as a nickname since he loves to eat ants and other insects. | http://localhost:8080/catalog/images/anthony.jpg | http://localhost:8080/catalog/images/anthony-s.jpg | 307.10 |
2 | feline02 | Fluffy Cat | A great pet for a hair stylist! Have fun combing Bailey's silver mane. Maybe trim his whiskers? He is very patient and loves to be pampered. | http://localhost:8080/catalog/images/bailey.jpg | http://localhost:8080/catalog/images/bailey-s.jpg | 307.00 |
When you expand CatalogService
, you will see a directory named catalog
. Find a file named catalog.sql
in the catalog
directory. The file contains the SQL statements that create the updated item
table and fill it with data.
The Model
Navigate to the catalog/src/java/model
directory. The content of this directory represents the model for the updated application. Notice that the model has only on entity class: Item
, which represents the item table in the petcatalog
database. The initial version of the application contains additional entity classes for the Address
, Category
, and Product
tables in the petcatalog
database. An instance of the Item
entity represents a row of data in the item
table.
Here is part of the source code for the Item
class:
package model;
import java.io.Serializable;
...
@Entity
@Table(name = "item")
...
public class Item implements Serializable {
private static final long serialVersionUID = 1L;
@Id
@Basic(optional = false)
@Column(name = "id")
private Integer id;
@Column(name = "productid")
private String productid;
@Column(name = "name")
private String name;
@Column(name = "description")
private String description;
@Column(name = "imageurl")
private String imageurl;
@Column(name = "imagethumburl")
private String imagethumburl;
@Column(name = "price")
private BigDecimal price;
...
//getters and setters
...
Navigate to the catalog/src/java/service
directory. You will see a class in that directory named ItemJpaController
. This is the web service for the application. If you compare the contents of the ItemJpaController
web service and the contents of the ItemJpaController
class in the controller layer of the initial version of the application, you will see that their contents are similar. Both classes use the Java Persistence API to handle operations for the Item
entity class, such as creating and editing instances of the entity class. For example, here is part of the create
method in the ItemJpaController
web service that creates an instance of the Item
entity class:
public void create(Item item) throws PreexistingEntityException, RollbackFailureException, Exception {
EntityManager em = null;
try {
utx.begin();
em = getEntityManager();
em.persist(item);
utx.commit();
...
The significant difference between the initial ItemJpaController
class and the web service is that the web service contains the @WebService
annotation, as follows:
@WebService
public class ItemJpaController {
...
The @WebService
annotation marks the class as a web service and tells the Java interpreter that the methods of this class are intended to be published as web service methods.
The Client
The expanded CatalogClient
download contains the code for the web service client, the controller and converter files, as well as the view layer of the application.
Web Service Client: The web service client accesses the ItemJpaControllerService
web service. When you expand CatalogClient
, you will see a directory named catalogclient
. Navigate to the catalogclient/src/java/client
directory. You will see a class in that directory named ItemJpaController
. It is the client for the ItemJpaControllerService
web service. Here is some of the code in the ItemJpaController
class.
package client;
import java.util.List;
import javax.xml.ws.WebServiceRef;
import service.Item;
import service.ItemJpaControllerService;
public class ItemJpaController {
@WebServiceRef(wsdlLocation = "WEB-INF/wsdl/client/ItemJpaControllerService/localhost_8080/catalog/ItemJpaControllerService.wsdl")
private ItemJpaControllerService service;
public List<Item> findItemEntities() {
service.ItemJpaController port = service.getItemJpaControllerPort();
java.util.List<service.Item> result = port.findAllItemEntities();
System.out.println("Result = "+ result);
return result;
}
}
In this code snippet, ItemJpaController
uses the @WebServiceRef
annotation to obtain a reference to the JAX-WS proxy factory class for the ItemJpaControllerService
web service. The value of the wsdlLocation
parameter in the @WebServiceRef
annotation is a URL pointing to the location of the WSDL file for the service. The JAX-WS factory class is a portable client artifact generated from the service's WSDL file by the wsimport
tool.
The ItemJpaController
class retrieves a proxy to the service by calling getItemJpaControllerPort()
on ItemJpaControllerService
. The proxy implements the service endpoint interface defined by ItemJpaControllerService
. The ItemJpaController
class can then invoke the port's findItemEntities()
method. The dynamic proxy and JAXB classes -- additional generated artifacts -- convert the web service method call into a SOAP request and send it to the web service's endpoint. The dynamic proxy and JAXB classes also receive the SOAP response and transform it into the return object of the class method, whose type in this case is List<Item>
.
Controller: The ItemController
class in the catalogclient/src/java/client
directory is the controller class for the Item
entity class. It invokes methods in the ItemJpaController
web service to perform operations for the Item
entity class, such as creating and editing an instance of the entity class.
For example, the following method in the ItemController
class invokes the create()
method in the ItemJpaController
class to create an instance of the Item
class:
private ItemJpaController jpaController = null;
public String create() {
try {
jpaController.create(item);
JsfUtil.addSuccessMessage("Item was successfully created.");
} catch (Exception e) {
JsfUtil.ensureAddErrorMessage(e, "A persistence error occurred.");
return null;
}
return listSetup();
}
Converter: The ItemConverter
class is the converter class for the Item
class. For example, the following method in the ItemConverter
class converts an instance of the Item
class to a String
object:
public Object getAsObject(FacesContext facesContext, UIComponent component, String string) {
if (string == null || string.length() == 0) {
return null;
}
Long id = new Long(string);
ItemJpaController controller = (ItemJpaController) facesContext.getApplication().getELResolver().getValue(facesContext.getELContext(), null, "itemJpa");
return controller.findItem(id);
}
View: Recall that the view layer of a web application uses data from domain objects provided by the controller to generate a web page. As is the case in the initial version of the application, the view is rendered in the application using JavaServer Pages (JSP) technology and JavaServer Faces technology. JSP enables the dynamic content required by the application, and JavaServer Faces technology provides UI components for the application. These are only two of a number of Java EE web technologies supported by GlassFish that provide simple, consistent mechanisms for extending web applications beyond static web pages.
Navigate to the catalogclient/web/item
directory. You'll see a file named List.jsp
. This file is the JSP page that displays the items in the catalog, as shown in Figure 1.
Here is part of the code in List.jsp
:
<%@taglib uri="#" prefix="f" %>
<%@taglib uri="#" prefix="h" %>
<f:view>
<html>
...
<body>
<h:panelGroup id="messagePanel" layout="block">
<h:messages errorStyle="color: red" infoStyle="color: green" layout="table"/>
</h:panelGroup>
<h1>Listing Item Items</h1>
<h:form styleClass="jsfcrud_list_form">
...
<h:dataTable value="#{item.itemItems}" var="item1" border="0" cellpadding="2" cellspacing="0" rowClasses="jsfcrud_odd_row,jsfcrud_even_row" rules="all" style="border:solid 1px">
<h:column>
<f:facet name="header">
<h:outputText value="Name"/>
</f:facet>
<h:outputText value=" #{item1.name}"/>
</h:column>
...
The tags that begin with f
or h
are JavaServer Faces technology tags. Notice especially the dataTable
tag. This tag is used to create a table and render it on the page. The tag is useful when you want to show a set of results in a table format. In an application that uses JavaServer Faces technology, the UIData
component, the superclass of dataTable
, supports binding to a collection of data objects. It does the work of iterating over each record in the data source -- in this case, the catalog. The HTML renderer for dataTable
displays the data as an HTML table.
The value
attribute of the dataTable
tag references the data to be included in the table. The var
attribute specifies a name that is used by the components within the dataTable
tag as an alias to the data referenced in the value
attribute. Here, the value
attribute points to a list of items in the item
table in the catalog. The var
attribute points to a single item in that list. As the UIData
component iterates through the list, each reference to item1
points to the current item in the list.
Note that the value
attribute of the dataTable
tag is bound to the item
property of the ItemController
. The ItemController
class is also defined as a managed bean class in the faces-config.xml
file, as follows:
<managed-bean>
<managed-bean-name>item</managed-bean-name>
<managed-bean-class>client.ItemController</managed-bean-class>
<managed-bean-scope>session</managed-bean-scope>
</managed-bean>
You can find the faces-config.xml
file in the catalogclient/web/WEB-INF
directory.
Defining ItemController
as a managed bean class allows you to use the managed bean name in JavaServer Faces expression language statements such as #{item.itemItems}
. When this expression is used in the dataTable
tag, it binds the UI component to the itemItems
property in the item
bean. The itemItems
property represents the list of items that are returned by the getItemItems()
method in the ItemController
, as shown here:
public List<Item>getItemItems() {
if (itemItems == null) {
getPagingInfo();
itemItems = jpaController.findItemEntities(pagingInfo.getBatchSize(), pagingInfo.getFirstItem());
}
return itemItems;
}
In JavaServer Faces technology, the dataTable
component supports data binding to a collection of data objects. The data collection is modeled as a collection of row objects that can be accessed by a row index. The APIs provide mechanisms to position to a specified row index and to retrieve an object that represents the data that corresponds to the current row index.
Notice in the List.jsp
file that the name, photo, and price of each item -- as well as show, edit, and destroy action links -- are displayed with JavaServer Faces technology column
tags. The column
tags represent columns of data in a UIData
component. While the UIData
component iterates over the rows of data, it processes the UIColumn
component associated with each column
tag for each row in the table. The UIData
component iterates through the list of items, product.productItems
, and displays the names, photos, and prices. Each time UIData
iterates through the list of items, it renders one cell in each column.
The dataTable
and column
tags use facet
tags to represent parts of the table that are not repeated or updated. These include headers, footers, and captions.
How the Updated Application Was Built
This article does not detail the steps in building the updated application. In general, the pet catalog application discussed in Part 2 was split into two parts: a catalog
project, which provides the web service methods to create, get, update, delete, or list catalog items, and a catalogclient
project, which calls the web service methods and displays the results using JavaServer Faces technology. The updated application is complete and executable. However, before you run it, remember to use the catalog.sql
file in the CatalogService
to create the item
table and fill it with data.
This article focuses on how the web service and web service client for the updated application were created.
The ItemJpaController
class in the catalog
project uses the Java Persistence API to retrieve a list of items from the catalog. Here are the steps that were followed to make the class a web service:
- Open the
catalog
project in the NetBeans IDE. - Expand the
service
node in the Project window. You should seeItemJpaController.java
in the expanded list, as shown in Figure 3.Figure 3. ItemJPAController.java in the Service Node
- Display the contents of the
ItemJPAController
class by double-clicking onItemJPAController.java
in the Projects window. Alternatively, you can right-clickItemJPAController.java
and select Open. - Add the
@WebService
annotation above the class declaration displayed in the editor window forItemJPAController.java
, as shown in Figure 4.Figure 4. Adding the @WebService Annotation to ItemJPAController
- Notice the error indicator in the margin to the left of the
@WebService
annotation in Figure 4. It's there because the NetBeans IDE cannot resolve the annotation. To fix this error, you must import thejavax.ws.WebService
package, as follows:- Click on the error indicator. This displays two possible selections as shown in Figure 5.
Figure 5. Adding the Import for the @WebService Annotation
- Select the import for
javax.ws.WebService
.
- Click on the error indicator. This displays two possible selections as shown in Figure 5.
- Build the web service by right-clicking on the
catalog
project in the Projects window and selecting Clean and Build. In response, the NetBeans IDE creates a number of directories and files, one of which is a web archive (war) file for the project. You should also see a Web Services node for thecatalog
project in the Projects window. Expand the Web Services node. You should see an entry for theItemJPAController
web service, and beneath it in the node hierarchy, its web service methods. This is shown in Figure 6.Figure 6. ItemJPAController Web Service in the Web Services Node
- Deploy the web service by right-clicking on the
catalog
project in the Projects window and selecting Run. In response, the NetBeans IDE starts the application server, runs thewsgen
utility to generate portable artifacts for web service execution, deploys the application, and opens a browser window that displays "Hello World!" As shown in Figure 7, the GlassFish V2 tab in the NetBeans IDE output window should indicate that theItemJpaController
web service has been deployed.Figure 7. Deploying the ItemJPAController Web Service
- Test the web service by right-clicking on the
ItemJPAController
web service in the Web Services node and selecting Test Web Service. In response, the NetBeans IDE opens a tester page for the web service as shown in Figure 8.Figure 8. ItemJPAControllerService Test Page
- Click on the WSDL File link in the tester page to see the WSDL file for the web service. Figure 9 shows some of the WSDL file.
Figure 9. WSDL File for ItemJPAControllerService
Notice that the web service name isItemJPAControllerService
. - Invoke one of the operations. For example, enter a number such as 10 in the parameter input box next to the
findItem
button and then click the button. In response, you should see a page that displays information about the invocation including the method returned, SOAP request, and SOAP response. This is shown in Figure 10.Figure 10. Testing a Web Service Method
The catalogclient
project uses the WSDL file from the ItemJpaControllerService
web service to generate a client for the service. Here are the steps that were followed to create the web service client:
- Open the
catalogclient
project in the NetBeans IDE. - Create a web service client as follows:
- Right-click on the
catalogclient
project in the Projects window. - Select New, then Web Service Client. This opens the New Web Service Client dialog box.
- Click the WSDL URL radio button and enter the URL of the WSDL file for the
ItemJpaControllerService
web service,http://localhost:8080/catalog/ItemJpaControllerService?wsdl
, as shown in Figure 11.Figure 11. Creating a Web Service Client
- Click the Finish button. In response, the NetBeans IDE retrieves the WSDL service description of the web service and runs the
wsimport
utility to generate the portable artifacts for the web service client. You can see this in the NetBeans IDE output window, as shown in Figure 12.Figure 12. Generating Code for the Web Service Client
- Right-click on the
- Replace the method calls with calls to operations in the referenced web service, as follows:
- Expand the
catalogclient
node in the Projects window, then the Source Packages node, then theclient
node. You should see three classes:ItemController.java
,ItemConverter.java
, andItemJpaController.java
. - Open the
ItemJpaController.java
class. - Expand the Web Service References node for the
catalogclient
project in the Projects window. Then expand the nodes beneath it in the hierarchy until you see the list of operations in theItemJpaControllerService
web service, as shown in Figure 13.Figure 13. Web Service Operations
- Scroll to the
create()
method in the editor window for theItemJpaController
class. - Using the mouse, drag the
create()
operation from the Projects window into the editor window for theItemJpaController
class. Drop the operation inside thecreate()
method. As Figure 14 shows, the NetBeans IDE generates the necessary code at the point where you dropped the operation to invoke thecreate()
operation.Figure 14. Generating Code to Invoke a Web Service Operation
Notice that the NetBeans IDE adds the following@WebServiceRef
annotation, instance variable, and import when you drag the web service operation into theItemJpaController
class:import javax.xml.ws.WebServiceRef; @WebServiceRef(wsdlLocation = "WEB-INF/wsdl/client/ItemJpaControllerService/localhost_8080/catalog/ItemJpaControllerService.wsdl") private ItemJpaControllerService service;
- Expand the
- Remove the encapsulating
try
/catch
block. Thecreate()
method should now look like this:public void create(service.Item item) throws Exception { service.ItemJpaController port = service.getItemJpaControllerPort(); port.create(item); }
- Perform similar drag-and-drop operations to generate the code to invoke the operations for the other method calls in the
ItemJpaController
class. Note that thefindItemEntities()
,findItem()
, andgetItemCount()
methods must return a result. So add the linereturn result;
to each of these methods. For example, thefindItemEntities()
method should look like this:public List<Item> findItemEntities() { service.ItemJpaController port = service.getItemJpaControllerPort(); java.util.List<service.Item> result = port.findAllItemEntities(); System.out.println("Result = " + result); return result; }
- Run the web service client by right-clicking on the
catalogclient
project in the Projects window and selecting Run. The NetBeans IDE compiles the web service client, deploys it to the GlassFish application server, and opens a new window in your web browser with the home page of the application,http://localhost:8080/catalogclient/
, as shown in Figure 15.Figure 15. Application Home Page
Click the "Show All Item Items" link. You should see a list of the items in the catalog, as shown in Figure 1.
Summary
This article showed you how to convert a Java Persistence API controller class in a web application to a SOAP-based web service that uses JAX-WS. GlassFish implements JAX-WS and other Java technologies that simplify developing and using web services. In addition, GlassFish has a built-in persistence manager, the Java Persistence API, and supports ease-of-use features such as annotations. These capabilities, combined with the simplicity of querying and manipulating MySQL databases, make it easy to build a web service that accesses a MySQL database with data persistence. It also makes it easy to create web applications that access web services. The NetBeans IDE, which integrates MySQL and GlassFish, includes features that make it even easier to build web services and web applications that use web services.
In the next article in this series, you'll see how to develop a RESTful web service using JAX-RS.