7.4 Service Types

Flash clients can communicate with several different service types running on a Java server. This section provides an overview of the different service types and how they are used with Flash Remoting.

7.4.1 JavaBean Services

Macromedia uses the term JavaBean service to refer to a Java class accessed through Flash Remoting that implements the java.io.Serializable interface (a.k.a. "implements Serializable"). While JavaBean means many things to many people, we will use Macromedia's term to identify this service type. In the case of JavaBean services, the fact that a class implements Serializable tells Flash Remoting that the service class can be stored in the user's session.

JavaBean services must have a no-argument constructor (a constructor that does not take any arguments) to be used with Remoting. If you have no other constructors, the default no-argument constructor implicit in the class is sufficient. If you have other constructors, you must explicitly implement a no-argument constructor. Otherwise, the Remoting gateway returns an error of type java.lang.InstantiationException because the gateway cannot create an instance of the service even though it can find the service class.

Error conditions are indicated by passing back an error object whose properties can be examined for additional details about the error. For the remainder of the chapter, we say "throws a SuchAndSuchException" as a shorthand way of saying that the gateway returns an error object whose type property is set to "SuchAndSuchException".

JavaBean service methods are implemented as instance methods of a JavaBean object. When the Remoting gateway invokes a JavaBean service method, it creates a new instance of the JavaBean object and invokes the service method with the arguments provided by the Flash client.

After the Remoting gateway invokes a JavaBean service, it stores the JavaBean instance in the user session and reuses it for subsequent service method calls by that same user. If the state of the JavaBean changes with one method call, the Remoting gateway uses it in its changed state for subsequent method calls. Use JavaBean services only if you want to maintain state in the Remoting service between service method calls, such as is necessary to create pageable resultsets, as discussed under Section 7.8.2 later in this chapter.

The following example shows a JavaBean service implementation with an echo( ) method that simply takes an argument and returns it back to the client. Note that this example implements java.io.Serializable and does not need to explicitly define a no-argument constructor, since it has no other constructors. When a Flash client calls echo( ), the Remoting gateway stores an instance of JavaBeanService in the session and reuses it for subsequent calls to the same service by the same client.

public class JavaBeanService
  implements java.io.Serializable {
  public Object echo (Object obj) {
    return obj;
  }
}

7.4.2 Java Class Services

Java class services are simply Java classes with no restrictions other than that they do not implement java.io.Serializable. Java class services must have a no-argument constructor as described for JavaBean services.

Like JavaBean services, Java class service methods are implemented as instance methods of the Java object. For each service method invocation, the Remoting gateway creates a new instance of the Java class service. The following example of a Java class service provides the same functionality as the previous JavaBean service example. The difference is that it does not implement java.io.Serializable, so the Remoting gateway creates a new instance of the Java class service each time echo( ) is called by a Flash client (recall that, in contrast, JavaBean instances are stored in the user session for subsequent service method calls by that same user):

public class JavaClassService {
  public Object echo (Object obj) {
    return obj;
  }
}

7.4.3 Enterprise JavaBean (EJB) Services

Enterprise JavaBeans (EJBs) are the J2EE model for distributed component development. For more information on EJB design and development, refer to Enterprise JavaBeans by Richard Monson-Haefel (O'Reilly). Any EJB available to the web application within which Flash Remoting is running can be used as an EJB service. That is, you may use both remote and local entity and session EJBs as Flash Remoting services.

To use an EJB service, a Flash client identifies the service using the EJB's JNDI name (see Section 7.6.2 later in this chapter for more on JNDI names). The Flash client can then invoke any home interface method using this service. The most common use is to call create( ), but the Flash client can also call finders on entity bean home interfaces. If the result of the call on the home interface is an EJB, Flash Remoting stores that instance in the user session and sends the Flash client back a NetServices object, which can be used to call methods on that EJB.

If you are not familiar with remote and local entity sessions, home interfaces, and finders, refer to the EJB resources cited in Appendix B.

Example 7-1 shows the client-side ActionScript code for using an EJB with the JNDI name java:comp/env/ejb/EjbService. The service variable is essentially a reference to the EJB home interface, and the Flash client invokes the create( ) method on it. Invoking the create( ) method creates a new instance of the EJB and passes it as the result to the create_Result( ) method on the Flash client. The create_Result( ) method then calls the echo( ) method on the EJB. Thus, we have demonstrated how to create an EJB, pass a reference to it back to Flash, and allow Flash to invoke methods on the EJB as a Remoting service itself.

Example 7-1. Invoking a method on an EJB from Flash
// Identify the EJB with JNDI name "java:comp/env/ejb/EjbService"
var service = gatewayConnection.getService("java:comp/env/ejb/EjbService", this);

// Create an instance of the EJB
service.create( );

// The result handler for create( ) receives a reference to the EJB
function create_Result(ejb) {
  // Call echo on the created EJB
  ejb.echo("Flash says 'say hi.'");
}

// Handle the result of calling echo( ).
function echo_Result(result) {
  trace("The EJB said " + result);
}

7.4.4 Servlet Services

Servlet services are simply servlets running in the web application container. A Flash client uses a servlet service by using the web application context name as the service name and the servlet name, as it is identified in the web.xml file, as the service method name. For example, consider a web application named remotingbook and a servlet named ServiceServlet mapped in its web.xml file:

<servlet>
 <servlet-name>ServiceServlet</servlet-name>
 <servlet-class>
   com.oreilly.frdg.java.service.ServiceServlet
 </servlet-class>
</servlet>

Example 7-2 shows the client-side ActionScript code, which creates a service object by specifying the web application name in quotes ("remotingbook") as the service name. It then invokes the servlet service as a method of the service object returned by getService( ).

Example 7-2. Invoking a servlet service from Flash
// The web application name is used as the service name
var service = gatewayConnection.getService("remotingbook", this);

// Call the servlet service as a method of the service object
service.ServiceServlet("Hello.");

// Handle the service servlet result
function ServiceServlet_Result(result) {
  trace("ServiceServlet_Result:" + result);
}

Example 7-3 shows a servlet service that accepts an argument list from a Flash client and, for demonstration purposes, simply returns the same arguments back to Flash. The servlet service receives the Flash arguments via the FLASH.PARAMS attribute of the request object. It returns a result by setting the FLASH.RESULT attribute of the request object:

Example 7-3. Servlet service implementation
public class ServiceServlet
  extends HttpServlet
{
  public void service(HttpServletRequest request,
                      HttpServletResponse response)
    throws ServletException
  {
    // Retrieve the parameter list from the Flash invocation of ServiceServlet( )
    List params = (List) request.getAttribute("FLASH.PARAMS");

    // Just echo the parameters back to Flash
    request.setAttribute("FLASH.RESULT", params);
  }
}

There is always a java.util.List in request.getAttribute("FLASH.PARAMS"). If the Flash client provides no arguments in the service method call, the List is empty.

Macromedia provides a servlet implementation, flashgateway.adapter.java.FlashServlet, that handles fetching the parameters from and setting the results in the request object's attributes. The following example shows a ServiceFlashServlet class, which extends FlashServlet to replicate the functionality of Example 7-3. The FlashServlet.service( ) method accepts a list of parameters from Flash and returns an object as the result. The ServiceFlashServlet.service( ) method does not throw any exceptions, so if you need to throw a checked exception (an exception that must be caught somewhere in the call chain) from your servlet service, you must implement your servlet service manually, as shown in the Example 7-3. Adding a checked exception when extending a method will cause a compiler error.

import flashgateway.adapter.java.FlashServlet;

public class ServiceFlashServlet
  extends FlashServlet
{
  public Object service (ServletRequest request,
                         ServletResponse response,
                         List params) {
    // Just echo the parameters back to Flash
    return params;
  }
}

In application servers that support the Servlet 2.3 specification, you can configure JSPs as servlets in your web.xml file as follows:

  <servlet>
   <servlet-name>JspService</servlet-name>
   <jsp-file>/WEB-INF/jsp/service/jspService.jsp</jsp-file>
  </servlet>

With this configuration, you can use the JSP file as a Remoting service in the same way you used a servlet as a service. Here is what the client-side ActionScript code looks like:

// The web application name is used as the service name
var service = gatewayConnection.getService("remotingbook", this);

// Call the JSP service
service.JspService ("Hello.");

// Handle the JSP servlet result
function JspService_Result(result) {
  trace("JspService_Result:" + result);
}

Here is the server-side code in jspService.jsp:

<%@ page language="java"%>

<%
// Retrieve the parameters sent from Flash
java.util.List params = (java.util.List) request.getAttribute("FLASH.PARAMS");

// Just echo the parameters back to Flash
request.setAttribute("FLASH.RESULT", params);
%>

Servlet services are awkward to use because the service method arguments and result must be accessed through attributes of the request object. Additionally, developers must implement a new servlet for each service method they provide to the Flash client. However, servlet services are the only service type that has direct access to the user request and, therefore, the user session. This access can be very helpful for developers who need to access, from Remoting services, information that has been stored in the user session by other objects running in the application.

7.4.5 JMX MBean Services

The Java Management Extensions (JMX) is an optional extension to the core Java technologies that standardizes management interfaces to remote services. Typically, it is used to manage services running in a J2EE application server. A managed bean (MBean) is a Java object that represents a JMX manageable resource. For more information on JMX and MBeans, see http://java.sun.com/products/JavaManagement.

When used with JRun, Flash Remoting gives Flash clients direct access to MBeans running in JRun as MBean services. With access to these MBeans, a Flash client can inspect the state of services deployed in JRun.

7.4.6 Server-Side ActionScript (SSAS) Services

SSAS is not a standard J2EE technology. It is a feature of JRun and ColdFusion. When used with JRun and ColdFusion, Flash Remoting gives Flash clients the ability to invoke methods on SSAS objects.

Server-Side ActionScript is covered in detail in Chapter 6 and is not addressed in this chapter.



    Part III: Advanced Flash Remoting