General Overview
This topic is a discussion of the general JEE web container
components. While useful, this isn't a discussion of any of the
frameworks built upon the JEE web container such as struts, JSF,
Spring MVC or others. Each of these frameworks have their own sites
with a plethora of examples and other information. Each of the
following sections contain a component or piece of the web container
setup. This paper also does not get into other Enterprise components
such as JMS or EJB, although there are ways for the web container to
use these components and those places will be mentioned.
Web Contexts
There are 4 different contexts in the web container, in
parentheses would be their object variable equivelant:
- Application (static)
- Session (class)
- Request (method)
- Page (Only applicable on the JSP) (sub-method)
Application scoped variables are available to every web piece.
They're available within a given servlet/jsp request, they're
available to the session and any setup for a servlet, listener,
filter or any other web component, just like static properties are
available to any method in a class and all instances all can see the
same static parameter. Just like static variables, any change to an
application scoped variable will be seen by the rest of the
application.
Session scoped variables are tied to a specific user that span
multiple requests. This would be like creating a configuration object
in a general project to store information about a specific process
for the length of the process. Any sub process that originates from
this process will get the same data in this configuration object.
Once the process is done the object is discarded, just like a session
when a user leaves the system (or a timeout occurs before the nest
request from a specific user).
Request scoped variables are tied to a specific request on the
server. The parameters only live for the length of the request and
are reset with the next request. In object speak these would be just
like parameters created within a request. Variables within request
don't require a visibility modifier (such as public) because once the
method is done the variables are cleaned up and rest for the next
request.
Page scope is a special case of the request scope used only for
JSPs. Many custom tags will create properties and, in most cases,
store them in the page scope for use on that specific page. If you
were to be redirected to another page (an extremely unlikely thing
but still possible) these variables are wiped clean which makes this
scope a perfect place to store this temporary information.
Servlets
Servlets are the primary way to execute logic in a web
application. While you do have direct access to the output stream
that is returned to the client it is generally considered proper form
for the servlet to execute the logic (such as accessing a database,
interacting with a web service or an EJB), set parameters in one of
the web contexts and then forward to a JSP to implement the actual
rendering logic. One usual deviation from this would be if you have
to return some kind of non-viewable content (such as an excel, PDF or
other file) for the user to save outside the HTML viewing process.
You can chain servlets together using the
HttpServletRequest.forward() and the
HttpServletResponse.sendRedirect() to chain logic (or, generally
using the former) to use a JSP to render the result back to the user.
One thing to note on the sendRedirect() method, it sends a response
back to the browser and tells the browser to go to the page so any
request variables that were set will be reset when accessing the
redirected resource. Usually, instead of directly chaining servlets,
filters would be used. These components are covered in a later
section.
JSP
JSPs are actually special servlets that are intended to just
render content for the user. The web server will actually compile the
JSP on the back-end into a servlet for quicker access. They're
intended to be very light weight and just take properties set in a
servlet and render them to the user.
Scriptlets
Scriptlets are defined as anything between <% and %>.
Everything between the braces must be valid java. A special cased
where the output is rendered directly to the screen is the <%= %>.
Whatever is between the braces is evaluated and the result is
rendered to the screen, you shouldn't put a semi-colon at the end of
this expression. In general a mature project should not use these as
they're generally reserved for lightweight projects that don't use
servlets at all. If you find yourself using scriptlets you most
likely should be doing more work in the servlet or creating a custom
tag to keep from cluttering the page.
Expression Language
JSPs have their own expression language for quick and easy access
to scoped variables. The format of the expression is ${..} where the
first word inside the braces is a variable name in a scope. After the
variable name you can access properties based on dot notation. So, if
you had an expression like the following ${foo.bar} the jsp would
look in the all the contexts (more on the order in a minute) for a
property called 'foo', and once it finds the object it will try to
access the property getBar() (or isBar() if the property is a Boolean). You can chain this down to
any level you wish, as long as the chain is valid. You can also
access indexed or mapped properties using brackets so an expression
like the following: ${foo[0].bar} would try to find a list in a
context called foo, retrieve the first element and access the bar
property of that object. As a convenience for a map property you can
use the dot notation to access a entry of the map so ${foo.bar} would
be the same as ${foo['bar']} if 'foo' is a map.
Tag Libraries
Tag libraries are self contained pieces of rendering logic that
an be accessed just like any other tag. There are standard tag
libraries (generally called JSTL) and nearly every framework has a
set of tag libraries for use with the framework. You define them at
the top of the JSP file using the format <%@ taglib uri=”uri”
prefix=”x”>. With the preceding tag declaration to use the
taglib you'd start your tags with <x:....> where the colon is
followed by the tag definition. Think of a definition as a method
call to render some kind of element. Now, there are standard tag
libraries for things like database connections but most mature
projects won't use them as they're targeted at stand alone JSPs. The
most common tag libraries used are core as <%@ taglib prefix="c"
uri="http://java.sun.com/jstl/core" %> and format as <%@
taglib prefix="f" uri="http://java.sun.com/jstl/fmt"
%>. There are additional tag libraries like sql and xml but most
of these are covered by a framework.
Custom Tag libraries
If the standard tag libraries and your framework's tag libraries
aren't sufficient for your needs you can roll your own tag library.
To do this you create an XML file called <name>.tld and place
it in your WEB-INF/tld directory. The XML file has to implement the
http://java.sun.com/xml/ns/javaee/web-jsptaglibrary_2_1.xsd
schema. You can view a tutorial on Oracle's site for exactly how to
write a TLD but essentially there are two types of tags:
- Static function calls you want to expose in your application
to the JSPs. These are defined using the <function> tag with
the function-class and function-signature elements
- The <tag> class to define the traditional tag setup
where you define the tag class with tag-class and body-content to
define how to handle sub tags or sub html elements.
Filters
Filters are a command pattern for usage with Servlets. Filters
can operate before the servlet call on the request and after the
servlet call on the response. For the request side they can be useful
for things like verifying a user has logged in (assuming you aren't
using container managed security defined below) and forwarding to a
login page before secured sections of the app. You can also perform
actions like retrieving necessary information or instantiating
objects needed by the servlet (such as data access objects or common
lookups) since filters can be shared across multiple servlets. On the
outbound side they're useful for things like encrypting output when
necessary any other cleanup tasks necessary after a servlet is done
executing its tasks.
Listeners
There are two different kind of listeners in a standard web
application:
- SessionListeners
- ApplicationContextListeners
Both listeners are essentially the same thing but targeted at
different levels of the web container. They both have two methods to
implement, one for when an object is created and one for when that
object is destroyed.
For the Session listener it's targeted (not surprisingly) at when
each session is created or destroyed. While not extreemly useful, it
can be used to track when a particular user has logged in (which can
also be done through a filter for each request) or useage statistics.
When sessions are destroyed you could go through the session and
serialize items for retrieval upon re-creation or closing resources
that were stored in the session but these are generally fringe cases.
The application context listener is called twice during the life
of a web app, once when the application starts up and once when it
shuts down. In it, you can run anything that you need to manually set
up or tear down.
One thing to note about both these listeners, tread lightly on
the closing of resources when things stop. While you're guaranteed to
see things start up the app could crash and the shutdown methods may
not be called (a general problem anyway but something to remember)
WAR packaging and web.xml
The WAR file is a standard JAR file with a .war extension that
can be decompressed and used by an application server.
The web.xml file is the configuation file for a web application.
In this file you define all listeners, servlets, servlet mappings and
all other less common web application components. As you'll see
below, it's located under the WEB-INF directory and is required to
deploy a web application.
Directory layout
/ (all jsps go at this level for standard access through the
browser)
/WEB-INF (in here you put any other configuration file (other
than classes and jars)
/web.xml
/classes (all classes for the web app go here)
/lib (any dependent libraries for your web ap)
/scripts (standard but configurable location for javascript
files)
/images (standard but configurable location for images)
Security
While there is no standard way for an application server to set
up security there are standard ways to interact and set up restricted
access in the web app. There are two prominent ways to deal with
security. Neither way is definitively better than the other and they
can easily be used together.
The first way is declarative through the web.xml config file
using the <security-constraint> tag. Inside this tag you define
what url patterns you want to secure (they can be hard paths
referenced by a jsp or virtual paths defined in a servlet mapping)
and the roles necessary to access these resources. When a request is
made the server will check if the request has an authenticated user
and if not then redirect them to a login page for authentication.
Once authenticated, it will check the roles assigned to that user to
see if one matches what is necessary to access the page. Both the
page and the user can have multiple roles and only one matching role
is necessary. If no roles match then a forbidden page (403) is
returned to the user.
The other authentication mechanism is progromatic security (which
relies on the user being authenticated on the system). There are two
methods on the HttpServletRequest object that deal with
authentication:
- getUserPrinciple()
- isUserInRole(String)
getUserPrinciple() returns a UserPrinciple object if the user is
logged in with information about the logged in user, otherwise it's
null. The isUserInRole takes in a role as a string and returns true
if the user has that role. These are available in both the servlet
and on jsp pages to conditionally render JSP elements or conditional
business logic on the server.
Resources
Resource-ref
Resource-ref is used to define connection factories for
enterprise components. Some of the standard enterprise factories are:
- DataSource
- QueueConnectionFactory
- TopicConnectionFactory
- Session (for JavaMail)
The declaration includes a JNDI location where to find the
resource.
Env-entry
The env-entry tag is used to define a property (similar to a jvm
property) for use by the web application. The following types are
possible:
- java.lang.Boolean
- java.lang.Byte
- java.lang.Character
- java.lang.Double
- java.lang.Float
- java.lang.Integer
- java.lang.Long
- java.lang.Short
- java.lang.String
These properties are useful for values that change based on the
environment. One example would be if you have to store report files
you can make the directory where they're stored an environment
property so you can put the same WAR file in each environment and
update the environment value on the server.