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 1. Listing Items in the Catalog

Figure 2. Item Detail

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
       ...
The Web Service

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.

Creating the Web Service

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:

  1. Open the catalog project in the NetBeans IDE.
  2. Expand the service node in the Project window. You should see ItemJpaController.java in the expanded list, as shown in Figure 3.

    Figure 3. ItemJPAController.java in the Service Node

    Figure 3. ItemJPAController.java in the Service Node

  3. Display the contents of the ItemJPAController class by double-clicking on ItemJPAController.java in the Projects window. Alternatively, you can right-click ItemJPAController.java and select Open.
  4. Add the @WebService annotation above the class declaration displayed in the editor window for ItemJPAController.java, as shown in Figure 4.

    Figure 4. Adding the @WebService Annotation to ItemJPAController

    Figure 4. Adding the @WebService Annotation to ItemJPAController

  5. 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 the javax.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

      Figure 5. Adding the Import for the @WebService Annotation

    • Select the import for javax.ws.WebService.
  6. 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 the catalog project in the Projects window. Expand the Web Services node. You should see an entry for the ItemJPAController 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

    Figure 6. ItemJPAController Web Service in the Web Services Node

  7. 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 the wsgen 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 the ItemJpaController web service has been deployed.

    Figure 7. Deploying the ItemJPAController Web Service

    Figure 7. Deploying the ItemJPAController Web Service

  8. 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

    Figure 8. ItemJPAControllerService Test Page

  9. 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

    Figure 9. WSDL File for ItemJPAControllerService

    Notice that the web service name is ItemJPAControllerService.
  10. 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

    Figure 10. Testing a Web Service Method

Creating the Web Service Client

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:

  1. Open the catalogclient project in the NetBeans IDE.
  2. 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

      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

      Figure 12. Generating Code for the Web Service Client

  3. 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 the client node. You should see three classes: ItemController.java, ItemConverter.java, and ItemJpaController.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 the ItemJpaControllerService web service, as shown in Figure 13.

      Figure 13. Web Service Operations

      Figure 13. Web Service Operations

    • Scroll to the create() method in the editor window for the ItemJpaController class.
    • Using the mouse, drag the create() operation from the Projects window into the editor window for the ItemJpaController class. Drop the operation inside the create() method. As Figure 14 shows, the NetBeans IDE generates the necessary code at the point where you dropped the operation to invoke the create() operation.

      Figure 14. Generating Code to Invoke a Web Service 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 the ItemJpaController class:
           import javax.xml.ws.WebServiceRef;
      
      
           @WebServiceRef(wsdlLocation = "WEB-INF/wsdl/client/ItemJpaControllerService/localhost_8080/catalog/ItemJpaControllerService.wsdl")
           private ItemJpaControllerService service;
        
      
  4. Remove the encapsulating try/ catch block. The create() method should now look like this:
          public void create(service.Item item) throws Exception {
    
                      service.ItemJpaController port = service.getItemJpaControllerPort();
                      port.create(item);
          }
      
    
  5. 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 the findItemEntities(), findItem(), and getItemCount() methods must return a result. So add the line return result; to each of these methods. For example, the findItemEntities() 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;
           }
      
    
  6. 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

    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.

For More Information