Java EE Web application structure

In this post, we are going to create a simple Java EE Web application from the scratch. The goal of this example is to show the folder structure used in the development process of a Java EE Web application. The application will be deployed on Tomcat 6, we will use Ant to automatize all the processes implied (cleanup, delete & create folders, compile, etc). The folder structure used in this example is defined by Sun Microsystems on its guidelines.

The guidelines suggest where to place each type of file generally present in a Java EE Web application. In the example we will not use all these file types, but the conventions have a suggestion for almost every existing file, such as Ant files, classes, Java source files, deployment descriptors, test files, external libraries, javadoc files, Web application ARchive (WAR), etc. Why should we follow this guidelines? Organizing your application as shown in these post and in consequence as shown in the Sun guidelines will make easier to manage and maintain the project in the future, saving time and effort. Keep this into your head, respecting the predefined folder structure and placing the files where they belong helps other developers working on the project, who will immediately know where is each resource. Do it for your fellows!

Recommended directory structure.

Don't panic! This is the recommended directory structure for a web application with a single WAR file. But we will use just the folders that are highlighted in orange colour. The following list explains in short the purpose of some of this folders.

  • build/ this folder is created by the build task of the ant script. This directory will contain an exact image of the files in the Web application ARchive for this application.
  • dist/ this is created by the dist Ant task. This directory will contain an exact image of the binary distribution for your web application.
  • docs/ it contains all the documentation for a project, including installation and setup files, etc.
  • lib/ it holds the components of external libraries used by the application.
  • src/ java source files.
  • web/ the static content of your web site, such as HTML, JSP, JavaScript files, CSS files, and images. This directory will be the document root of your web application, and it will be directly accessible to a client request.
  • web/WEB-INF/ inside this folder are stored the special configuration files required for your application, including the web application Deployment Descriptor (web.xml), tag library descriptors for custom tag libraries, etc. The contents of this directory, or any file it contains, is not directly accessible to a client request.

Once you have compiled your application and generated the WAR file, the only thing left is move the WAR file to the applications folder of the server. In this case, the WAR file will be moved inside the $CATALINA_HOME/webapps folder ($CATALINA_HOME environment variable should points to the installation path of your Tomcat server).

Environment

Required software that has already been installed and configured on the system.

Exercise steps

Step 1 - Create the folder structure

First of all, we need to create the directory structure where we will develop the Web application. Execute the following commands to obtain all the structure at once. The paramater -p used with the mkdir command creates all the parents directories as needed, if they were not created yet.

~$ mkdir -p ~/lab/projects/SimpleWebApp/src/java/com/onewaytickettojava/jeewas
~$ mkdir -p ~/lab/projects/SimpleWebApp/web/WEB-INF
Terminal

The first command line creates the src folder, followed by the java folder, and ends with the folders that corresponds to the package of the Java file. Do you miss some folder? The rest of them will be created later by the Ant script.

Step 2 - Place the components on their folders

Since the main goal of this post is to show and explain the recommended directory structure used on the development of a Java EE Web application, detailed explanations of the components such as JSPs, Servlets, web.xml are beyond the scope of this article.

Create the Servlet

Place the SimpleServlet.java file inside the folder corresponding to its package. In this case, inside ~/lab/projects/SimpleWebApp/src/java/com/onewaytickettojava/jeewas.

package com.onewaytickettojava.jeewas;

import java.io.IOException;
import java.io.PrintWriter;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.util.Calendar;

public class SimpleServlet extends HttpServlet {

    protected void doGet(HttpServletRequest request, HttpServletResponse response)
    throws ServletException, IOException {
        response.setContentType("text/html;charset=UTF-8");
        PrintWriter out = response.getWriter();

        try {
            out.println("<html>");
            out.println("  <head>");
            out.println("    <title>Simple Servlet</title>");  
            out.println("  </head>");
            out.println("  <body>");
            out.println("    <h1>Simplet Servlet</h1>");
            out.println("    <p>" + Calendar.getInstance().getTime() + "</p>");
            out.println("  </body>");
            out.println("</html>");
        } finally { 
            out.close();
        }
    } 
}
SimpleServlet.java

A summarized explanation of this Servlet could be something like this, SimpleServlet handles HTTP GET requests and returns an HTML page with the actual time to show you how much dynamic it is. Take into account that this is a very simple example, it has no javadoc comments and even worse, it has embedded HTML inside the Servlet, which is ugly and error-prone.

Create the JSP

There are two JavaServer Pages, index.jsp, the default welcome page and the simplePage.jsp. This last one will be accessed directly from the browser address bar.

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"
 "http://www.w3.org/TR/html4/loose.dtd">
<html>
   <head>
      <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
      <title>Index JSP</title>
   </head>
   <body>
      <h1>Index JSP</h1>
      <p>Defined as Welcome page in the Deployment Descriptor</p>
   </body>
</html>
index.jsp

Remember, the simplePage.jsp file is directly accessible because it is stored outside the WEB-INF folder. If you want to restrict the direct access to your JSPs, you can save them inside a subfolder (e.g. jsp) into the WEB-INF folder.

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
   <head>
      <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
      <title>Simple Page JSP</title>
   </head>
   <body>
      <h1>Simple Page JSP</h1>
      <p>Accessed directly from the address bar.</p>
   </body>
</html>
simplePage.jsp
Create the web.xml

Finally, we need to copy the web.xml. It must be stored inside the WEB-INF directory. It provides the configuration and deployment information for the Web components that comprise the Web application, such as servlets, servlet parameters, filters, listeners, welcome files and many more.

<?xml version="1.0" encoding="UTF-8"?>
<web-app version="2.5" xmlns="http://java.sun.com/xml/ns/javaee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd">
   <servlet>
      <servlet-name>SimpleServlet</servlet-name>
      <servlet-class>com.onewaytickettojava.jeewas.SimpleServlet</servlet-class>
   </servlet>
   <servlet-mapping>
      <servlet-name>SimpleServlet</servlet-name>
      <url-pattern>/SimpleServletURL</url-pattern>
   </servlet-mapping>
   <welcome-file-list>
      <welcome-file>index.jsp</welcome-file>
   </welcome-file-list>
</web-app>
web.xml
Ant script

We have almost finished! We only need to compile the Java source files including the dependencies, move the generated class file to the corresponding build subfolder, move the JSP as well the web.xml, and once everything is on its place, pack all this stuff into a WAR file and copy it to the deployment folder of the Tomcat server. Just this, nothing else. Luckily we have Ant installed, and it will help us to automatize all this process in one single script.

<?xml version="1.0" encoding="UTF-8"?>
<project name="SimpleWebApp" basedir="." default="install">
  <property environment="env"/>
  <property name="build.dir" value="build" />
  <property name="dist.dir" value="dist" />
  <property name="src.dir" value="src" />
  <property name="web.dir" value="web" />
  <property name="catalina.dir" value="${env.CATALINA_HOME}"/>

  <path id="classpath.build">
    <pathelement location="${catalina.dir}/lib"/>
    <fileset dir="${catalina.dir}/lib">
      <include name="*.jar"/>
    </fileset>
  </path>

  <target name="compile" description="Compiles the classes">
    <mkdir dir="${build.dir}/WEB-INF/classes" />
    <javac srcdir="${src.dir}" 
           destdir="${build.dir}/WEB-INF/classes" 
           fork="yes" 
           classpathref="classpath.build" />
  </target>

  <target name="clean" description="Delete old build and dist directories">
    <delete dir="${build.dir}"/>
    <delete dir="${dist.dir}"/>
  </target>

  <target name="all" depends="clean,compile" description="Clean build and dist directories, then compile"/>

  <target name="dist" depends="all" description="Create an exact image of the binary distribution">
    <mkdir dir="${dist.dir}" />
    <copy todir="${dist.dir}/WEB-INF">
      <fileset dir="${build.dir}/WEB-INF">
        <include name="**/*" />
      </fileset>
    </copy>
    <copy todir="${dist.dir}">
      <fileset dir="${web.dir}">
          <include name="**/*" />
      </fileset>
    </copy>
  </target>

  <target name="install" depends="dist" description="Copy the Web application to the server webapps directory">
    <copy todir="${catalina.dir}/webapps/${ant.project.name}">
      <fileset dir="${dist.dir}">
          <include name="**/*" />
      </fileset>
    </copy>

  </target>

  <target name="war" depends="dist" description="Creates the WAR file">
    <war destfile="${build.dir}/${ant.project.name}.war" webxml="${dist.dir}/WEB-INF/web.xml">
     <fileset dir="${dist.dir}">
        <include name="**/*" />
      </fileset>
    </war> 
  </target>
 
</project>
build.xml

Most of the tasks names are fairly self-explanatory. However, if there is some task or property you do not understand, drop a comment or send me an e-mail and sure you will get a response.

Test

Let's test it. Open a terminal and go to the project folder, then, type the ant command and check out if every task of the Ant script works properly (mine works ;-).

~/lab/projects/SimpleWebApp$ ant
Buildfile: build.xml

clean:
   [delete] Deleting directory /home/me/lab/projects/SimpleWebApp/build
   [delete] Deleting directory /home/me/lab/projects/SimpleWebApp/dist

compile:
    [mkdir] Created dir: /home/me/lab/projects/SimpleWebApp/build/WEB-INF/classes
    [javac] Compiling 1 source file to /home/me/lab/projects/SimpleWebApp/build/WEB-INF/classes

all:

dist:
    [mkdir] Created dir: /home/me/lab/projects/SimpleWebApp/dist
     [copy] Copying 1 file to /home/me/lab/projects/SimpleWebApp/dist/WEB-INF
     [copy] Copying 3 files to /home/me/lab/projects/SimpleWebApp/dist

install:
     [copy] Copying 4 files to /home/me/lab/servers/tomcat/webapps/SimpleWebApp

BUILD SUCCESSFUL
Total time: 1 second
~/lab/projects/SimpleWebApp$ 
Terminal

At this point, there is a copy of the SimpleWebApp application inside the webapps folder of the Tomcat server. Open a terminal and start the server, the Web application is ready to be tested. However, if we specifically call the war Ant task, a WAR file will be created inside the build folder and we must copy this file inside the webapps folder manually before starting the server. Tomcat will automatically deploy the WAR file on the start up, visit the $CATALINA_HOME/webapps folder if you want to see how it is deployed. Tomcat uses the name of the WAR file as the project name, so there must be a folder called SimpleWebApp inside the $CATALINA_HOME/webapps folder.

~/lab/projects/SimpleWebApp$ tomcat start
Using CATALINA_BASE:   /home/me/lab/servers/tomcat
Using CATALINA_HOME:   /home/me/lab/servers/tomcat
Using CATALINA_TMPDIR: /home/me/lab/servers/tomcat/temp
Using JRE_HOME:       /home/me/lab/jvm/java-6-sun
Tomcat started.
~/lab/projects/SimpleWebApp$
Terminal

It is time to check the JSPs and the Servlet. The URL to access the Web application is http://localhost:8080/SimpleWebApp. Typing this location in the address bar of a web browser, the page displayed is the one defined in the web.xml, under the tag <welcome-file>. To access the simplePage.jsp file we should type this location: http://localhost:8080/SimpleWebApp/simplePage.jsp.

Screenshots of the JSPs and the Servlet.

Finally, to test the Servlet, we need to type into the address bar the url defined in the web.xml under the tag <url-pattern>. This value is related through the <servlet-name> tag with the real location of the Servlet class, defined under the <servlet-class> tag. Thus, to test the Servlet, visit: http://localhost:8080/SimpleWebApp/SimpleServletURL.

Test files

Files used during the test. Click on the file to download it (do not use "Save Link As...").

References

0 comments

Be the first to write a comment!

Post a Comment

Top