Return to index

logo

 

JSP - Part 1
Scriptlets,
Expressions
and Beans



TJI will support JSP in four phases. Currently, the first 3 phases are complete.

  • Phase 1 : Scriptlets, expressions, page directives, beans, jsp:include and jsp:forward actions
  • Phase 2 : Custom Tags (based on the latest JSP 2.0 API and class SimpleTag)
  • Phase 3 : Most uses of the Expression Language and the Standard Tag Library (core)
  • Phase 4 : Support for the tag library descriptor and other advanced features.

This document describes those features introduced in phase 1.

It is recommended that you take a look at the example JSP projects available from our website's 'Resources' page. These include a JSP version of 'Duke's Book Store' to parallel the servlet based version.

TJI makes the development of JSP projects easy by providing an integrated Web Server that requires no setup and that updates automatically when a JSP page or tag handler is changed; there is no need to reload it by hand or by button, and still less need to restart the server!

The Java IDE jar (ide.jar) includes all the required JSP packages - so users without an 'Enterprise Edition' SDK can develop and run JSP projects without needing to download any extras.

JSP projects run on a server. Normally (after deployment), this will be a server on the web or a network. However, during development your JSP projects can run in the integrated Kinabaloo Web Server and you can see their results (responses) either in a browser (such as Netscape or Internet Explorer) or in the integrated Web Browser (the 'Web' tab of The Java IDE).

If you set the starting page (servlet, JSP or HTML) - by setting it as the project's 'main' or 'html' file, the integrated Web Browser will automatically be selected and then load that page when you select 'Run'.

If you wish to use TomCat or other web server you may do so by copying your project to the the required location. For example, project JSP1 is located in TJI at homepath/web/JSP1. Simply copy directory JSP1 and paste it in (i.e. under) the webapps directory of your TomCat installation; the sub-directory structure (WEB-INF/classes) is the same in TJI and TomCat. TomCat handles the core tags automatically. You will need to copy any custom tags used to TomCat and set up TomCat to use them by writing an XML structured Tag Library Descriptor (.tld) file. You may also need to modify TomCat's web.xml file. See the TomCat documentation and examples for further help on this topic.

 

Introduction

JavaServer Pages (JSP) lets you separate the dynamic part of your pages (the 'business logic' - java code) from the static HTML (the 'presentation'). Whereas servlets are written as java source files which produce HTML output, JSP files are basically HTML files - but dynamic ones that are altered by Java code that is embedded using special tags. The most basic types of JSP tag start with "<%" and end with "%>". A JSP enabled server will handle these JSP tags and a modified version of the HTML will then be sent to the client's browser.

For example, here is a section of a JSP page that results in something like "Thanks for ordering TJI !" for a URL of:

http://host/OrderConfirm.jsp?product=TJIversion1.2

<html>
     <body>
          <p>
               Thanks for ordering :
               <b>
                    <%= request.getParameter("product") %>
               </b>
               ...

JSP files have a .jsp extension, and typically are installed in the same location on the server as html files. Although what you write often looks more like a regular HTML file than a servlet, behind the scenes the JSP page is converted to a normal servlet, with the static HTML simply being sent out to the browser (if the coding dictates). This conversion process is called 'translation'.

On a dedicated server, this translation is normally done the first time that the page is requested, and developers can simply request the page themselves when first installing it if they want to be sure that the first real user doesn't get a momentary delay while the JSP page is translated to a servlet and the servlet is compiled and loaded. (Note that many Web servers let you define 'aliases' that so that a URL that appears to reference an HTML file really points to a servlet or JSP page.)

In TJI, a JSP page is translated to a servlet and that servlet compiled when the project containing it is built (as required). If the TJI Web Server detects that a requested JSP page has not yet been translated and compiled - or that the JSP source file has since been changed - it too will translate and compile the JSP page. At this point, all loaded servlets are reloaded.

In many cases, a large percent of your JSP page just consists of static HTML, known as 'template text'. In just about all respects, this HTML looks just like normal HTML, follows all the same syntax rules, and is simply "passed through" to the client by the servlet created to handle the page.

Aside from the regular HTML, there are three main types of JSP constructs that you can embed in a JSP page:

  • scripting elements (or 'scriptlets'),
  • 'directives', and
  • 'actions'.

Scripting elements let you specify Java code that will become part of the resultant servlet, directives let you control the overall structure of the servlet, and actions let you specify existing components that should be used, and otherwise control the behavior of the JSP engine. To simplify the scripting elements, you have access to a number of predefined variables such as request in the snippet above.

Note that phase 1 of TJI's support for JSP covers most of the features of version 1.0 of the JSP specification. Version 2.0 of JSP takes the functionality of JSP further, allowing scriptlets to be off page and referenced by simple looking tags. This will be covered in TJI's JSP parts 2 and 3.

Note that well-written JSP pages try to avoid using scriptlets, and rely more on tags and beans to much better separate business logic from presentation. By using the standard tags and custom tags, one can better separate the java code into off-page 'tag handlers' which are called automatically by the special HTML-like JSP tags. This is a natural progression for JSP. More on this in part 2.

 

Predefined variables (Implicit Objects)

request : HttpServletRequest

This is the HttpServletRequest object associated with the page request, and lets you look at the request parameters (using method getParameter), the request type (GET, POST, HEAD, etc.), and the incoming HTTP headers (cookies, Referer, etc.).

response : HttpServletResponse

This is the HttpServletResponse object associated with the response to the client.

out : PrintWriter

This is the PrintWriter object used to send output to the client. Note that out is used almost exclusively in scriptlets, since JSP expressions automatically get placed in the output stream, and thus rarely need to refer to out explicitly.

session : HttpSession

This is the HttpSession object associated with the request. In JSP, sessions are created automatically, so this variable is created even if there was no incoming session reference.

application : ServletContext

This is the ServletContext object as obtained using :
getServletConfig().getServletContext().

config : ServletConfig

This is the ServletConfig object for this page.

pageContext : PageContext

PageContext extends JspContext to provide useful context information - access to all the namespaces associated with a JSP page, and access to several page attributes.

The predefined variables are available inside both scriptlets and expressions.

Comments

<%-- comment --%>

Everything inside - even other tags - is ignored.

Expressions

<%= java expression %>

or

<jsp:expression> java expression </jsp:expression>

An expression like this is evaluated and sent to the output stream.
Thus a JSP expression is used to insert Java values directly into the output.

That is, the Java expression is evaluated, converted to a string, and inserted into the page. This evaluation is performed at run-time (when the page is requested and the expression is processed), and thus has full access to information about the request.

For example, the following shows the date/time that the page was requested:

Current time: <%= new java.util.Date() %>

If class java.util.Date has been imported, one can simply write :

Current time: <%= new Date() %>

Here's another example, that uses the predefined variable request :

Your hostname is : <jsp:expression> request.getRemoteHost() </jsp:expression>

A second use of expressions - with custom tags - is described in JSP Part 2.

Scriptlets

<% java code %>

or

<jsp:scriptlet> java code </jsp:scriptlet>

The java code is inserted in the servlet's service / doGet method.

If you want to do something more complex than insert a simple expression, JSP scriptlets let you insert arbitrary code into the servlet method that will be built to generate the page.

Scriptlets have access to the same automatically defined variables as expressions. So, for example, if you want output to appear in the resultant page, you would use the predefined variable out.

<%     
String     queryData = request.getQueryString();
out.println("Attached     GET data: " + queryData); 
%>

Note that code inside a scriptlet gets inserted exactly as written, and any static HTML (template text) before or after a scriptlet gets converted to print statements. This means that scriptlets need not contain complete Java statements, and blocks left open can affect the static HTML outside of the scriptlets.

For example, the following JSP fragment, containing mixed template text and scriptlets :

<% if (Math.random() < 0.5) { %>
  Have a <B>nice</B> day!
<% } else { %>
  Have a <B>lousy</B> day!
<% } %> 

will get converted to something like:

if (Math.random() < 0.5) { 
   out.println("Have a <B>nice</B> day!");
} else { 
   out.println("Have a <B>lousy</B> day!");
} 

 

Declarations

<%! java code %>

or

<jsp:declaration> java code </jsp:declaration>

Notice the exclamation mark! Code is inserted in the servlet outside of the service / doGet method - that is, it will persist as long as the servlet is loaded.

In other words, a JSP declaration lets you define methods or fields that get inserted into the main body of the servlet class (outside of the method processing the request). Hence this is a way to define persistent variables and add methods.

Since declarations do not generate any output, they are normally used in conjunction with JSP expressions or scriptlets. For example, here is a JSP fragment that prints out the number of times the current page has been requested since the server was last booted (or the servlet class was changed and reloaded):

<%! private int accessCount = 0; %>

...

Accesses to page since server reboot:

<%= ++accessCount %>

 

Page Directives

<%@ page ... %>

The two page directives currently supported by TJI are :

<%@ page import="package.class" %>

Multiple imports can be declared in one tag - for example :

<%@ page import="java.util.*, java.net.URL" %>

and


<%@ page include
file="relative_URL">

Only HTML files can be included.

The page directive to include a file will include that file
at translation time, not at run time. If you need to be able to include the latest version of a file, you should use jsp:include instead. And if you need to include a JSP file, you also must use the jsp:include action.

 

jsp:include Action

<jsp:include page="relative URL" />

The included file should be either an html or jsp file; TJI supports both.

This action lets you insert files into the page as it is being generated at run-time ('dynamic include').

Unlike the include directive, which inserts the file at the time the JSP page is translated into a servlet, this action inserts the file at the time the page is requested. This pays a small penalty in efficiency, but it gains significantly in flexibility. For example, imagine a JSP page that inserts two different snippets into a "What's New?" Web page. Each time the headlines change, authors only need to update the two included files and can leave the main JSP page unchanged.

 

jsp:forward Action

<jsp:forward page="relative URL" />

The forwarded file should be either an html or jsp file.

This action lets you forward the request to another page. It has a single attribute, page, which should consist of a relative URL. This could be a static value, or could be computed at request time, as in the two examples below :

<jsp:forward page="/utils/errorReporter.jsp" />

<jsp:forward page="<%= someJavaExpression %>" />

 

jsp:useBean Action

<jsp:useBean id="beanName" class="[package.]class" [scope="x"] />

Finds or creates an instance of (creates if not already created with the given id) the specified java bean class and names this instance the value of id.

For example :

<jsp:useBean id="bd" class="BookDB" />

The bean will exist for the duration of the specified scope. If no scope is specified, the default scope is used - 'page' scope. The four possible values are : "page", "request", "session" and "application".

* Page scope is the briefest scope - the bean exists only as long as the declaring page is active.

* Request scope allows the bean to exist as long as the request, so it will exist in a page forwarded to, or after return from an include.

* Session scope ties the bean to a particular user for a certain amount of time - typically 2 hours - as defined by cookie life or server setting.

* Application scope is 'forever' - well, until the server is rebooted.

Even if a bean's scope is defined as "session", say, you will still need to place a jsp:useBean tag on each page that will use it. This is why the tag name is useBean and not createBean. A new bean is created only when a bean with the specified id does not already exist - such as would be the case after a session expires for a session-scope bean, whereupon a new bean will be created by jsp:useBean.

You can read bean properties using a JSP expression, by using a scriptlet that calls the appropriate getXxx method, or more commonly, by using the jsp:getProperty action.

Note: jsp:useBean must be called before trying to set or get its properties.

 

jsp:setProperty Action

<jsp:setProperty name="beanName" property="prop" value="val" />

Sets bean properties, by calling the appropriate setter method of the bean.

For example, if the property is 'size' the bean's setSize() method will be called.

<jsp:setProperty name="bd" property="size" value="100" />

Special Case :

<jsp:setProperty name="bd" property="*" />

When the property is set to "*", it means "set every bean property whose name matches each of the request parameters". Request parameters are mostly set by HTML/JSP forms and so this useful functionality allows form data to be stored in a Java Bean very simply. The Java Bean can then perform complex validation or other processing on the data.

 

jsp:getProperty Action

<jsp:getProperty name="beanName" property="prop" />

This element retrieves the value of a bean property, converts it to a string, and inserts it into the output. The two required attributes are name, the name of a bean previously referenced with jsp:useBean (its id, not class), and property, the property whose value should be retrieved and inserted into the output.

Here is an example :

<jsp:useBean  id="itemBean" class="ItemBean" scope="session" />
...
<ul>
<li>
Number of items: 
<jsp:getProperty  name="itemBean"  property="numItems" />
</li>
<li>
Cost of each item:
<jsp:getProperty  name="itemBean" property="unitCost" />
</li>
</ul>
...


Here is another simple example that loads a Bean and sets and then gets a simple String parameter.

<html>
    <body>
        <jsp:useBean id="test" class="SimpleBean" session="request" />
        <jsp:setProperty name="test" property="message" value="Hello WWW" />
        <p align="center">
            Message: 
            <b>
                <jsp:getProperty name="test" property="message" />
            </b>
        </p>
    </body>
</html>


And here is the source code for the bean used in the above JSP page :

public class SimpleBean {
     private String message = "No message specified";

 

     public String getMessage() {
          return(message);
     }

 

     public void setMessage(String message) {
          this.message = message;
     }
}


If you are new to Java Beans, you'll notice that the above Bean is just a normal class. That's because essentially a java bean
is a normal class, but one that follows certain conventions; the main ones are the use of 'getter' and 'setter' methods for 'variables', and having a no-parameter constructor. The convention for 'getter' and 'setter' methods is that if a field has the identifier abc, then the method names must be getAbc and setAbc.

This might make the use of Beans seem trivial - but remember that a 'getter' method could retrieve the returned object / value from a database or be calculated in some other way; a 'setter' method can validate the object or value that it receives. Hence, although a bean seems like a simple black box from the outside, it can be complex on the inside. Indeed, that's the whole purpose of Java Beans - to hide complexity and present a standard way of interacting with the outside world.

Return to index