Showing posts with label jsp. Show all posts
Showing posts with label jsp. Show all posts

Saturday, May 31, 2008

All About JSP : TagHandler

The package javax.servlet.jsp.tagext package has interfaces
  1. Tag
  2. IterationTag
  3. BodyTag

There are classes provided in the javax.servlet.jsp.tagext package which provide default implementation for the above interfaces :
  1. TagSupport
  2. BodyTagSupport
THERE s no IterationTagSupport

Tag interface
The six methods which Tag interface provides and which we have to implement are :
  1. setPageContext(PageContext pc)
  2. setParent(Tag parent)
  3. getParent()
  4. doStartTag()
  5. doEndTag()
  6. release()
Above six methods are a must.
If there are attributes in tag then we have additional setter & getter for them.

Tag Interface Lifecycle
  1. The setPageContext() method : is the first method that is called in the life cycle of a custom tag.
  2. The setParent() and getParent() methods : are used when custom tags are nested one inside the other. The JSP container calls the setParent() method on the child tag and passes it a reference to the parent tag. The getParent() method is usually called by one of the child tags and not directly by the JSP container.
  3. the setters of attributes are called
  4. doStartTag() method : After setting up the tag with appropriate references by calling the setPageContext(), setParent(), and setter methods, the container calls the doStartTag() method on the tag. After initialization, the doStartTag() method decides whether or not to continue evaluating its body content. As a result, it returns one of the two integer constants defined in the Tag interface: EVAL_BODY_INCLUDE or SKIP_BODY. May throw a JSPException.
  5. doEndTag() method : After the body of the tag is evaluated or skipped (depending on the return value of doStartTag()), the container calls the doEndTag() method. May throw a JSPException.
  6. release() method : Finally, the container calls the release() method on the handler class when the tag handler object is no longer required. A custom tag may occur multiple times on a JSP page. A single instance of the tag handler may be used to handle all of these occurrences. The JSP container calls the release() method on the handler class when the handler object is no longer required. It is important to note that this method is not called after every call to doEndTag().

IterationTag Interface

The IterationTag interface extends the Tag interface and allows us to include the body content multiple times, in a way that is similar to the loop functionality of a programming language. The IterationTag interface declares one method and one constant

int doAfterBody() : This method is called after each evaluation of the tag body. It can return either of two values: IterationTag.EVAL_BODY_AGAIN or Tag.SKIP_BODY. The return value determines whether or not the body needs to be reevaluated.

EVAL_BODY_AGAIN : Return value for doAfterBody(). This constant instructs the JSP engine to evaluate the tag body and include it in the output.

If doStartTag() returns SKIP_BODY, then the body is skipped and the container calls doEndTag(). In this case, the doAfterBody() method is never called on the iterative tag. However, if doStartTag() returns EVAL_BODY_INCLUDE, the body of the tag is evaluated, the result is included in the output, and the container calls doAfterBody() for the very first time.

BodyTag Interface

The BodyTag interface extends IterationTag and adds a new functionality that lets the tag handler evaluate its body content in a temporary buffer. This feature allows the tag to process the generated contents at will. For example, after evaluation, the tag handler can view the body content, discard it completely, modify it, or add more data to it before sending it to the output stream. Since it is derived from IterationTag, BodyTag can also handle the evaluation and processing of the content as many times as required.

void setBodyContent(BodyContent) : Called by the JSP container to pass a reference to a
BodyContent object.

void doInitBody( ) : Called by the JSP container after calling setBodyContent(), to allow the tag handler class to perform initialization steps on BodyContent.

EVAL_BODY_BUFFERED : A constant defined as a return value for doStartTag() and doAfterBody() for tags that want to buffer the evaluation of their content

LifeCycle

The doStartTag() method of a class that implements the BodyTag interface returns any one of three values: EVAL_BODY_INCLUDE or SKIP_BODY inherited from the Tag interface, or EVAL_BODY_BUFFERED, which is defined in the BodyTag interface. The actions taken by the JSP container for the return values EVAL_BODY_INCLUDE and SKIP_BODY are the same as for the IterationTag interface.

However, if doStartTag() returns EVAL_BODY_BUFFERED, the JSP container takes a different course of action. It first creates an instance of the BodyContent class. The BodyContent class is a subclass of JspWriter and overrides all the print and write methods of JspWriter to buffer any data written into it rather than sending it to the output stream of the response. The JSP container passes the newly created BodyContent instance to the tag handler using its setBodyContent() method, calls doInitBody() on the tag, and finally evaluates the body of the tag, filling the BodyContent buffer with the result of the body tag evaluation.

The container calls doAfterBody() after evaluating the body, writing the data directly into the output or buffering it, as the case may be. If the output was buffered, we can add, modify, or delete the contents of this buffer. Finally, this method returns EVAL_BODY_AGAIN or EVAL_BODY_BUFFERED to continue evaluating the body in a loop, or returns SKIP_BODY to terminate the loop.

Finally, the container calls doEndTag(), and, as with the other interfaces, the tag handler class that is implementing the BodyTag interface can return either SKIP_PAGE or EVAL_PAGE.

Friday, May 30, 2008

All about JSP : Custom Tags

What's Custom Tag ? and Whats Use ??
Custom tags allow us to move the presentation logic outside the JSP pages into independent Java classes. One may choose to make custom tag for particular project or as an independent jar file.

There are diff kinds of custom tags
  1. Empty Tags
  2. Tags with attributes
  3. Tags with JSP code
  4. Tags with nested tags

Whats TagHandler ?
As name suggest its something that handles Tag and that something can only be java class. A tag handler is a Java class that implements one of the tag interfaces—Tag, IterationTag, or BodyTag—of the package javax.servlet.jsp.tagext.

The JSP specification defines a tag handler as a runtime, container-managed object that evaluates custom actions during the execution of a JSP page.

Whats Tag library descriptor ?
Its the way to let JSP engine know the tag handler classes for custom tags.

How to inform JSP Engine about custom tag library ?
TWO ways
(1) Use the taglib directive

< % @ taglib prefix="test" uri="testLib.tld" % >

(2) Use jsp root
< jsp="http://java.sun.com/JSP/Page" test="testLib.tld" version="1.2">
...JSP PAGE...
< / jsp:root>

Above examples shows URI. It can be of many type right ?
Three Types
(1) Absolute URI :
A URI that has a protocol, a hostname, and optionally a port number.
http://localhost:8080/mytaglibs

(2) Root Relative URI :
A URI that starts with a / "and" that does not have a protocol, a hostname, or a port number. It is interpreted as relative to the document root of the web application.
/myLib
/mytaglib/myLib

(3) Non-root Relative URI :
does not start with a / "and" that does not have a protocol, a hostname, or a port number. It is interpreted as relative to either the current JSP page "or" the WEB-INF, depending on where it is used.
myLib
mytaglib/myLib

< % @ taglib prefix="test" uri="sampleLib.tld" % >
The JSP engine searches for the file in the same directory as the JSP page.
Though keeping all the JSP pages and the TLD files in the same directory is the simplest way to use a taglib directive, it has two major drawbacks: security and flexibility.

How is the URI mapped to TLD ?
Through mapping ... standard reason ... achieve security & flexibility by maintaining a level of redirection ... If we wanted to switch to a newer version of the library, say myLib2.tld, then we would have to manually modify all the JSP pages that are affected by this change. The JSP container maintains a map between the URIs that we use in taglib directives and the actual physical location of the TLD files in the file system.
With this approach, instead of using a page-relative path, we use an absolute URI path:
< % @ taglib prefix="test" uri="http://www.myserver.com/myLib" % >
When the JSP engine reads the above URI, it refers to its internal map to find the corresponding
TLD file location.

The JSP specification mandates that, when deployed in a JAR file, a TLD file be
placed either directly under or inside a subdirectory of the META-INF directory. In
addition, the name of the TLD file must be taglib.tld. Thus, a JAR file containing
a packaged tag library is typically structured like this:
  • myPackage/myTagHandler1.class
  • myPackage/myTagHandler2.class
  • myPackage/myTagHandler3.class
  • META-INF/taglib.tld
How can the jsp container populate the taglib map
Three ways ...
• First, the container reads the user-defined mapping entries present in the deployment descriptor. This is called explicit mapping. We will learn how to add new entries to the deployment descriptor in the next section.
• Then, the container reads all the taglib.tld files present in the packaged JARs. For each jarred TLD file that contains information about its own URI, the JSP container automatically creates a mapping between the specified URI and the current location of the JAR file. This is called implicit mapping. We will learn how to add the URI information to a TLD file in the next chapter, where we will create a custom tag library.
• Finally, the JSP container adds entries for the URIs that are known to the container by default. These URIs are called well-known URIs. The element of a JSP document contains an example of a well-known URI: http://java.sun.com/JSP/Page

Algorithm ?
• If the value of the uri attribute matches any of the entries, the engine uses the value of the corresponding to locate the actual TLD file.
• If the value is a root-relative URI (that is, it starts with a /), the JSP engine assumes the location to be relative to the web application’s document root directory. Thus, the location for the URI http://www.manning.com/studyKit in listing 15.1 will resolve to
the TLD file /myLibs/studyKit.tld.
• If the value is a non-root relative URI (that is, it starts without a /), the JSP engine prepends /WEB-INF/ to the URI and assumes the location to be relative to the web application’s document root directory. Thus, the location for the URI http://www.manning.com/
sample.jar in listing 15.1 will resolve to the TLD file /WEB-INF/yourLibs/studyKit.tld.

• If the value of the uri attribute of the taglib directive does not match any of the entries, then the following three possibilities arise:
• If the specified uri attribute is an absolute URI, then it is an error and is reported at translation time.
• If the specified uri attribute is a root-relative URI, it is assumed to be relative to the web application’s document root directory.
• If the specified uri attribute is a non-root-relative URI, it is assumed to be relative to the current JSP page. Thus, if the JSP file /jsp/test.jsp contains the directive < % @ taglib prefix="test" uri="sample.tld" % >, the engine will expect to find the sample.tld file at /jsp/sample.tld.


Ques Where will it look for TLD file ?
< % @ taglib uri="www.myserver.com/myLib.tld" prefix="mylib" % >
Ans
The URI www.myserver.com/myLib.tld does not contain a protocol; therefore, it is not an absolute URI. It does not start with a /, so it is not a root-relative URI either. It is a page-relative URI. After failing to find an entry in the map, the engine will search for the file hello.tld at the location relative to the current page. Suppose the JSP page is at location
C:\tomcat\webapps\app15\test.jsp
The engine will look for the file at
C:\tomcat\webapps\app\www.myserver.com\hello.tld

Note
The value of cannot be an absolute URI. and both the and are mandatory when defining absoulte way.