analytics

Sunday, November 15, 2009

JSP Basics

Introduction

JavaServer Pages (JSP) builds web applications that serve dynamic content. JSP not only enjoys cross-platform and cross-Web-server support, but effectively melds the power of server-side Java technology with the features of static HTML pages.

JSP pages typically comprise of:

  • Static HTML/XML components.
  • Special JSP tags
  • Optionally, snippets of code written in the Java programming language called "scriptlets."

Consequently, you can create and maintain JSP pages by conventional HTML/XML tools.

It is important to note that the JSP specification is a standard extension defined on top of the Servlet API. Thus, it leverages all of your experience with servlets.

There are significant differences between JSP and servlet technology. Unlike servlets, which is a programmatic technology requiring significant developer expertise, JSP appeals to a much wider audience. It can be used not only by developers, but also by page designers, who can now play a more direct role in the development life cycle.

Another advantage of JSP is the inherent separation of presentation from content facilitated by the technology, due its reliance upon reusable component technologies like the JavaBeans component architecture and Enterprise JavaBeans technology.

JSP Advantages

Separation of static from dynamic content: With servlets, the logic for generation of the dynamic content is an intrinsic part of the servlet itself, and is closely tied to the static presentation templates responsible for the user interface. Thus, even minor changes made to the UI typically result in the recompilation of the servlet. This tight coupling of presentation and content results in brittle, inflexible applications. However, with JSP, the logic to generate the dynamic content is kept separate from the static presentation templates by encapsulating it within external JavaBeans components. These are then created and used by the JSP page using special tags and scriptlets. When a page designer makes any changes to the presentation template, the JSP page is automatically recompiled and reloaded into the web server by the JSP engine.

Write Once Run Anywhere: JSP technology brings the "Write Once, Run Anywhere" paradigm to interactive Web pages. JSP pages can be moved easily across platforms, and across web servers, without any changes.

JSP or Servlets?

It is true that both servlets and JSP pages have many features in common, and can be used for serving up dynamic web content. Naturally, this may cause some confusion as to when to opt for one of the technologies over the other. Luckily, Sun's J2EE Blueprints offers some guidelines towards this.

According to the Blueprints, use servlets strictly as a web server extension technology. This could include the implementation of specialized controller components offering services like authentication, database validation, and so forth. It is interesting to note that what is commonly known as the "JSP engine" itself is a specialized servlet running under the control of the servlet engine. Since JSP only deals with textual data, you will have to continue to use servlets when communicating with Java applets and applications.

Use JSP to develop typical web applications that rely upon dynamic content. JSP should also be used in place of proprietary web server extensions like server-side includes as it offers excellent features for handling repetitive content.

JSP Architecture

Typically, JSP pages are subject to a translation phase and a request processing phase. The translation phase is carried out only once, unless the JSP page changes, in which case it is repeated. Assuming there were no syntax errors within the page, the result is a JSP page implementation class file that implements the Servlet interface, as shown below.

[JSP Translation Phase]

The translation phase is typically carried out by the JSP engine itself, when it receives an incoming request for the JSP page for the first time. Note that the JSP 1.1 specification also allows for JSP pages to be precompiled into class files. Precompilation may be especially useful in removing the start-up lag that occurs when a JSP page delivered in source form receives the first request from a client. Many details of the translation phase, like the location where the source and class files are stored are implementation dependent. The source for the class file generated by Tomcat for this example JSP page (shown in the above figure) is as follows:

package jsp;


import javax.servlet.*;
import javax.servlet.http.*;
import javax.servlet.jsp.*;
import javax.servlet.jsp.tagext.*;
import java.io.PrintWriter;
import java.io.IOException;
import java.io.FileInputStream;
import java.io.ObjectInputStream;
import java.util.Vector;
import org.apache.jasper.runtime.*;
import java.beans.*;
import org.apache.jasper.JasperException;
import java.text.*;
import java.util.*;

public class _0005cjsp_0005cjsptest_0002ejspjsptest_jsp_0
extends HttpJspBase {

static {
}
public _0005cjsp_0005cjsptest_0002ejspjsptest_jsp_0( ) {
}

private static boolean _jspx_inited = false;
public final void _jspx_init() throws JasperException {
}

public void _jspService(HttpServletRequest request,
HttpServletResponse response)
throws IOException, ServletException {

JspFactory _jspxFactory = null;
PageContext pageContext = null;
HttpSession session = null;
ServletContext application = null;
ServletConfig config = null;
JspWriter out = null;
Object page = this;
String _value = null;
try {
if (_jspx_inited == false) {
_jspx_init();
_jspx_inited = true;
}
_jspxFactory = JspFactory.getDefaultFactory();
response.setContentType("text/html");
pageContext = _jspxFactory.getPageContext(this,
request,response, "", true, 8192, true);

application = pageContext.getServletContext();
config = pageContext.getServletConfig();
session = pageContext.getSession();
out = pageContext.getOut();
// begin
out.write("\r\n\r\n\r\n");
// end
// begin [file="E:\\jsp\\jsptest.jsp";from=(3,2);to=(5,0)]
Date d = new Date();
String today = DateFormat.getDateInstance().format(d);
// end
// begin
out.write("\r\nToday is: \r\n ");
// end
// begin [file="E:\\jsp\\jsptest.jsp";from=(7,8);to=(7,13)]
out.print(today);
// end
// begin
out.write("
\r\n\r\n\r\n");
// end
} catch (Exception ex) {
if (out.getBufferSize() != 0)
out.clear();
pageContext.handlePageException(ex);
} finally {
out.flush();
_jspxFactory.releasePageContext(pageContext);
}
}
}
The JSP page implementation class file extends HttpJspBase, which in turn implements the Servlet interface. Observe how the service method of this class, _jspService(), essentially inlines the contents of the JSP page. Although _jspService() cannot be overridden, the developer can describe initialization and destroy events by providing implementations for the jspInit() and jspDestroy() methods within their JSP pages.

Once this class file is loaded within the servlet container, the _jspService() method is responsible for replying to a client's request. By default, the _jspService() method is dispatched on a separate thread by the servlet container in processing concurrent client requests, as shown below:

[JSP Request Processing Phase]


JSP Access Models

The early JSP specifications advocated two philosophical approaches, popularly known as Model 1 and Model 2 architectures, for applying JSP technology. These approaches differ essentially in the location at which the bulk of the request processing was performed, and offer a useful paradigm for building applications using JSP technology.

Consider the Model 1 architecture, shown below:

[Model1 Architecture]


In the Model 1 architecture, the incoming request from a web browser is sent directly to the JSP page, which is responsible for processing it and replying back to the client. There is still separation of presentation from content, because all data access is performed using beans.

Although the Model 1 architecture is suitable for simple applications, it may not be desirable for complex implementations. Indiscriminate usage of this architecture usually leads to a significant amount of scriptlets or Java code embedded within the JSP page, especially if there is a significant amount of request processing to be performed. While this may not seem to be much of a problem for Java developers, it is certainly an issue if your JSP pages are created and maintained by designers--which is usually the norm on large projects. Another downside of this architecture is that each of the JSP pages must be individually responsible for managing application state and verifying authentication and security.


Model2 Architecture


The Model 2 architecture, shown above, is a server-side implementation of the popular Model/View/Controller design pattern. Here, the processing is divided between presentation and front components. Presentation components are JSP pages that generate the HTML/XML response that determines the user interface when rendered by the browser. Front components (also known as controllers) do not handle any presentation issues, but rather, process all the HTTP requests. Here, they are responsible for creating any beans or objects used by the presentation components, as well as deciding, depending on the user's actions, which presentation component to forward the request to. Front components can be implemented as either a servlet or JSP page.

The advantage of this architecture is that there is no processing logic within the presentation component itself; it is simply responsible for retrieving any objects or beans that may have been previously created by the controller, and extracting the dynamic content within for insertion within its static templates. Consequently, this clean separation of presentation from content leads to a clear delineation of the roles and responsibilities of the developers and page designers on the programming team. Another benefit of this approach is that the front components present a single point of entry into the application, thus making the management of application state, security, and presentation uniform and easier to maintain.


JSP Syntax Basics

JSP syntax is fairly straightforward, and can be classified into directives, scripting elements, and standard actions.

Directives

JSP directives are messages for the JSP engine. They do not directly produce any visible output, but tell the engine what to do with the rest of the JSP page. JSP directives are always enclosed within the <%@ ... %> tag. The two primary directives are page and include. JSP 1.1 also provides the taglib directive.

Page Directive

Typically, the page directive is found at the top of almost all of your JSP pages. There can be any number of page directives within a JSP page, although the attribute/value pair must be unique. Unrecognized attributes or values result in a translation error. For example,

<%@ page import="java.util.*, com.foo.*" buffer="16k" %>


makes available the types declared within the included packages for scripting and sets the page buffering to 16K.

Include Directive

The include directive lets you separate your content into more manageable elements, such as those for including a common page header or footer. The page included can be a static HTML page or more JSP content. For example, the directive:

<%@ include file="copyright.html" %>

can be used to include the contents of the indicated file at any location within the JSP page.


Tag libraries


JSP’s offer a unique feature of “Tag Libraries”. Simply put, these are custom defined JSP tags. They are basically meant for componentizing presentation level logic. They are very similar to beans except the fact that Beans are used to separate Business logic.

Every tag is mapped to a particular class file which is executed whenever the tag is encountered in an JSP file.

The general syntax :

<%@ taglib uri=“ - - - - - ” prefix = “ - - - ” %>

There are two things to remember while using TAGLIB’s :

The Class file should be created and it should be deployed in the Servlet folder of the web server.

The class file should implement the Tag and BodyTag interfaces.

The mapping of a particular tag to a particular class file should be done in the taglib.tld file.

The tag is then ready to be used in the JSP file !!

The taglib file forms the central description for the tag library :

This file is an XML document that defines the tag’s operation.

It maps the tag name on the page to the implementing class.

It defines inputs to the class.

It references the helper class that provides details of any output variables set by the tag class.

This Tag and Bodytag have some methods, these all methods are callback methods.

Tag methods: doStartTag()
doEndTag()

Body Tag : doAfterBody()

Let’s have small example to display Hello World :

1. First we write simple jsp file

<% @ taglib uri=”/taglib.tld” prefix=”nt” %>

2. It will look for file specified in uri attribute,that file will be

3. Next this will look for Helloworld .class file will be

Package mytags;

Import javax.servlet.jsp.*;
Import javax.servlet.jsp.tagtext.*;

Public class Helloworld implements Tag {

private PageContext pagecontext;
private Tag parent;

public int doStartTag() throws JSPException {
return SKIP_BODY;
}

public int doEndTag () throws JSPException {
try{
pageContext.getOut().write(“Hello World”);
} catch(java.io.Exception ex) {
throw new JSPException(“IO Exception”);
}
return EVAL_PAGE;
}

public void release (){}

public void setPageContext(pageContext p) {
pageContext=p;
}

public void setParent(Tag t) {
parent = t;
}

public void getParent() {
return parent;
}

}

Here in first .jsp file we are writing tag.But name and properties of this tag we are writing in .tld file. And whatever task that tag is going to perform is written in .class file which has been called by .tld file.

So by using taglib we can create our own defined tags.


Scripting elements

Declarations

JSP declarations let you define page-level variables to save information or define supporting methods that the rest of a JSP page may need. While it is easy to get led away and have a lot of code within your JSP page, this move will eventually turn out to be a maintenance nightmare. For that reason, and to improve reusability, it is best that logic-intensive processing is encapsulated as JavaBean components.

Declarations are found within the <%! ... %> tag. Always end variable declarations with a semicolon, as any content must be valid Java statements:

<%! int i=0; %>

You can also declare methods. For example, you can override the initialization event in the JSP life cycle by declaring:

<%! public void jspInit() { 	//some initialization code    } %>


Expressions

With expressions in JSP, the results of evaluating the expression are converted to a string and directly included within the output page. Typically expressions are used to display simple values of variables or return values by invoking a bean's getter methods. JSP expressions begin within <%= ... %> tags and do not include semicolons:

 <%= fooVariable %>

<%= fooBean.getName() %>

Scriptlets

JSP code fragments or scriptlets are embedded within <% ... %> tags. This Java code is run when the request is serviced by the JSP page. You can have just about any valid Java code within a scriptlet, and is not limited to one line of source code. For example, the following displays the string "Hello" within H1, H2, H3, and H4 tags, combining the use of expressions and scriptlets:

<% for (int i=1; i<=4; i++) { %>

<%=i%>>Hello<%=i%>>
<% } %>

Comments

Although you can always include HTML comments in JSP pages, users can view these if they view the page's source. If you don't want users to be able to see your comments, embed them within the <%-- ... --%> tag:

<%-- comment for server side only --%>

A most useful feature of JSP comments is that they can be used to selectively block out scriptlets or tags from compilation. Thus, they can play a significant role during the debugging and testing process.


Object Scopes

Before we look at JSP syntax and semantics, it is important to understand the scope or visibility of Java objects within JSP pages that are processing a request. Objects may be created implicitly using JSP directives, explicitly through actions, or, in rare cases, directly using scripting code. The instantiated objects can be associated with a scope attribute defining where there is a reference to the object and when that reference is removed. The following diagram indicates the various scopes that can be associated with a newly created object:

[JSP Object Scopes]


JSP Implicit Objects

As a convenience feature, the JSP container makes available implicit objects that can be used within scriptlets and expressions, without the page author first having to create them. These objects act as wrappers around underlying Java classes or interfaces typically defined within the Servlet API. The nine implicit objects:

  • request: represents the HttpServletRequest triggering the service invocation. Request scope.
  • response: represents HttpServletResponse to the request. Not used often by page authors. Page scope.
  • pageContext: encapsulates implementation-dependent features in PageContext. Page scope.
  • application: represents the ServletContext obtained from servlet configuration object. Application scope.
  • out: a JspWriter object that writes into the output stream. Page scope.
  • config: represents the ServletConfig for the JSP. Page scope.
  • page: synonym for the "this" operator, as an HttpJspPage. Not used often by page authors. Page scope.
  • session: An HttpSession. Session scope. More on sessions shortly.
  • exception: the uncaught Throwable object that resulted in the error page being invoked. Page scope.

Note that these implicit objects are only visible within the system generated _jspService() method. They are not visible within methods you define yourself in declarations.


Synchronization Issues

By default, the service method of the JSP page implementation class that services the client request is multithreaded. Thus, it is the responsibility of the JSP page author to ensure that access to shared state is effectively synchronized. There are a couple of different ways to ensure that the service methods are thread-safe. The easy approach is to include the JSP page directive:

<%@ page isThreadSafe="false" %>

This causes the JSP page implementation class to implement the SingleThreadModel interface, resulting in the synchronization of the service method, and having multiple instances of the servlet to be loaded in memory. The concurrent client requests are then distributed evenly amongst these instances for processing in a round-robin fashion, as shown below:

[Thread-safe JSPs]

The downside of using this approach is that it is not scalable. If the wait queue grows due to a large number of concurrent requests overwhelming the processing ability of the servlet instances, then the client may suffer a significant delay in obtaining the response.

A better approach is to explicitly synchronize access to shared objects (like those instances with application scope, for example) within the JSP page, using scriptlets:

<% synchronized (application) {   SharedObject foo = (SharedObject) 	application.getAttribute("sharedObject");   foo.update(someValue);   application.setAttribute("sharedObject",foo); } %>



Exception Handling

JSP provides a rather elegant mechanism for handling runtime exceptions. Although you can provide your own exception handling within JSP pages, it may not be possible to anticipate all situations. By making use of the page directive's errorPage attribute, it is possible to forward an uncaught exception to an error handling JSP page for processing. For example,

<%@ page isErrorPage="false" errorPage="errorHandler.jsp" %>

informs the JSP engine to forward any uncaught exception to the JSP page errorHandler.jsp. It is then necessary for errorHandler.jsp to flag itself as a error processing page using the directive:

<%@ page isErrorPage="true" %>

This allows the Throwable object describing the exception to be accessed within a scriptlet through the implicit exception object.


Session Management



By default, all JSP pages participate in an HTTP session. The HttpSession object can be accessed within scriptlets through the session implicit JSP object. Sessions are a good place for storing beans and objects that need to be shared across other JSP pages and servlets that may be accessed by the user. The session objects is identified by a session ID and stored in the browser as a cookie. If cookies are unsupported by the browser, then the session ID may be maintained by URL rewriting. Support for URL rewriting is not mandated by the JSP specification and is supported only within a few servers. Although you cannot place primitive data types into the session, you can store any valid Java object by identifying it by a unique key. For example:

<% Foo foo = new Foo(); session.putValue("foo",foo); %>

makes available the Foo instance within all JSP pages and servlets belonging to the same session. The instance may be retrieved within a different JSP page as:

<% Foo myFoo = (Foo) session.getValue("foo"); %>

The call to session.getValue() returns a reference to the generic Object type. Thus it is important to always cast the value returned to the appropriate data type before using it. It is not mandatory for JSP pages to participate in a session; they may choose to opt out by setting the appropriate attribute of the page directive:

<%@ page session="false" %>

There is no limit on the number of objects you can store into the session. However, placing large objects into the session may degrade performance, as they take up valuable heap space. By default, most servers set the lifetime of a session object to 30 minutes, although you can easily reset it on a per session basis by invoking setMaxInvalidationInterval(int secs) on the session object. The figure below highlights the general architecture of session management:

[JSP Session Management]

The JSP engine holds a live reference to objects placed into the session as long as the session is valid. If the session is invalidated or encounters a session timeout, then the objects within are flagged for garbage collection.

Jsp Actions

JSP actions use constructs in XML syntax to control the behavior of the servlet engine. You can dynamically insert a file, reuse JavaBeans components, forward the user to another page, or generate HTML for the Java plugin. Available actions include:


  • jsp:include - Include a file at the time the page is requested.
  • jsp:useBean - Find or instantiate a JavaBean.
  • jsp:setProperty - Set the property of a JavaBean.

  • jsp:getProperty - Insert the property of a JavaBean into the output.
  • jsp:forward - Forward the requester to a new page.
  • jsp:plugin - Generate browser-specific code that makes an OBJECT or EMBED tag for the Java plugin.

Using JavaBean Components

The component model for JSP technology is based on JavaBeans component architecture. JavaBeans components are nothing but Java objects which follow a well-defined design/naming pattern: the bean encapsulates its properties by declaring them private and provides public accessor (getter/setter) methods for reading and modifying their values.

Before you can access a bean within a JSP page, it is necessary to identify the bean and obtain a reference to it. The tag tries to obtain a reference to an existing instance using the specified id and scope, as the bean may have been previously created and placed into the session or application scope from within a different JSP page. The bean is newly instantiated using the Java class name specified through the class attribute only if a reference was not obtained from the specified scope. Consider the tag:



In this example, the Person instance is created just once and placed into the session. If this useBean tag is later encountered within a different JSP page, a reference to the original instance that was created before is retrieved from the session.

The tag can also optionally include a body, such as



<% user.setDate(DateFormat.getDateInstance( ).format(new Date())); //etc.. %>


Any scriptlet (or tags, which are explained shortly) present within the body of a tag are executed only when the bean is instantiated, and are used to initialize the bean's properties.

Once you have declared a JavaBean component, you have access to its properties to customize it. The value of a bean's property is accessed using the tag. With the tag, you specify the name of the bean to use (from the id field of useBean), as well as the name of the property whose value you are interested in. The actual value is then directly printed to the output:



Changing the property of a JavaBean component requires you to use the tag. For this tag, you identify the bean and property to modify and provide the new value:



or

">

When developing beans for processing form data, you can follow a common design pattern by matching the names of the bean properties with the names of the form input elements. You also need to define the corresponding getter/setter methods for each property within the bean. The advantage in this is that you can now direct the JSP engine to parse all the incoming values from the HTML form elements that are part of the request object, then assign them to their corresponding bean properties with a single statement, like this:



This runtime magic is possible through a process called introspection, which lets a class expose its properties on request. The introspection is managed by the JSP engine, and implemented through the Java reflection mechanism. This feature alone can be a lifesaver when processing complex forms containing a significant number of input elements.

If the names of your bean properties do not match those of the form's input elements, they can still be mapped explicitly to your property by naming the parameter as:





Forwarding Requests

With the tag, you can redirect the request to any JSP, servlet, or static HTML page within the same context as the invoking page. This effectively halts processing of the current page at the point where the redirection occurs, although all processing up to that point still takes place:

The invoking page can also pass the target resource bean parameters by placing them into the request, as shown in the diagram:

[JSP Forwarding]

A tag may also have jsp:param subelements that can provide values for some elements in the request used in the forwarding:

">

Request Chaining

Request chaining is a powerful feature and can be used to effectively meld JSP pages and servlets in processing HTML forms, as shown in the following figure:

[JSP Including]

Consider the following JSP page, say Bean1.jsp, which creates a named instance fBean of type FormBean, places it in the request, and forwards the call to the servlet JSP2Servlet. Observe the way the bean is instantiated--here we automatically call the bean's setter methods for properties which match the names of the posted form elements, while passing the corresponding values to the methods.

The servlet JSP2Servlet now extracts the bean passed to it from the request, makes changes using the appropriate setters, and forwards the call to another JSP page Bean2.jsp using a request dispatcher. Note that this servlet, acting as a controller, can also place additional beans if necessary, within the request.

public void doPost (HttpServletRequest request,

HttpServletResponse response) {
try {
FormBean f = (FormBean) request.getAttribute
("fBean");
f.setName("Mogambo");
// do whatever else necessary
getServletConfig().getServletContext().
getRequestDispatcher("/jsp/Bean2.jsp").
forward(request, response);
} catch (Exception ex) {
. . .
}
}

The JSP page Bean2.jsp can now extract the bean fBean (and whatever other beans that may have been passed by the controller servlet) from the request and extract its properties.






Including Requests

The tag can be used to redirect the request to any static or dynamic resource that is in the same context as the calling JSP page. The calling page can also pass the target resource bean parameters by placing them into the request, as shown in the diagram:

[JSP Including]

For example:



not only allows shoppingcart.jsp to access any beans placed within the request using a tag, but the dynamic content produced by it is inserted into the calling page at the point where the tag occurs. The included resource, however, cannot set any HTTP headers, which precludes it from doing things like setting cookies, or else an exception is thrown.

No comments:

Post a Comment