Section 10.11. Modifying the InventoryFacadeBean EJB

10.11. Modifying the InventoryFacadeBean EJB

Example 10-7 shows the new and upgraded XDoclet tags in the InventoryFacadeBean EJB that support Web Services deployment.

Example 10-7.
 /**  * @ejb.bean  *  name="InventoryFacade"  *  ...  *  view-type="all"  * ...  *  * @wsee.port-component  *  name="Inventory"  *  wsdl-port="InventoryEndpointPort"  *  service-endpoint-interface=""  *  service-endpoint-bean="com.jbossatwork.ejb.InventoryFacadeBean"  *  * @ejb.interface  *  service-endpoint-  *  */ public class InventoryFacadeBean implements SessionBean {     ...     /**      * @ejb.interface-method      *  view-type="all"      * ...      *      */     public CarDTOArray findAvailableCars(  ) throws EJBException {         CarDTOArray carDTOArray = new CarDTOArray(  );         CarDTO[  ] cars = (CarDTO[  ]) listAvailableCars(  ).toArray(new CarDTO[0]);         carDTOArray.setCars(cars);         return carDTOArray;     }     /**      * @ejb.interface-method      *  view-type="both"      * ...      *      */     public List listAvailableCars(  ) throws EJBException {         ...     }     ... } 

We've added a new method called findAvailableCars( ) that we're exposing as a Web Service. This method doesn't do muchit wraps the call to the listAvailableCars( ) method (which won't be used as a Web Service) and converts its return value (a java.util.List) to a CarDTOArray. We added the findAvailableCars( ) method because Java 2 Collections are incompatible with J2EE 1.4 Web Services, and we didn't want to change the existing listAvailableCars( ) method. See the "Web Services Data Types" and "Web Services and Collections" sections for more details.

Setting the view-type to all in the class-level @ejb.bean tag tells XDoclet to generate the Service Endpoint Interface along with the EJB Remote and Local Component interfaces. The new class-level @ejb.interface tag specifies the Java file for the Service Endpoint In addition to generating the Service Endpoint Interface, we have to tell XDoclet which method to include and which methods to exclude. Thus we include the findAvailableCars( ) method in the Service Endpoint Interface along with the EJB Remote and Local Component interfaces by setting the view-type to all in their method-level @ejb.interface-method tags. We exclude all other business methods (such as listAvailableCars( )) from the Service Endpoint Interface by setting the view-type to both in their method-level @ejb.interface-method tags. That way, these business methods show up only in the EJB Remote and Local Component interface files.

The class-level @wsee.port-component tag provides data that XDoclet uses to generate the webservices.xml file so it can associate the InventoryFacadeBean EJB with the InventoryEndpoint Service Endpoint Interface.

10.11.1. Web Services Data Types

We've now shown all the steps needed to deploy a Web Service, and at this point we'd love to close our eyes and declare success, but that wouldn't be honest. We could have just shown a simplistic "Hello World" Web Service method like Example 10-8.

Example 10-8.
     ...     public void hello(  ) throws java.rmi.RemoteException {     }     ... 

The hello( ) method doesn't return anything, nor does it take any parameters. We could have also shown the same method using primitive Java data types (such as int, float, or boolean), Java wrappers ( such as Integer, Float, or Boolean), or java.lang.String, but that's not realistic. In our everyday jobs, we develop Java objects for our application domain and use them as parameters and return values for our business methods. So rather than shying away from the hard issues of exchanging custom Java objects through a Web Service, we have a method like Example 10-9.

Example 10-9.
   ...    public com.jbossatwork.dto.CarDTOArray findAvailableCars(  )       throws java.rmi.RemoteException;    ... 

The findAvailableCars( ) method returns a CarDTOArray object that encapsulates an array of CarDTO objects. We'll cover the CarDTOArray in greater detail in the "Web Services and Collections" section, but if you can exchange custom data types and arrays of custom data types, then you can do anything else. This is easy once you understand the rules for serializing and deserializing custom objects. Each application-specific class must follow the JavaBeans conventions:

  • It must have a default constructor.

  • Each private or protected data member must have a corresponding public getter and setter.

For example, the CarDTO's make data member is a String, so the getter and setter must look like Example 10-10.

Example 10-10.
     private String make;     ...     public String getMake(  )     {         return make;     }     public void setMake(String make)     {         this.make = make;     } 

10.11.2. Web Services and Collections

J2EE Web Services can't exchange Java 2 Collections or arrays of custom data types due to portability concerns. WSDL uses XML Schema data types but it has no mappings for Collections or arrays of application-specific types. To get around these restrictions, we wrap an array of CarDTOs in a CarDTOArray object in Example 10-11 that follows the Java Bean conventions.

Example 10-11.
 package com.jbossatwork.dto; import; import com.jbossatwork.dto.CarDTO; public class CarDTOArray implements Serializable {     private CarDTO[  ] cars;     public CarDTOArray(  ) {  }     public CarDTO[  ] getCars(  ) {         return cars;     }     public void setCars(CarDTO[  ] cars) { = cars;     } } 

Wrapping an array of DTOs in a JavaBean is inconvenient and tedious, but sometimes you have to sacrifice for the sake of interoperability. Remember that the main reason for Web Services is that it provides the ability for a service written in one programming language to be used by clients written in other languages.

We've shown all the components to deploy an EJB as a Web Service, but where do all the pieces belong?

JBoss at Work. A Practical Guide
JBoss at Work: A Practical Guide
ISBN: 0596007345
EAN: 2147483647
Year: 2004
Pages: 197

Similar book on Amazon © 2008-2017.
If you may any questions please contact us: