The Source for Java Technology Collaboration
User: Password:
Register | Login help    

Search

Online Books:
java.net on MarkMail:


Sample Application using JAX-WS, JSF, EJB 3.0, and Java

Posted by caroljmcdonald on September 18, 2007 at 8:43 PM PDT

Sample Application using JAX-WS, JSF, EJB 3.0, and Java Persistence APIs on Glassfish

eBay and Amazon provide Web Services APIs for developers who want to provide access to these services in their web site. This Sample Store Catalog application shows how to expose a  Service as a Web Service for remote client applications (this example was not modeled after the eBay or Amazon APIs).

This example demonstrates a Catalog Stateless Session Bean, and the Java Persistence APIs to implement Catalog Service which provides pagination of store items,  and JAX-WS to expose this Catalog Service as a Web Service. A separate example JSF JAX-WS client shows how this Catalog Web Service can then be used remotely in a sample Store web site.   I took this example  Pagination of Data Sets in a Sample Application using JSF, Catalog Facade Stateless Session, and Java Persistence APIs and modified the Catalog Session Bean to expose its public methods as Web Services, then I put the JSF Store UI in a separate Web Application and modified it to use JAX-WS to call the Catalog Web Services.

Download the Sample Application Code

Explanation of the usage of  JAX-WS,  JSF, EJB 3.0, and Java Persistence APIs in a sample Store Catalog Application

The image below shows the Catalog Listing page, which allows a user to page through a list of items in a store.

listpage.jpg


Explanation of the Catalog Web Service which uses JAX-WS, JPA, and EJB 3.0

The Catalog Session EJB  uses a JPA EntityManager Query object to return a list of items. With the @PersistenceContext annotation, the CatalogBean uses dependency injection to lookup and obtain a Container Managed EntityManager .  The @Stateless annotation marks this class as a Stateless Session EJB. The @WebService annotation marks this class as a web service, and causes any public methods to be exposed as Web Services.  The example JSF Web Service client uses the Catalog Web Service getItems method to get the Items for displaying on the Web Store UI .   (Note: Red colors are for Java EE tags, annotations code,  and Green for my code or variables)

Code Sample from: Catalog.java

  
@WebService
   @Stateless
   public class Catalog implements CatalogService {

   @PersistenceContext(unitName="PetCatalogPu")
   private EntityManager em;
 
   @TransactionAttribute(TransactionAttributeType.NOT_SUPPORTED)
   public List<Item> getItems(int firstItem,int batchSize) {
        Query q = em.createQuery("select object(o) from Item as o");
        q.setMaxResults(batchSize);
        q.setFirstResult(firstItem);
        List<Item> items= q.getResultList();
        return items;
   }
   



The code below shows the Item entity class which maps to the  ITEM table that stores the item instances. This is a typical Java Persistence entity object.  For more information on this code see this previous blog.

Code Sample from: Item.java

@Entity

public class Item implements java.io.Serializable {

   
@Id  
    private String itemID;

    private String name;   
    private String description;   
    private String imageurl;    
    private BigDecimal price;
    @OneToOne(cascade={CascadeType.PERSIST})
    private Address address;
    @ManyToOne
    private Product product;

    
    public Item() { }
     
    public String getItemID() {
        return itemID;
    }

    public void setItemID(String itemID) {
        this.itemID = itemID;
    }

    // getters and setters for other item attributes
    ...
}   



When this application is deployed,  the JAXB,  JAX-WS, and WSDL files needed for the Service will be generated on the server. You can access the Catalog WSDL contract at this URL: http://host:8080/CatalogService/Catalog?wsdl .  Below is part of the WSDL, you can see that the Catalog class name defaults to the portType name and the getItems method name defaults to the operation name (defaults can be changed using annotations, see the Java EE tutorial for more information).


Code Sample from: CatalogService.wsdl

<portType name="Catalog">
    <operation name="getItems">
       <input message="tns:getItems"/>
       <output message="tns:getItemsResponse"/>
    </operation>
</portType>
...
  <service name="CatalogService">
    <port name="CatalogPort" binding="tns:CatalogPortBinding">
      <soap:address location="http://host:8080/CatalogService/Catalog" />
    </port>
  </service>


Here is part of the generated xml Schema for the WSDL getItems response message:


Code Sample from: CatalogService.xsd

<xs:complexType name="getItemsResponse">
    <xs:sequence>
      <xs:element name="return" type="tns:item" />
    </xs:sequence>
  </xs:complexType>

  <xs:complexType name="item">
    <xs:sequence>
      <xs:element name="address" type="tns:address" minOccurs="0"/>
      <xs:element name="contactinfo" type="tns:sellercontactinfo" minOccurs="0"/>
      <xs:element name="description" type="xs:string" minOccurs="0"/>
      <xs:element name="disabled" type="xs:int"/>
      <xs:element name="imagethumburl" type="xs:string" minOccurs="0"/>
      <xs:element name="imageurl" type="xs:string" minOccurs="0"/>
      <xs:element name="itemid" type="xs:string" minOccurs="0"/>
      <xs:element name="name" type="xs:string" minOccurs="0"/>
      <xs:element name="numberofvotes" type="xs:int"/>
      <xs:element name="price" type="xs:decimal" minOccurs="0"/>
      <xs:element name="product" type="tns:product" minOccurs="0"/>
      <xs:element name="totalscore" type="xs:int"/>
    </xs:sequence>
  </xs:complexType>



and the corresponding generated JAXB class:

Code Sample from: GetItemResponse.java

@XmlRootElement(name = "getItemResponse")
@XmlType(name = "getItemResponse")
public class GetItemResponse {

    @XmlElement(name = "return")
    private Item _return;

    public Item getReturn() {
        return this._return;
    }

    public void setReturn(Item _return) {
        this._return = _return;
    }
   
...
}


JAX-WS delegates all data binding functionality to JAXB 2.0:
jaxb.gif.gif

After deployment on Glassfish you can access a web client tester application provided by the Glassfish Application Server at the  URL for the Web Service followed by "?Tester"  for example :  http://host:8080/CatalogService/Catalog?Tester. Below is the Web Service Tester interface for the CatalogService. It provides an easy way to call the Web Service operations from a browser.

testws.jpg

Here is an example soap request and response for the getItems WebService operation:

SOAP Request


<?xml version="1.0" encoding="UTF-8"?>
<S:Envelope xmlns:S="http://schemas.xmlsoap.org/soap/envelope/">
<S:Header/>
<S:Body>
<ns2:getItems xmlns:ns2="http://model.sessionpagination/">
<arg0>0</arg0>
<arg1>2</arg1>
</ns2:getItems>
</S:Body>
</S:Envelope>

SOAP Response


<?xml version="1.0" encoding="UTF-8"?>
<S:Envelope xmlns:S="http://schemas.xmlsoap.org/soap/envelope/">
<S:Body>
<ns2:getItemsResponse xmlns:ns2="http://model.sessionpagination/">
<return>
<address>
<addressid>1</addressid>
<city>Mountain View</city>
<latitude>37.3857400000</latitude>
<longitude>-122.0839730000</longitude>
<state>CA</state>
<street1>Castro St</street1>
<street2/>
<zip>94040</zip>
</address>
<contactinfo>
<contactinfoid>1</contactinfoid>
<email>abc@abc.xyz</email>
<firstname>Sean</firstname>
<lastname>Brydon</lastname>
</contactinfo>
<description>super friendly</description>
<itemid>1</itemid>
<name>Friendly Cat</name>
<numberofvotes>3</numberofvotes>
<price>307.10</price>
<product>
<category>
<categoryid>CATS</categoryid>
<description>Loving and finicky friends</description>
<name>Cats</name>
</category>
<description>Great for reducing mouse populations</description>
<name>Hairy Cat</name>
<productid>feline01</productid>
</product>
<totalscore>15</totalscore>
</return>
<return>
<address>
...
</address>
<contactinfo>
...
</contactinfo>
<itemid>2</itemid>
<name>Fluffy Cat</name>
<product>
<category>
<categoryid>CATS</categoryid>
...
</category>
<name>Hairy Cat</name>
<productid>feline01</productid>
</product>
</return>
</ns2:getItemsResponse>
</S:Body>
</S:Envelope>


Explanation of the JSF Store UI which uses JAX-WS to call the Catalog Web Service.

The JSF Store UI is a separate web application which is a JAX-WS client.

jaxws-ClientService.gif


The List.jsp page uses a JSF dataTable component to display a list of catalog items. The dataTable component is useful when you want to show a set of results in a table.

In the List.jsp web page the dataTable is defined as shown below:

Code Sample from:  List.jsp

<h:dataTable value='#{item.items}' var='dataTableItem' border="1"
      cellpadding="2" cellspacing="0">


The value attribute of a dataTable tag references the data to be included in the table. The var attribute points to a single item in that list. As the dataTable JSF component iterates through the list, each reference to dataTableItem points to the current item in the list.

The dataTable's value is bound to the items property of the ItemController managed-bean  class, which is defined in the faces-config.xml


Code Sample from: faces-context.xml

 <managed-bean>
    <managed-bean-name>item</managed-bean-name>
      <managed-bean-class>
         sessionpagination.ItemController
      </managed-bean-class>
    <managed-bean-scope>session</managed-bean-scope>
 </managed-bean>


This ItemController ManagedBean items property is defined as shown below (the blue color highlights the JAX-WS dynamic proxy classes and methods):

Code Sample from: ItemController.java

 public class ItemController {

  @WebServiceRef(wsdlLocation = "http://localhost:8080/CatalogService/Catalog?wsdl")
  private CatalogService service;


  public DataModel getItems() {
      if (model==null  || index != firstItem){
          model=getNextItems();
      }
      return this.model;
  }
  public DataModel getNextItems() {
      Catalog port = service.getCatalogPort();
      model = new ListDataModel(port.getItems( firstItem,batchSize));
      return model;
  }


The ItemController ManagedBean uses dependency injection to obtain a reference to the CatalogService JAX-WS proxy factory class, which is generated from the Catalog WSDL file using the wsimport utility. (To see how to do this easily with Netbeans see the  Netbeans Web Services (JAX-WS) in Java EE 5 tutorial). The ItemController retrieves a proxy to the service by calling getCatalogPort() on the CatalogService, which returns the Catalog Service Endpoint Interface.  The proxy implements the Catalog Service Endpoint Interface defined by the Catalog service. The ItemController can then invoke the port’s getItems method.  The dynamic proxy and jaxb classes convert the WS method into a SOAP request and send it to the Web service's endpoint,  receive the SOAP response, and transform the SOAP response into the java method's return object which in this case is a List<Item>.

The getItems() method wraps a List of items, returned from the Catalog Service,  in a DataModel.   The dataTable JSF component supports data binding to a collection of data objects represented by a DataModel instance.  The data collection underlying a DataModel instance 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.   

The Name, Photo, and Price item properties are displayed  with the JSF column component:

Code Sample from: List.jsp

  <h:column>
      <f:facet name="header">
          <h:outputText value="Price"/>
      </f:facet>
      <h:outputText value="#{dataTableItem.price}"/>
  </h:column>


The column tags represent columns of data in a dataTable. The dataTable JSF  component  iterates through the list of items (item.items) each time rendering one cell in each column and displaying  the item name, photo, and price.

For more information on the JSF part of this code see this previous blog.


Conclusion

The sample Store Catalog application demonstrates how to expose  EJB 3.0  Stateless Session EJB methods which use  the Java Persistence APIs as a Web Service operations using JAX-WS.
The sample JSF Store UI application  demonstrates how to use  the JSF dataTable and DataModel to page through a list of  Items which are retrieved from the Catalog Service using JAX-WS.


Running the Sample Application on Glassfish:

  • Download and install GlassFish V2, following the instructions on the download page. Alternatively you can use Sun Java System Application Server PE 9, Sun's GlassFish distribution.
  • Download and install NetBeans 5.5.1
  • Download the Sample Application Code
  • install Glassfish and Netbeans 5.5.1.  Then add the glassfish application server to Netbeans.

To Open and Test Run the sessionpagination Project:

  • Open the Netbeans sessionpagination project: In Netbeans under File Open Project... go to the directory where you unzipped the sample and select the sessionpagination project.
  • If you get a message that says unresolved references, right click on the project and select Resolve Reference Problems. Use the Resolve Reference Problems dialog to map the ejb and web modules to their project, which are subdirectories beneath the sessionpagination directory.
  • After the references are resolved, right-click the sessionpagination project and select Open Required Projects.
  • If the web module says unresolved references, right-click the sessionpagination-Web module and select Resolve Reference Problems:
  • Browse to the sessionpagination-ejb directory which is a sub-directory below the sessionpagination directory and select Open Project Folder.
  • If you don't have any resolve reference problems errors then ignore those steps.
  • Starts the application server, or at least connect to the database, because the run script for this application will also create the database tables, and this will fail if the database is not started.
  • Right-click the project node and choose Run Project.
    The Netbeans IDE starts the application server, builds the application, and opens the web context page in your browser. This application also has a local JSF client in the war of the application which will be displayed.
  • To go to the web client Tester application provided by the Glassfish Application Server use the url :  http://host:8080/CatalogService/Catalog?Tester. You should see the tester page. For the getItems operation type in integer the integers 0, 5 as input and click on the getItems button. This will return a list of  items 0 through 5.

To Open and Test Run the sessionpagination-wsclient Project:

  • Open the Netbeans sessionpagination-wsclient project: In Netbeans under File Open Project... go to the directory where you unzipped the sample and select the sessionpagination-wsclient project.
  • Right-click the project node and choose Run Project.
    The Netbeans IDE  builds the application, and deploys it.
  • When you run the project, your browser should display the opening page of the application at http://localhost:8080/sessionpagination-wsclient/
index.jpg

References:




Related Topics >> Web Services and XML      
Comments
Comments are listed in date ascending order (oldest first)

running the client (JSF) and server (Spring and JAX-WS services)

Hi, I was wondering how would you approach if I had to run the client (JSF) and the server (Spring and JAX-WS service implementations) on two different jvms. Would you recommend using the same domain model on the client side?. Would the sample work if I split up the client and service on two different servers (physical). I was not able to run the sample that way... thanks Srini

It should run fine on 2

It should run fine on 2 different servers, that's the point. The objects that get passed are in the WSDL and JAXB objects are generated in the client stubs from that . Just make sure you set the URL for the web service in the wsdl correctly , in the sample it is set for localhost

(No subject)