The client depends on the network, and the network is imperfect. Although the client appears to be a stand-alone entity, it cannot be programmed as such because it is part of a distributed application. Three aspects of the network:
Latency is non-zero.
Bandwidth is finite.
The network is not always reliable.
A well-designed enterprise application must address these issues, starting with the client. The ideal client connects to the server only when it has to, transmits only as much data as it needs to, and works reasonably well when it cannot reach the server.
Different networks have different security requirements, which constrain how clients connect to an enterprise. For example, when clients connect over the Internet, they usually communicate with servers through a firewall. The presence of a firewall that is not under your control limits the choices of protocols the client can use. Most firewalls are configured to allow Hypertext Transfer Protocol (HTTP) to pass across, but not Internet Inter-Orb Protocol (IIOP). This aspect of firewalls makes Web-based services, which use HTTP, particularly attractive compared to RMI- or CORBA-based services, which use IIOP.
Security requirements also affect user authentication. When the client and server are in the same security domain, as might be the case on a company intranet, authenticating a user may be as simple as having the user log in only once to obtain access to the entire enterprise, a scheme known as Single Sign On. When the client and server are in different security domains, as would be the case over the Internet, a more elaborate scheme is required for single sign on, such as that proposed by the Liberty Alliance.
Every client platform's capabilities influence an application's design. For example, a browser client cannot generate graphs depicting financial projections; it would need a server to render the graphs as images, which it could download from the server. A programmable client, on the other hand, could download financial data from a server and render graphs in its own interface.
Design Issues and Guidelines for Browser Clients
Browsers are the thinnest of clients; they display data to their users and rely on servers for application functionality.
From a deployment perspective, browser clients are attractive for a couple of reasons. First, they require minimal updating. When an application changes, server-side code has to change, but browsers are almost always unaffected. Second, they are ubiquitous. Almost every computer has a Web browser and many mobile devices have a microbrowser.
Presenting the User Interface
Browsers have a couple of strengths that make them viable enterprise application clients. First, they offer a familiar environment. Browsers are widely deployed and used, and the interactions they offer are fairly standard. This makes browsers popular, particularly with novice users. Second, browser clients can be easy to implement. The markup languages that browsers use provide high-level abstractions for how data is presented, leaving the mechanics of presentation and event-handling to the browser.
Another, more significant cost of using browser clients is potentially low responsiveness. The client depends on the server for presentation logic, so it must connect to the server whenever its interface changes. Consequently, browser clients make many connections to the server, which is a problem when latency is high. Furthermore, because the responses to a browser intermingle presentation logic with data, they can be large, consuming substantial bandwidth.
Validating User Inputs
Consider an HTML form for completing an order, which includes fields for credit card information. A browser cannot single-handedly validate this information, but it can certainly apply some simple heuristics to determine whether the information is invalid. For example, it can check that the cardholder name is not null, or that the credit card number has the right number of digits. When the browser solves these obvious problems, it can pass the information to the server. The server can deal with more esoteric tasks, such as checking that the credit card number really belongs to the given cardholder or that the cardholder has enough credit.
Validating user inputs with a browser does not necessarily improve the responsiveness of the interface. Although the validation code allows the client to instantly report any errors it detects, the client consumes more bandwidth because it must download the code in addition to an HTML form. For a non-trivial form, the amount of validation code downloaded can be significant. To reduce download time, you can place commonly-used validation functions in a separate source file and use the script element's src attribute to reference this file. When a browser sees the src attribute, it will cache the source file, so that the next time it encounters another page using the same source file, it will not have to download it again.
Also note that implementing browser validation logic will duplicate some server-side validation logic. The EJB and EIS tiers should validate data regardless of what the client does. Client-side validation is an optimization; it improves user experience and decreases load, but you should NEVER rely on the client exclusively to enforce data consistency.
Communicating with the Server
Browser clients connect to a J2EE application over the Web, and hence they use HTTP as the transport protocol.
When using browser interfaces, users generally interact with an application by clicking hyperlinked text or images, and completing and submitting forms. Browser clients translate these gestures into HTTP requests for a Web server, since the server provides most, if not all, of an application's functionality.
User requests to retrieve data from the server normally map to HTTP GET requests. The URLs of the requests sometimes include parameters in a query string that qualify what data should be retrieved.
User requests to update data on the server normally map to HTTP POST requests. Each of these requests includes a MIME envelope of type application/x-www-form-urlencoded, containing parameters for the update.
After a server handles a client request, it must send back an HTTP response; the response usually contains an HTML document. A J2EE application should use JSP pages to generate HTML documents.
Managing Conversational State
Because HTTP is a request-response protocol, individual requests are treated independently. Consequently, Web-based enterprise applications need a mechanism for identifying a particular client and the state of any conversation it is having with that client.
The HTTP State Management Mechanism specification introduces the notion of a session and session state. A session is a short-lived sequence of service requests by a single user using a single client to access a server. Session state is the information maintained in the session across requests. For example, a shopping cart uses session state to track selections as a user chooses items from a catalog. Browsers have two mechanisms for caching session state: cookies and URL rewriting.
A cookie is a small chunk of data the server sends for storage on the client. Each time the client sends information to a server, it includes in its request the headers for all the cookies it has received from that server. Cookie support is inconsistent: some users disable cookies, some firewalls and gateways filter them, and some browsers do not support them. Furthermore, you can store only small amounts of data in a cookie; to be portable across all browsers, you should use four kilobytes at most.
Both cookies and pages containing rewritten URLs are vulnerable to unauthorized access. Browsers usually retain cookies and pages in the local file system, so any sensitive information (passwords, contact information, credit card numbers, etc.) they contain is vulnerable to abuse by anyone else who can access this data. Encrypting the data stored on the client might solve this problem, as long as the data is not intended for display.
Because of the limitations of caching session state on browser clients, these clients should not maintain session state. Rather, servers should manage session state for browsers. Under this arrangement, a server sends a browser client a key that identifies session data (using cookies or URL rewriting), and the browser sends the key back to the server whenever it wants to use the session data. If the browser caches any information beyond a session key, it should be restricted to items like the user's login and preferences for using the site; such items do not need to be manipulated, and they can be easily stored on the client.
Design Issues and Guidelines for Java Clients
Java clients can be divided into three categories: applications, applets, and MIDlets.
Application clients execute in the Java 2 Runtime Environment, Standard Edition (JRE). They are very similar to the stand-alone applications that run on traditional desktop computers. As such, they typically depend much less on servers than do browsers.
Application clients are packaged inside JAR files and may be installed explicitly on a client's machine or provisioned on demand using Java Web Start technology. Preparing an application client for Java Web Start deployment involves distributing its JAR with a Java Network Launching Protocol (JNLP) file. When a user running Java Web Start requests the JNLP file (normally by clicking a link in a Web browser), Java Web Start automatically downloads all necessary files. It then caches the files so the user can relaunch the application without having to download them again (unless they have changed, in which case Java Web Start technology takes care of downloading the appropriate files).
Applet clients are user interface components that typically execute in a Web browser, although they can execute in other applications or devices that support the applet programming model. They are typically more dependent on a server than are application clients, but are less dependent than browser clients.
Like application clients, applet clients are packaged inside JAR files. However, applets are typically executed using Java Plug-in technology. This technology allows applets to be run using Sun's implementation of the Java 2 Runtime Environment, Standard Edition (instead of, say, a browser's default JRE).
MIDlet clients are small applications programmed to the Mobile Information Device Profile (MIDP), a set of Java APIs which, together with the Connected Limited Device Configuration (CLDC), provides a complete Java 2 Micro Edition (J2ME) runtime environment for cellular phones, two-way pagers, and palmtops.
A MIDP application is packaged inside a JAR file, which contains the application's class and resource files. This JAR file may be pre-installed on a mobile device or downloaded onto the device (usually over the air). Accompanying the JAR file is a Java Application Descriptor (JAD) file, which describes the application and any configurable application properties.
Presenting the User Interface
Java applet and application clients may use the Java Foundation Classes (JFC)/Swing API, a comprehensive set of GUI components for desktop clients.
Implementing the user interface for a Java client usually requires more effort to implement than a browser interface, but the benefits are substantial. First, Java client interfaces offer a richer user experience; with programmable GUI components, you can create more natural interfaces for the task at hand. Second, and perhaps more importantly, full programmability makes Java clients much more responsive than browser interfaces.
When a Java client and a browser client request the same data, the Java client consumes less bandwidth. For example, when a browser requests a list of orders and a Java client requests the same list, the response is larger for the browser because it includes presentation logic. The Java client, on the other hand, gets the data and nothing more.
Furthermore, Java clients can be programmed to make fewer connections than a browser to a server.
Validating User Inputs
Like presentation logic, input validation logic may also be programmed on Java clients, which have more to gain than browser clients from client-side input validation. Recall that browser clients have to trade off the benefit of fewer connections (from detecting bad inputs before they get to the server) for the cost of using more bandwidth (from downloading validation code from the server). In contrast, Java clients realize a more responsive interface because they do not have to download validation logic from the server.
With Java clients, it is straightforward to write input validation logic.
Communicating with the Server
Java clients may connect to a J2EE application as Web clients (connecting to the Web tier), EJB clients (connecting to the EJB tier), or EIS clients (connecting to the EIS tier).
Like browser clients, Java Web clients connect over HTTP to theWeb tier of a J2EE application. This aspect of Web clients is particularly important on the Internet, where HTTP communication is typically the only way a client can reach a server. Many servers are separated from their clients by firewalls, and HTTP is one of the few protocols most firewalls allow through.
Whereas browsers have built-in mechanisms that translate user gestures into HTTP requests and interpret HTTP responses to update the view, Java clients must be programmed to perform these actions. A key consideration when implementing such actions is the format of the messages between client and server.
Unlike browser clients, Java clients may send and receive messages in any format.
Binary messages consume little bandwidth. This aspect of binary messages is especially attractive in low-bandwidth environments (such as wireless and dial-up networks), where every byte counts.
Java technologies for XML alleviate some of the burdens experienced with binary messaging. These technologies, which include the Java API for XML Processing (JAXP), automate the parsing and aid the construction of XML messages.
A side benefit of using XML messages is that alternate clients are easier to support, as XML is a widely-accepted open standard. You can use XML to encode messages from a variety of clients. A C++ client, for example, could use a SOAP toolkit to make remote procedure calls (RPC) to a J2EE application.
Like browser clients, Java Web clients carry out secure communication over HTTPS.
When using Web clients, you must write code for translating user gestures into HTTP requests, HTTP requests into application events, event responses into HTTP responses, and HTTP responses into view updates. On the other hand, when using EJB clients, you do not need to write such code because the clients connect directly to the EJB tier using Java Remote Method Invocation (RMI) calls.
Unfortunately, connecting as an EJB client is not always possible. First, only applet and application clients may connect as EJB clients. (At this time, MIDlets cannot connect to the EJB tier because RMI is not a native component of MIDP.) Second, RMI calls are implemented using IIOP, and most firewalls usually block communication using that protocol. So, when a firewall separates a server and its clients, as would be the case over the Internet, using an EJB client is not an option. However, you could use an EJB client within a company intranet, where firewalls generally do not intervene between servers and clients.
When deploying an applet or application EJB client, you should distribute it with a client-side container and install the container on the client machine. This container (usually a class library) allows the client to access middle-tier services (such as the JMS, JDBC, and JTA APIs) and is provided by the application server vendor. However, the exact behavior for installing EJB clients is not completely specified for the J2EE platform, so the client-side container and deployment mechanisms for EJB clients vary slightly from application server to application server.
Clients should be authenticated to access the EJB tier, and the client container is responsible for providing the appropriate authentication mechanisms.
Generally, Java clients should not connect directly to a J2EE application's EIS tier. EIS clients require a powerful interface, such as the JDBC API, to manipulate data on a remote resource. When this interface is misused (by a buggy client you have implemented or by a malicious client someone else has hacked or built from scratch), your data can be compromised. Furthermore, non-trivial EIS clients must implement business logic. Because the logic is attached to the client, it is harder to share among multiple types of clients.
In some circumstances, it may be acceptable for clients to access the EIS tier directly, such as for administration or management tasks, where the user interface is small or nonexistent and the task is simple and well understood. For example, a simple Java program could perform maintenance on database tables and be invoked every night through an external mechanism.
Managing Conversational State
Whereas browser clients require a robust server-side mechanism for maintaining session state, Java clients can manage session state on their own, because they can cache and manipulate substantial amounts of state in memory. Consequently, Java clients have the ability to work while disconnected, which is beneficial when latency is high or when each connection consumes significant bandwidth.
To support a disconnected operation, a Java client must retrieve enough usable data for the user before going offline. The initial cost of downloading such data can be high, but you can reduce this cost by constraining what gets downloaded, by filtering on user preferences, or requiring users to enter search queries at the beginning of each session. Many applications for mobile devices already use such strategies; they also apply well to Java clients in general.
When Java clients manipulate enterprise data, they need to know about the model and some or all of the business rules surrounding the data model. For example, the client must understand the concept of booked and unbooked seats, and model that concept just like the server does. For another example, the client must also prevent users from trying to select booked seats, enforcing a business rule also implemented on the server. Generally, clients manipulating enterprise data must duplicate logic on the server, because the server must enforce all business rules regardless of what its clients do.
When Java clients manipulate enterprise data, applications need to implement data synchronization schemes. For example, between the time when the user downloads the seating plan and the time when the user decides what seats he or she wants to buy, another user may buy some or all of those seats. The application needs rules and mechanisms for resolving such a conflict. In this case, the server's data trumps the client's data because whoever buys the tickets first - and hence updates the server first - gets the tickets. The application could continue by asking the second user if he or she wants the seats that the first user did not buy. Or, it could refresh the second user's display with an updated seating plan and have the user pick seats all over again.