java hosting


JavaRanch Newsletter Articles in this issue :
J2EE Web Tier TechnologiesSimon Brown Printable Version
Service Locator - An ImplementationRahul Mahindrakar Printable Version
Parsing XML with the SAX APIMatthew Phillips Printable Version
Book Review of the MonthCindy Glass
Map Is
Printable Version

J2EE Web Tier Technologies

Simon Brown, January 2003

Abstract

This article, the second in a series, looks at the web technologies that are a part of the Java 2 Enterprise Edition. Specifically, it provides a brief tour of Java Servlets and JavaServer Pages, highlighting the key differences between the two technologies and how they fit into the larger J2EE platform.

Introduction

In the first article in the series, we started to take a look at the Java 2 Enterprise Edition (J2EE) by introducing what it is, what it can be used for and how to get started building applications. This article sees the start of our tour where we?ll be taking a closer look at the technologies that make up the J2EE platform.

We saw last time that J2EE is a platform for building distributed, component based applications, although we didn?t really mention that there are a number of ways in which this functionality can be exposed and delivered to the end user - be it a human or an automated user. Examples here include a traditional desktop GUI application, a web service, an application running on a mobile phone/PDA or, more commonly, a web-based browser interface. J2EE provides two technologies for building web based applications - Java Servlets and JavaServer Pages (JSP).

What are Java Servlets?

One of the first ways in which dynamic behaviour was implemented on the web was with CGI scripts. These small programs (usually written in languages such as C, C++, Perl and UNIX shell scripts) would take a HTTP request (e.g. from a web browser), process it in some way and return the results back to the user. Typically, the sort of functionality that they provided was to process information submitted by users using a HTML form, or to dynamically generate content for presentation to the user by embedding markup language (e.g. HTML) inside the CGI script. CGI was a great mechanism for addressing the needs of the fast moving web environment, although a couple of its weaker points were the integration with other technologies (e.g. databases) and the execution model since it typically spawned a new instance of the CGI script for each and every request. The latter of these potentially makes CGI unscalable and therefore restrictive for very large web sites.

Java Servlets was really the first true server-side Java technology and, at a high level, is simply the Java equivalent of CGI scripts. From an implementation perspective, servlets are simply Java classes that implement a predefined interface. The following example illustrates how to write a servlet that outputs an HTML page containing the current date, formatted in an appropriate way for the user?s locale.

  package mypackage;

  import java.io.*;
  import java.text.*;
  import java.util.*;

  import javax.servlet.http.*;
  import javax.servlet.ServletException;

  public class DateServlet extends HttpServlet {

    protected void doGet(HttpServletRequest request, HttpServletResponse response)
      throws ServletException, IOException {

      // get a reference to the output writer
      PrintWriter out = response.getWriter();

      // get the locale of the client and create an appropriate date format
      Locale loc = request.getLocale();
      DateFormat df = DateFormat.getDateInstance(DateFormat.MEDIUM, loc);

      // and generate the page
      out.println("<html>");

      out.println("<head>");
      out.println("<title>The current date</title>");
      out.println("<link rel=\"stylesheet\" href=\"../page.css\">");
      out.println("</head>");

      out.println("<body>");
      out.println("<h1>The date is ");
      out.println(df.format(new Date()));
      out.println("</h1>");
      out.println("</body>");

      out.println("</html>");

      out.flush();
      out.close();
    }

  }

As this shows, servlets are fairly simple to build although even with this short example, a great deal of static content is embedded within the source code. However, servlets expand and improve on the concept of CGI because they address the two major issues that we mentioned earlier - integration and the execution model.

Where a new process will be created for each and every request in the CGI model, servlets are simply objects that run inside a container provided by a third party such as BEA, IBM and so on. Depending on which servlet container you use, there could be one or more instance of each servlet ready to service incoming requests, made possible by utilising Java?s threading model. For this reason, servlets are a much more scalable alternative to CGI scripts because rather than creating a new process to service a request, each request can be serviced by a different thread.

The other aspect that is greatly improved over the CGI model is that of integration. Since servlets are written in Java, they have access to the rich library of features provided by Java, including access to databases and other enterprise resources such as Enterprise JavaBeans (EJB). In essence, it is possible to achieve a great deal without ever leaving the Java environment.

What about JavaServer Pages?

We mentioned that there are in fact two web tier technologies within J2EE so let?s look at the other. JavaServer Pages (JSP) is a technology for presenting information over the web and uses a paradigm where Java code is embedded into the HTML - the opposite of the approach taken with servlets where any static content is embedded within out.println() calls. From an implementation perspective, JSP is written as pages (e.g. HTML files) and can have embedded within them fragments of Java source code known as scriptlets. These scriptlets are a mechanism for adding dynamic behaviour into otherwise static content. A JSP version of the previous example is as follows.

  <html>
    <head>
      <title>The current date</title>
      <link rel="stylesheet" href="../page.css">
    </head>

    <%@ page import="java.text.*" %>
    <%@ page import="java.util.*" %>

    <body>
      <%
        // get the locale of the client and create an appropriate date format
        Locale loc = request.getLocale();
        DateFormat df = DateFormat.getDateInstance(DateFormat.MEDIUM, loc);
      %>
      <h1>The date is <%= df.format(new Date()) %></h1>
    </body>
  </html>

As this shows, JSP pages are really just static content (in this case HTML) with special tags and characters. In this example, first of all we have directives that specify something about the JSP page (<%@ ... %>), then we have scriptlets that contain regular Java code (<% ... %>) and finally we have expressions (<%= ... %>), the results of which get output to the page.

Doesn?t mixing code and content lead to unmaintainable web applications?

One of the pitfalls in using JSP is that it is very easy to build large pages containing lots of embedded Java code and business logic. For this reason, JSPs provide easy integration with JavaBeans and another feature called JSP tag extensions, more commonly known as custom tags. These custom tags allow re-usable functionality to be encapsulated into XML-like tags that can be easily used on the pages by both page developers and designers. The example below illustrates how the functionality to format the date can be moved into, and reused as, a custom tag.

  <html>
    <head>
      <title>The current date</title>
      <link rel="stylesheet" href="../page.css">
    </head>

    <%@ taglib uri="/dateTaglib" prefix="date" %>

    <body>
      <h1>The date is <date:currentDate/></h1>
    </body>
  </html>

In this example, all of the Java code has been removed from the page and is now wrapped up and encapsulated as a reusable component. From an implementation perspective, custom tags are essentially just Java classes that again implement a specific interface. However, JSP 2.0 introduces the notion of building custom tags as fragments of JSP pages meaning that people that are not familiar with the Java programming language can also take advantage of custom tags to wrap up reusable functionality.

Building custom tags to represent common and recurring functionality is a great way to increase the maintainability of web applications while also making them easier to understand and read, particularly for page authors - those people that are focussed on the look and feel of an application rather than its functionality. After all, the amount of code on the page, mixed in with the content, is dramatically reduced.

Another good reason for using custom tags is that, through reuse, they can help decrease the time required to build web applications, and therefore decrease your time to market. There are currently many open source tag libraries (collections of custom tags) available to download from the Internet, and a good source of these is the Jakarta Taglibs project. Included in this collection of tag libraries is the JSP Standard Tag Library (JSTL) - an implementation of an initiative managed through the Java Community Process for the development of a standard tag library that can be used and reused for building JSP-based web applications. Essentially, JSTL contains a number of custom tags that help to solve many of the common problems encountered while building web applications, ranging from iterating over collections, delivering localized content and manipulating XML documents.

Why do we need Java Servlets and JSP?

On a final note, you may be wondering why we need both Java Servlets and JSP. After all, anything that can be done with servlets can be done with JSP and vice-versa, especially since behind the scenes a JSP is translated into a servlet the first time that it is requested. This is done automatically by the JSP container, and therefore all of the benefits around performance and scalability apply to JSPs too.

In reality, the answer to this question lies in how we use servlets and JSP pages, rather than any specific technical differences. Servlets are written in the same way as you would write regular Java classes and it?s for this reason that they are more suited to delivering content that is easy to generate programmatically. In other words, servlets are useful where there is more code (logic) than content (for example HTML). JSPs are more useful in buiding the presentation side of web applications because generating dynamic content is much easier if you are writing much of that content in its native form. We'll be seeing more about how servlets and JSP pages coexist when we look in detail at J2EE design patterns and application architectures in a future article.

Where can I find more information about Java Servlets and JSP?

The Servlet and JSP home pages are a good place to start, as is TheServerSide.com. Of course, if you have a specific question, don't forget to join us over at the JavaRanch Servlets and JSP forums. Also, take a look at the J2EE section of The Bunkhouse for a list of related books, reviews and recommendations.

Summary

To wrap up, support for building web-based applications within the Java 2 Enterprise Edition is comprehensive and provides everything that you'll need in order to build scalable web-based interfaces to new or existing applications. Java Servlets and JavaServer Pages provide us with the ability to build rich, dynamic interfaces while allowing us to choose whichever of these two complementary technologies best fit our needs. In addition to this, experiences with JSP have led to the creation of JSP tag extensions that give us a way to wrap up and reuse the common, recurring functionality within our web applications. These are a very powerful tool with which to ensure that maintainability isn't just something that we achieve when coding regular Java classes.

With our brief tour of the J2EE web tier complete, the next article will look at the business tier and specifically Enterprise JavaBeans.


Return to Top
SERVICE LOCATOR - AN IMPLEMENTATION
by Rahul Mahindrakar

Patterns have become very important and indespensible for Architects and Programmers. This is because provide reusable solutions to recurring problems in different contexts and also provide a language to describe them. The important point here is reuability of the same solution again and again .

J2EE provides its own set of patterns, other than the core design patterns. I have been working on the J2EE patterns for the past few weeks. The ServiceLocator pattern interests me a lot. This pattern tries to encapsulate complex interfaces and network operations to service lookup and creation. The basic aim of this article is to provide an implementation to this pattern. The aim is to be able to reuse this same class over different projects in J2EE without code change.

All J2EE clients that want to access components like EJB’s, JMS Queues and DataSource need to access them through a lookup. A typical lookup involves the following

 InitialContext ic= new InitialContext();
  ABCHome	home=(ABCHome) ic.lookup(“ABCHome” ;) ;
For EJB lookup’s addition actions like PortableRemoteObject.narrow() need to be invoked.

The above lines of code recur again and again in the web layer that accesses the Business layer. This type of code may also recur in the Business layer as one EJB access another like in the Business Fa?ade pattern. This can cause the following problems

  • Lookup Names are hardcoded in code.
  • Migration from one type of service to another can create a huge problem.
  • Caching is not implemented for objects being looked up.
The servicelocator pattern tries to solve the above problem. Using this you will have to replace the above code with
ABCHome home = 
    (ABCHome) ServiceLocator.getInstance().getHome(“ABCHome”, ABCHome.class , true) ;
Types of Clients of ServiceLocator
  1. Java Clients
  2. Web tier based clients like jsp, servlets , utility classes
  3. EJB tier clients
Normally for Web based clients and EJB tier clients the ServiceLocator.getInstance() should work in all application servers. However with Java Clients certain properties need to be set up before the getInstance() is called. These properties can be passed via the setup(Properties p) method call. Note that this method must be called the before the getInstance is called the first time.

Servlce Lookup Strategies

There following strategies can be followed in the ServiceLocator Pattern.

1. The lookup Names exist in the Web layer or Business layer. In this scenario the JNDI name to be looked up are passed from this layer. The problem here is that multiple objects looking up the same object may hardcode the lookup names in code like in the line 1 above. This is the same problem that we talked of earlier. To solve this problem one can look up the JNDI names and other properties through a property file. This is very easy to implement and solves the problem.

2. A second solution introduces the concept of services and in this case we move the lookup specific variables into a Services class. A service encapsulates the users from the complexities like JNDI names, Home class names , remote class names etc. The requestor of the services knows just the service which is defined in the Services class. This is something like

Services.CustomerService
This is passed to the ServiceLocator class. The service locater API then determines based on the service what all parameters it requires and get this from the services class. The Service specific parameters can be in the ServiceLocator class,or in an inner class or in a different class. We here have implemented this in a totally new class with package access. This is to prevent others from modifying the main ServiceLocator class. Package access has been provided to the methods of the Services class so that the ServiceLocator class can access them. Other classes can only access the public defined services of Services class. The properties can also be got from a properties file.

In both the cases the properties file strategy is recommended so that changes to code need not be done in case of change in properties.

In this case the ServiceLocator can be invoked as follows

ABCHome home = (ABCHome) 
      ServiceLocator.getInstance().getHome(ServiceLocator. CustomerService, true);
Cached / UnCached Lookups

There are also two types of Service lookups through the ServiceLocater. These two types are Cached and UnCached lookups.

The Cached lookups can be made through passing the a Boolean of true to all lookup methods for the pFromCache parameter

The Uncached lookups can be made through passing a Boolean of false to all lookup method for the pFromCache parameter.

Another difference between Cached and Uncached lookups is that the Uncached lookups do not create the Cache. Thus the first time a Cached lookup Is made a JNDI lookup will take place even though a Uncached lookup has been made earlier for the same service.

Lets talk “implementation”

The implementation thus

1) Undertakes JNDI Lookups for various objects like

  • EJBHome
  • EJBLocalHome
  • TopicConnectionFactory
  • QueueConnectionFactory
  • Topic
  • Queue
  • DataSource, Topic
  • Session for Mail
  • URL
  • Boolean Object
  • String Objects
  • Float
  • Double
  • Character
  • Long
  • Byte
  • Short
  • Integer
  • UserTransaction
2) Undertakes cacheing of the above objects
3) Provides an uncached version to those who do not wish to implement cacheing
4) Provides strategies wherein the jndi names, EjbHomes, EjbObject class names may not be coded in the client but rather in the Services
5) Provides access to the EJBRemoteObject directly without accessing the EjbHome (see method getStatelessEJB().
6) The Cache is not created with a lookup of false passed in the parameter

Resources:
Core J2EE Patterns

There is a Java class too and here is the code


Return to Top

Parsing XML with the SAX API

by Matthew Phillips

What is SAX?

SAX is an event driven XML parser. SAX uses the Observer design pattern to pass pieces of the document back to the client. If you are familiar with this pattern, you may skip to the Setup section at the end of this section. Unlike other implementations of the Observer pattern, such as the AWT event model, only one Observer can be registered with the parser.

The Observer pattern

The Observer pattern allows you to register an event listener with an event generator. When the event generator creates an event it passes control to the event listener to process that event. If you are familiar with AWT or Swing you see this in the way those handle events. You simply add your event listener (such as a ButtonListener) to your event generator (such as a Button through the addButtonListener interface). When the button is pressed, an event is generated and control is passed to the ButtonListener.

Setup

The only thing that you need (aside from a Java development environment, such as the SDK) is a parser implementation. J2SE 1.4 includes the Crimson parser, but for this tutorial I will be using the Xerces parser available from The Apache Software Foundation. As I go over running the examples, I will show you where to make changes for a parser other than Xerces. If the parser you choose is a standard implementation you should not need to change anything in the included code. The sample XML document that we will be parsing is located here. We will also be using a Book JavaBean.

The ContentHandler interface

The ContentHandler interface is where you tell the parser how you want a document to be handled. It is the event listener. You may view the sample implementation that I am using here.

I'll give a brief explanation of the methods that do nothing in this particular example and then move on to the methods that do the work in this example. The setDocumentLocator allows the parser to pass a Locator object that knows the line and column of the document the parser is at. This could be helpful for debugging purposes, but verify that your parser implements a Locator before relying on it.

The startDocument method is called by the parser when it begins to read the document. The endDocument method is called when the parser finishes with the document. If you have any start of document or end of document processing (such as opening a database connection) it should be done in these methods.

If you are using name spaces, the startPrefixMapping and endPrefixMapping allow you to do any processing that you may need to occur on a specific name space.

The ignorableWhiteSpace method allows you to process the white space that occurs between tags.

The processingInstruction method is called when the parser reads a processing instruction from the XML document.

The skippedEntity method occurs when a non-validating parser finds an entity reference that it cannot resolve.

Now we will turn to the meat of the ContentHandler implementation. Our startElement method receives four parameters. The namespaceURI is the URI of the name space that the element is a part of. The localName is the element name after any prefix or colon. The qualifiedName is the full name of the element, including any prefix. The attributes are any attributes of the element. There are two things we are concerned with when a new element occurs. The first is to instantiate a new StringBuffer to place the text content that follows the element. Our other concern is when the element is a book element. When this occurs we need to get the value of the isbn attribute, instantiate a new Book, instantiate a new List of authors, and assign the isbn to the book. We keep a copy of the isbn as a member element for later use in adding the book to the library.

The characters method is called by the parser when it reads the text content between the tags. The parser may call this method multiple times so a char array is passed with the start position of the content in question and the length of that content. The array itself may contain other content depending on the parser implementation. Our specific needs in this example is to save the content to the StringBuffer we instantiated in startElement.

The final method, endElement, is called when the parser encounters an end element. At that point we need to pass our content to the appropriate method of the book. Because the parser includes all white space when it calls the characters method, we trim that out when we assign it to a String. Using the qualifiedName of the element we can determine which method to call to assign the data to the Book. If the book tag is being closed we also need to assign the authors to the book and place the book in our library Map.

Putting it together

The class that starts the parsing process is found here. The first line of interest is where we instantiate the XMLReader. The no-parameter createXMLReader method of the XMLReaderFactory creates the default XML parser (I will show you how to set this in the next section). You could also pass a String to the method with the fully qualified class name of the parser that you want to use. The next two lines instantiate the Map we are using to represent the library and the ContentHandler from the previous section. After instantiating the ContentHandler, we register it with the parser. As stated before, only one ContentHandler may be registered with the parser. After registering the content handler we parse the document. The rest of the code reads through the Map and prints the results.

Running the code

After you compile the code you will need to add some parameters to run it. Assuming that you are using the Xerces parser you will type the following on the command line to run the code:

        java -Dorg.xml.sax.driver=org.apache.xerces.parsers.SAXParser PrintLibrary.
        
You should see the books output to the command line.

Summary

There is a great deal more to the SAX API than what I have demonstrated here, but this should go. Xerces has examples that are included with it, although I have not looked at them closely. An excellent book on parsing XML documents with Java is Processing XML with Java: A Guide to SAX, DOM, JDOM, JAXP, and TrAX by Elliotte Rusty Harold.


Return to Top
Book Review of the Month

Sun Certified Programmer & Developer Study Guide
by Kathy Sierra and Bert Bates
Imagine this: you're in college, studying for the final exam -- and the teacher gives you all of her notes that spell out EXACTLY what you need to know, what you DON'T need to worry about, and even points out all the little traps she'll try to catch you in when you take the exam. Kathy Sierra, the co-developer of the 310-035 Programmer's exam, with the help of Bert Bates has done just that. The 3rd edition of Osborne's Sun Certified Programmer and Developer for Java 2 is an awesome book.

Get this -- it's actually entertaining to read, very easy to understand, and the mock exams more closely resemble the real thing than any other mock out there. The "Two-minute Drills" are an excellent resource to help you review before you take the exam. The Exam Watches interspersed throughout the chapter point out all the traps you might fall in during the exam, and the On The Job blurbs give you a practical application for the knowledge you just learned.

The end chunk of the book discusses what you need to know to pass the Developer s exam. It won't teach you Swing or Threads - but what the exam assessor's are looking for - the things you need to pay attention to in order to pass that exam.

I fully recommend this book.

More info at Amazon.com More info at Amazon.co.uk

Chosen by Cindy Glass and Map Is

Return to Top

Managing Editor: Carl Trusiak

Comments or suggestions for JavaRanch's NewsLetter can be sent to the NewsLetter Staff
For advertising opportunities contact NewsLetter Advertising Staff