Sunday, April 26, 2009

JSP Tutorial 13 Protecting your website with a login page

Some sites require that all users log-in using a username and password,
before being able to visit any page.

This can be done using JSP sessions or servlets, and in fact this was
a common technique for a while.  But starting with a new release of
Servlets specifications (2.2) from Sun, this feature is now very simple
to implement.  

It is no longer necessary to use JSP techniques to provide login/password
protection, but it is still a very common requirement of web-sites, therefore
a brief overview is provided here.

To password-protect your site, you just need to design a login page. 
This page can be as simple or complicated as you need it to be.  It
must contain a <FORM> tag, with the METHOD set to
POST and the ACTION set to "j_security_check".

<FORM METHOD=POST ACTION=j_security_check>

The target j_security_check is provided by the application
server, and does not need to be coded.

The form must contain two <INPUT> fields, named j_username
and j_password respectively for the username and password. 
Typically, the username field will be a TEXT input field, and
the password field will be a PASSWORD input field.

After this, you must tell your application server to password protect
your pages using the login page you have provided.  The details will
vary from server to server, but a good implementation will provide you
hooks that you can use, for example, to match usernames and passwords against
a database.  (E.g., in Blazix you can supply an implementation of
the interface desisoft.deploy.AuthCheck to check usernames and
passwords against a database or other sources.)

Exercise:  Read your application server's documentation
and add login/password protection to some of your JSPs.

JSP Tutorial 12 Techniques for form editing

A tag library such as the one that comes with the Blazix
server
, may not be available in your environment.  How can you
allow similar features without using a tag library?

It is a little tedious, but it can be done.  Basically, you must
edit each HTML tag yourself, and put in a default value.  The following
examples shows how we modify GetName.jsp to provide features similar to
blx:getProperty
but with manual HTML tag editing:

<jsp:useBean id="user" class="user.UserData" scope="session"/>
<HTML>
<BODY>
<FORM METHOD=POST ACTION="SaveName.jsp">
What's your name? <INPUT TYPE=TEXT NAME=username
         SIZE=20 VALUE="<%= user.getUsername() %>"><BR>
What's your e-mail address? <INPUT TYPE=TEXT
         NAME=email SIZE=20
         VALUE="<%= user.getEmail() %>"><BR>
What's your age? <INPUT TYPE=TEXT NAME=age
         SIZE=4 VALUE=<%= user.getAge() %>>
<P><INPUT TYPE=SUBMIT>
</FORM>
</BODY>
</HTML>

As you can see, this simply involves adding a "VALUE" field in the INPUT
tags, and initializing the field with an expression!

To handle exceptions during input processing, a simple approach is to
use "String" fields in the bean, and do the conversion to the
target datatype yourself.  This will allow you to handle exceptions.

Exercise:  Modify the earlier example to do everything without
the Blazix tag library (you can restrict this to only one field.)

JSP Tutorial 11 Tag libraries

JSP 1.1 introduces a method of extending JSP tags, called "tag libraries". 
These libraries allow addition of tags similar to jsp:include
or jsp:forward, but with different prefixes other than jsp:
and with additional features.

To introduce you to tag libraries, in this tutorial we use the Blazix
tag library as an example.  This tag library comes bundled with the
Blazix
server
. If you are not using the Blazix Server, you may just want
to review the material to get familiar with the syntax,
and continue on to the next page.

Each tag-library will have its own tag-library specific documentation. 
In order to use the tag library, you use the "taglib" directive to specify
where your tag library's "description" resides.  For the Blazix tag
library,  the (recommended) directive is as follows

<%@ taglib prefix="blx" uri="/blx.tld" %>

The "uri" specifies where to find the tag library description.  
The "prefix" is unique for the tag library.  This directive is saying
that we will be using the tags in this library by starting them with blx:

The Blazix tag library provides a blx:getProperty tag.  This tag
can be used to allow the user to edit form data.  In our GetName.jsp
file, we will now add a jsp:useBean and place the form inside blx:getProperty.

The new GetName.jsp is

<%@ taglib prefix="blx" uri="/blx.tld" %>
<jsp:useBean id="user" class="user.UserData" scope="session"/>
<HTML>
<BODY>
<blx:getProperty name="user" property="*">
<FORM METHOD=POST ACTION="SaveName.jsp">
What's your name? <INPUT TYPE=TEXT NAME=username SIZE=20><BR>
What's your e-mail address? <INPUT TYPE=TEXT NAME=email SIZE=20><BR>
What's your age? <INPUT TYPE=TEXT NAME=age SIZE=4>
<P><INPUT TYPE=SUBMIT>
</FORM>
</blx:getProperty>
</BODY>
</HTML>

Note that the blx:getProperty doesn't end with /> but is instead terminated
by a separate </blx:getProperty> line.  This puts all the form
input fields inside the blx:getProperty so they can be appropriately modified
by the tag library.

Try putting a link to GetName.jsp from the NextPage.jsp, and you will
see that the bean's data shows up automatically in the input fields.

The user can now edit the data.

We still have a couple of problems.  The user cannot clear out
the name field.  Moreover, if the user enters a bad item in the "age"
field, something which is not a valid integer, a Java exception occurs.

We will use another tag from the Blazix tag library to take care of
this.  Blazix offers a blx:setProperty tag that can be used to take
care of these problems.  blx:setProperty allows us to define
an exception handler method.  If an exception occurs, we can collect
an error message for the user and continue processing.

Following is a version of SaveName.jsp that processes any errors, and
either shows the user GetName.jsp again to user can enter the data correctly,
or automatically forwards to NextPage.jsp.

<%@ taglib prefix="blx" uri="/blx.tld" %>
<%!
    boolean haveError;
    StringBuffer errors;

    public void errorHandler( String field,
                              String value,
                              Exception ex )
    {
        haveError = true;
        if ( errors == null )
            errors = new StringBuffer();
        else
            errors.append( "<P>" );
        errors.append( "<P>Value for field \"" +
                     field + "\" is invalid." );
        if ( ex instanceof java.lang.NumberFormatException )
            errors.append( " The value must be a number." );
    }
%>
<%
    // Variables must be initialized outside declaration!
    haveError = false;
    errors = null;
%>
<HTML>
<BODY>
<jsp:useBean id="user" class="user.UserData" scope="session"/>
<blx:setProperty name="user"
     property="*" 
     onError="errorHandler"/> 
<%
    if ( haveError ) {
        out.println( errors.toString());
        pageContext.include( "GetName.jsp" );
    } else
        pageContext.forward( "NextPage.jsp" );
%>
</BODY>
</HTML>

Note that haveError and errors must be re-initialized
each time, therefore they are being initialized outside of the declaration.

[Also notice the use of pageContext.include and pageContext.forward
These are like jsp:include and jsp:forward, but are more
convenient to use from within Java blocks.   pageContext
is another pre-defined variable that makes it easy to do certain operations
from within Java blocks.]

Here, if an error occurs during the processing of blx:setProperty,
we display the error and then include the GetName.jsp again so
user can correct the error.  If no errors occur, we automatically
forward the user to NextPage.jsp.

There is still a problem with the forms, the "age" shows up as zero
initially rather than being empty.  This can be fixed by adding "emptyInt=0"
to both the blx:getProperty and blx:setProperty tags
(bean fields should be initialized to 0.)   It happens that "0"
is not a valid value for age, so we can use "0" to mark empty strings. 
If "0" were a valid value for age, we could have added "emptyInt=-1"
(and made sure to initialize the bean fields to -1.)

Another small problem is that the "<HTML>" tag gets doubled if there
is an error and we end up including "GetName.jsp".  A more elegant
solution is to remove the out.println, and pass back the error as shown

<%
    if ( haveError ) {
        request.setAttribute( "errors",
                 errors.toString());
        pageContext.forward( "GetName.jsp" );
    } else
        pageContext.forward( "NextPage.jsp" );
%>

We can then do a "request.getAttribute" in the GetName.jsp,
and if the returned value is non-null, display the error. 
left as an exercise.

Exercise:  Read the documentation on Blazix or
another tag library, and use some tags from this library.

JSP Tutorial 10 Beans and Form processing

Forms are a very common method of interactions in web sites.  JSP
makes forms processing specially easy.

The standard way of handling forms in JSP is to define a "bean". 
This is not a full Java bean.  You just need to define a class that
has a field corresponding to each field in the form.  The class fields
must have "setters" that match the names of the form fields.  For
instance, let us modify our GetName.html to also collect email
address and age.

The new version of GetName.html is

<HTML>
<BODY>
<FORM METHOD=POST ACTION="SaveName.jsp">
What's your name? <INPUT TYPE=TEXT NAME=username SIZE=20><BR>
What's your e-mail address? <INPUT TYPE=TEXT NAME=email SIZE=20><BR>
What's your age? <INPUT TYPE=TEXT NAME=age SIZE=4>
<P><INPUT TYPE=SUBMIT>
</FORM>
</BODY>
</HTML>

To collect this data, we define a Java class with fields "username",
"email" and "age" and we provide setter methods "setUsername",
"setEmail" and "setAge", as shown.  A "setter" method
is just a method that starts with "set" followed by the name of
the field.  The first character of the field name is upper-cased. 
So if the field is "email", its "setter" method will
be "setEmail".  Getter methods are defined similarly, with
"get" instead of "set".   Note that the setters  (and getters)
must be public.


package user;

public class UserData {


    String username;
    String email;
    int age;

    public void setUsername( String value )
    {
        username = value;
    }

    public void setEmail( String value )
    {
        email = value;
    }

    public void setAge( int value )
    {
        age = value;
    }

    public String getUsername() { return username; }

    public String getEmail() { return email; }

    public int getAge() { return age; }


}

The method names must be exactly as shown.  Once you have defined
the class, compile it and make sure it is available in the web-server's
classpath.  The server may also define special folders where you can
place bean classes, e.g. with Blazix you can place them in the "classes"
folder.  If you have to change the classpath, the web-server would
need to be stopped and restarted if it is already running.  (If you
are not familiar with setting/changing classpath, see notes
on changing classpath
.)

Note that we are using the package name user, therefore
the file UserData.class must be placed in a folder named
user under the classpath entry.

Now let us change "SaveName.jsp" to use a bean to collect the
data.

<jsp:useBean id="user" class="user.UserData" scope="session"/>
<jsp:setProperty name="user" property="*"/> 
<HTML>
<BODY>
<A HREF="NextPage.jsp">Continue</A>
</BODY>
</HTML>

All we need to do now is to add the jsp:useBean tag and the jsp:setProperty
tag!  The useBean tag will look for an instance of the "user.UserData"
in the session.  If the instance is already there, it will update
the old instance.  Otherwise, it will create a new instance of user.UserData
(the instance of the user.UserData is called a bean), and put it in
the session.

The setProperty tag will automatically collect the input data, match
names against the bean method names, and place the data in the bean! 

Let us modify NextPage.jsp to retrieve the data from bean..

<jsp:useBean id="user" class="user.UserData" scope="session"/> 
<HTML>
<BODY>
You entered<BR>
Name: <%= user.getUsername() %><BR>
Email: <%= user.getEmail() %><BR>
Age: <%= user.getAge() %><BR>
</BODY>
</HTML>

Notice that the same useBean tag is repeated.  The bean is available
as the variable named "user" of class "user.UserData". 
The data entered by the user is all collected in the bean.

We do not actually need the "SaveName.jsp", the target of GetName.html
could have been NextPage.jsp, and the data would still be available
the same way as long as we added a jsp:setProperty tag. 
But in the next tutorial, we will actually use SaveName.jsp as
an error handler that automatically forwards the request to NextPage.jsp,
or asks the user to correct the erroneous data.

Exercise:  1)  Write a JSP/HTML set that allows a user
to enter the name of a system property, and then displays the value returned
by System.getProperty for that property name (handle errors appripriately.)  
2)  Go back to the exercises where you manually modified boolean variables. 
Instead of a boolean variable, make these come from a HIDDEN form field
that can be set to true or false.

JSP Tutorial 9 JSP Sessions

On a typical web site, a visitor might visit several pages and perform
several interactions.

If you are programming the site, it is very helpful to be able to associate
some data with each visitor.  For this purpose, "session"s
can be used in JSP.

A session is an object associated with a visitor.  Data can be
put in the session and retrieved from it, much like a Hashtable. 
A different set of data is kept for each visitor to the site.

Here is a set of pages that put a user's name in the session, and display
it elsewhere.  Try out installing and using these.

First we have a form, let us call it GetName.html

<HTML>
<BODY>
<FORM METHOD=POST ACTION="SaveName.jsp">
What's your name? <INPUT TYPE=TEXT NAME=username SIZE=20>
<P><INPUT TYPE=SUBMIT>
</FORM>
</BODY>
</HTML>

The target of the form is "SaveName.jsp", which saves the user's name in
the session.  Note the variable  "session".  This
is another variable that is normally made available in JSPs, just like
out
and request variables.  (In the @page directive, you can
indicate that you do not need sessions, in which case the "session" variable
will not be made available.)
<%
   String name = request.getParameter( "username" );
   session.setAttribute( "theName", name );
%>
<HTML>
<BODY>
<A HREF="NextPage.jsp">Continue</A>
</BODY>
</HTML>

The SaveName.jsp saves the user's name in the session, and puts a link
to another page, NextPage.jsp.

NextPage.jsp shows how to retrieve the saved name.

<HTML>
<BODY>
Hello, <%= session.getAttribute( "theName" ) %>
</BODY>
</HTML>

If you bring up two different browsers (not different windows of the same
browser), or run two browsers from two different machines, you can put
one name in one browser and another name in another browser, and both names
will be kept track of.

The session is kept around until a timeout period.  Then it is
assumed the user is no longer visiting the site, and the session is discarded.

Exercise:  Add another attribute "age" to the above example.

JSP Tutorial 8 JSP Tags

Another important syntax element of JSP are tags.  JSP tags do not
use <%, but just the < character. 
A JSP tag is somewhat like an HTML tag.  JSP tags can have a "start
tag", a "tag body" and an "end tag".  The start and end tag both use
the tag name, enclosed in < and > characters. 
The end starts with a / character after the < character. 
The tag names have an embedded colon character : in them, the
part before the colon describes the type of the tag.  For instance:
<some:tag>
body
</some:tag>

If the tag does not require a body, the start and end can be conveniently
merged together, as
<some:tag/>

Here by closing the start tag with a /> instead of > character, we are
ending the tag immediately, and without a body.  (This syntax convention
is the the same as XML.)

Tags can be of two types: loaded from an external tag library, or predefined
tags.   Predefined tags start with jsp: characters. 
For instance, jsp:include is a predefined tag that is used to
include other pages.

We have already seen the include directive.  jsp:include
is similar.  But instead of loading the text of the included file
in the original file, it actually calls the included target at run-time
(the way a browser would call the included target.  In practice, this
is actually a simulated request rather than a full round-trip between the
browser and the server).  Following is an example of jsp:include
usage

<HTML>
<BODY>
Going to include hello.jsp...<BR>
<jsp:include page="hello.jsp"/>
</BODY>
</HTML>

Try it and see what you get.  Now change the "jsp:include"
to "jsp:forward" and see what is the difference.  These two
predefined tags are frequently very useful.

Exercise:  Write a JSP to do either a forward or
an include, depending upon a boolean variable (hint:  The
concepts of mixing HTML and scriptlets work with JSP tags also!)

JSP Tutorial 7 JSP Declarations

The JSP you write turns into a class definition.  All the scriptlets
you write are placed inside a single method of this class.

You can also add variable and method declarations to this class. 
You can then use these variables and methods from your scriptlets and expressions.

To add a declaration, you must use the <%! and %>
sequences to enclose your declarations, as shown below.

<%@ page import="java.util.*" %>
<HTML>
<BODY>
<%!
    Date theDate = new Date();
    Date getDate()
    {
        System.out.println( "In getDate() method" );
        return theDate;
    }
%>
Hello!  The time is now <%= getDate() %>
</BODY>
</HTML>

The example has been created a little contrived, to show variable and method
declarations.

Here we are declaring a Date variable theDate, and the method
getDate
Both of these are available now in our scriptlets and expressions.

But this example no longer works!  The date will be the same, no
matter how often you reload the page.  This is because these are declarations,
and will only be evaluated once when the page is loaded!  (Just as
if you were creating a class and had variable initialization declared in
it.)

Exercise:  Modify the above example to add another function
computeDate
which re-initializes theDate.  Add a scriptlet that calls
computeDate
each time.


Note: Now that you know how to do this -- it is in general not a good idea to use variables as shown
here. The JSP usually will run as multiple threads of
one single instance. Different threads would interfere with
variable access, because it will be the same variable for all of
them. If you do have to use variables in JSP, you should use
synchronized access, but that hurts the performance.
In general, any data you need should go either in the session
object or the request object (these are introduced a little
later) if passing data between
different JSP pages. Variables you declare inside scriptlets
are fine, e.g. <% int i = 45; %> because these are declared
inside the local scope and are not shared.