[an error occurred while processing this directive]
> developer > web app development
J2EE Components for the Real World
by Martin Holzner, Lead Consulting Eng. , Novell
Date Created: 2001-07-10 13:53:00.000
  Introduction
  Prerequisite Knowledge
  How does it work?
  How is the content of a WAR file accessed?
  A Simple Servlet
  Test the Servlet
  Conclusions
  Resources

introduction
As Novell moves increasingly toward standards and the Java Enterprise Edition platform (J2EE), many experienced SilverStream developers will face the same dilemma I found myself in some time ago: it's hard to let go. But actually, once you clear the first hurdle, it all starts to make sense. Novell is in the process of adapting its many tools to support J2EE development. This means you'll soon be as comfortable developing J2EE applications as you are developing SilverStream applications.

For those developers who have not yet worked with J2EE, the following three-part article should open a few doors. Part 1 discusses a simple servlet and its deployment as part of a Web Archive (WAR) file. It also shows how to create and deploy a JSP. Part 2 discusses how to combine a servlet and JSP as well as create some GUI and functionality for sending email from an HTML page. Part 3 wraps it all up by showing how to apply a few simple security settings and implement a standard way for logging in.

prerequisite knowledge
What types of J2EE components exist? What are components?

SUN's Blue Prints defines a component as "an application-level software unit." In addition to JavaBean components, which are part of the J2SE platform, the J2EE platform supports the following component types:

Component TypeComponentsPackaging Media
AppletappletsClient Archive (CAR)
application clientclient-side Java codeClient Archive (CAR)
Web componentJSPs , servletsWeb Archive (WAR)
enterprise JavaBeansSessionBeans, EntityBeansEJB Archive (JAR)
other mediaWARs, CARs, JARsEnterprise Application Archive (EAR)


This article only discusses Web components, i.e., servlets, JSPs and WAR files. (See 2.1.4 in the Blue Prints for a graphical overview of all components, their containers and how they communicate with each other.)

Briefly, Web components are server-side entities that provide a response to a request. A servlet is a program that extends the functionality of a Web server by providing a programmatic approach to deliver HTML content as a response. A JSP is a servlet "inside out," and therefore it is a text-based document that describes how to process a request to create a response.
how does it work?
The Java code, JSP document or both are developed, compiled, jarred up, and loaded into a container. Practically any development tool can be used for all these steps except for the last. (Deployment is not yet standardized, and therefore it is left up to the container provider.) In order for components to be uploaded into the server, they must be put into an archive file. The example at hand uses a WAR file. All of these archives comply with the JAR standard, and are easy to create using the JAR command.

The internal structure of a WAR file is defined by the specification, which must be followed. The easiest way to follow the specification and not have problems putting your code into the right structure inside the WAR file is to start with the right directory structure in your development environment. The structure should mirror the specified structure of a WAR file as indicated by the following example:



All publicly available resources are placed in the WAR file root. The "WEB-INF" directory contains all other resources. The "WEB-INF/web.xml" is the descriptor file for this particular WAR file, and is used during deployment (more detail will be provided about this later). JARs containing classes used in this WAR file go into "WEB-INF/lib." Other classes that are not in a JAR must be placed into "WEB-INF/classes" in order to be used by the other resources in the WAR file. This kind of development can get confusing very fast. It is helpful to keep the structure simple and use batch files (or better ANT) to automate the steps of compiling, building and deploying.

The example given follows the sample file structure below, which was used under the "J2EEComponents" directory and serves as the root directory (C:\J2EE\J2EEComponents).



Notice that since the "src" directory was not intended to be part of the WAR file, it has been placed at the same level as the "docroot" (root of WAR file) directory.

It is helpful to create source files in the "J2EEComponets/src" directory, and compile them (using javac) into the "J2EEComponets/docroot/web-inf/classes" directory. Creating the "web.xml" in the "J2EEComponets/web-inf" directory is also helpful.

How is the content of a WAR file accessed?
how is the content of a WAR file accessed?
The content of a WAR file is considered to be an application. Each WAR file has a home page (default page) and a path that is the root for that WAR file. Your deployment plan must map the WAR file to the path it will be running under in the container.
a simple servlet
This section describes how to create the servlet class, compile it, create the deployment descriptor, build the WAR file, create the deployment plan, and upload it all to the server. The components involved are "HeyServlet.java" (and ".class"), "web.xml," and "deploy.myapp.xml."

Create the servlet class and compile it.

There are several ways to create a servlet, and the easiest way is to extend "javax.servlet.http.HttpServlet." (Note that this comes close to an old fashioned Ag servlet with Server Lifetime, since this class is only loaded once when its URL is first requested.) To compile the class, simply use javac from the JDK.

Code 1 (HeyServlet.java)

package one;

import javax.servlet.*;

import javax.servlet.http.*;

import java.io.*;


public class HeyServlet extends HttpServlet

{

  // ever wondered when a servlet gets instantiated ?

  static

  {

	System.out.println(java.util.Calendar.getInstance().getTime() + ": Servlet  loading...");

  }

  protected void doGet(HttpServletRequest    req, HttpServletResponse resp)

		throws ServletException, java.io.IOException

  {

	resp.setContentType("text/html");

	PrintWriter out = resp.getWriter();

	try

	{

		StringBuffer html = new StringBuffer();

		html.append("");

		html.append("Hey,    I just called a servlet !");

		html.append("");

		out.println(html.toString());

		out.flush();

		out.close();

	}

	catch (Exception e)

	{

		e.printStackTrace();

	}

  }

  protected void doPost(HttpServletRequest req, HttpServletResponse resp)

		throws ServletException, java.io.IOException

  {

	System.out.println("doPost called");

	doGet(req,resp);

  }

}



Create the deployment descriptor.

After the servlet is compiled, the deployment descriptor (web.xml) must be written as follows:


<?xml version="1.0" encoding="ISO-8859-1"?> <!DOCTYPE web-app

  PUBLIC "-//Sun Microsystems, Inc.//DTD Web Application 2.2//EN"

  "http://java.sun.com/j2ee/dtds/web-app_2_2.dtd">

	<web-app>

	<!-- Servlet Configuration -->

		<servlet>

			<servlet-nameheyservlet</servlet-name>

			<servlet-classone.HeyServlet</servlet-class>

		</servlet>

	<!-- Servlet Mapping -->

		<servlet-mapping>

			<servlet-name>heyservlet</servlet-name>

			<url-pattern>/hello.html</url-pattern>

		</servlet-mapping>

  	<!-- The Welcome File List -->

  		<welcome-file-list>

    		<welcome-file>welcome.html</welcome-file>

  		</welcome-file-list>

  	<!-- Error File List -->

  		<error-page>

  			<error-code>404</error-code>

  			<location>/oops.html</location>

  		</error-page>

	 	<error-page>

  			<exception-type>java.lang.Exception</exception-type>

  			<location>/error.jsp</location>

		</error-page>

 	</web-app>



This example uses only a few tags. The "servlet" tag announces a servlet, and the "servlet-mapping" tag maps that servlet to a URL inside the container. The "welcome-file-list" tag defines the home page of the application in this WAR file (default is index.html), and the "error-page" tag can be used to define different pages for different errors and exceptions. (See BehindTheScenes for a complete description off all the possible tags in this file.)

Build the WAR file.

After the deployment descriptor is created, the WAR file must be built and deployed to the server. (To deploy it, a deployment plan must be provided.) WAR files are JAR files with a different ending and a special internal structure as described above. In the example given, the file structure matches the required structure in the WAR file, therefore it can simply be jarred up. To do this, change to the root directory "J2EEComponents" and create the WAR file called "myapp.war" by using the following command:

>> jar -cfv myapp.war -C docroot This command creates or overwrites a WAR file in the "J2EEComponents" directory, which includes all the contents of the "J2EEComponents/docroot" directory as well as all of its subdirectories, thus preserving the directory structure. The resulting WAR should contain the "web-inf/web.xml file," the "web-inf/classes/HeyServlet.class," the welcome file (welcome.html), and the error page (error.jsp).

Create the deployment plan.

Here is where the process becomes proprietary and vendor methods begin to differ. To make the bridge between the code and its description in the WAR file to the container that will actually run the code, some mappings must be provided so the container can complete the deployment. These mappings are defined in the deployment plan. (For examples on the different deployments refer to the SilverStream_Home directory under the "samples\SilverCmd" and "Resources\DTDs" listings.) For the servlet example given, this is very simple. All that is required is to define the URL under which this WAR file will be accessible on the server. As previously noted, the content of a WAR file can be considered an application under the root path, which is defined here in the deployment plan (deploy.myapp.xml).


 	<?xml version="1.0" encoding="UTF-8" standalone="yes"?>

	<?AgMetaXML 1.0?>

	<warjaroptions isobject="true">

   		<warjar isobject="true">

      		<sessiontimeout type="String">300</sessiontimeout>

      		<url type="String">/myapp</url>

   		</warjar>

	</warjaroptions>



Upload the WAR file into the server.

For deploying a WAR file there is a special option in "SilverCmd." For those who have not used SilverCmd yet, this is a command line tool that has been around since version 3.0 and lives in the "SilverStream\bin" directory. To see its powerful features just type ">>SilverCmd" from the command line.

The options for deploying a WAR file are as follows:

SilverCmd DeployWAR <server> <db> <warfile> -f deploymentplan [options]

SilverCmd QuickDeployWAR <server> <db> <warfile> -f deploymentplan -s <rootdir> [options]

Note that "DeployWAR" does the full job, and "QuickDeployWAR" is a smart version that updates only the changed code. The given example uses the following:

>> silvercmd deploywar myserver mydb myapp.war -f deploy.myapp.xml -o

test the servlet
After the WAR file is deployed, all that remains is trying to hit the URL that the servlet is assigned to: http://myserver/mydb/myapp/hello.html. (Remember this was done in the web.xml.)
conclusions
The J2EE way of developing applications is not much harder than what you are used to and it is a lot more flexible. Everything except the final deployment is standards-based, which makes code very portable. As the J2EE specification becomes more widely adopted by different application server vendors, code will become even more portable across a wider range of servers. Although many vendors currently claim compliance, there are big differences when you actually start to develop the code. As seen in the simple example provided, the biggest challenge is to manage the code structure, and therefore the file structure and the build process. To master this complexity, you may want to consider ANT as a building tool.
resources
arrow  J2EE platform and SUN's Blue Prints
arrow  SilverStream Help
arrow  web.xml tags