J2EE Web Tier TechnologiesSimon Brown, January 2003
AbstractThis 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.
IntroductionIn 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 withinout.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 (
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.
SummaryTo 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
ABCHome home = (ABCHome) ServiceLocator.getInstance().getHome(“ABCHome”, ABCHome.class , true) ;Types of Clients of ServiceLocator
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.CustomerServiceThis 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
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: There is a Java class too and here is the code Return to Top |
||||||
Parsing XML with the SAX APIby Matthew PhillipsWhat 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 patternThe 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. SetupThe 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. Putting it togetherThe 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. SummaryThere 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 |
||||||
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