JSP Fragments is a new feature of JSP 2.0 that allows page
authors to create custom action fragments that can be invoked. It allows a portion
of JSP code to be encapsulated into a Java object that can be passed around
and evaluated zero or more times. Template text and expression evaluations can
be included in JSP fragments.
JSP Fragments are created when providing the body of a <jsp:attribute>
standard action for an attribute that is defined as a fragment or of type JspFragment,
or when providing the body of a tag invocation handled by a Simple Tag Handler.
Depending on the configuration of the action being invoked, the body of the
element either specifies a value that is evaluated only once, or it specifies
the body as a JSP fragment.
For example, in Code Snippet A where we have defined an attribute named
x and assigned a value of tutorial1, the fragment may be invoked only once.
On the other hand in Code Snippet B the fragment may be invoked several
times for evaluation.
<jsp:attribute name="stringFrag"> This is the output of chaining 2 defined strings: ${result} </jsp:attribute>
It is worth noting that the fragments themselves are represented
by the JSP container in Java, by an instance of the javax.servlet.jsp.tagext.JspFragment
interface, even though the JSP Fragment is coded in JSP syntax. In the context
of a tag invocation, pieces of JSP code are translated into JSP fragments.
Methods for creating a JSP Fragment
There are two ways to create a JSP Fragment:
Providing the body of a <jsp:attribute>:
For an attribute that is defined as a fragment (or of type
JspFragment) in a tag file, a JSP Fragment can be created by providing the body
of a <jsp:attribute> by specifying fragment
= "true" in the attribute directive:
Another way to create a JSP fragment is to provide the body
of a tag invocation handled by a Simple Tag Handler.
The JspFragment instance is associated with the JspContext of the surrounding
page, before being passed to a tag handler. All information that is not specific
to servlets is abstracted by the JspContext, which also serves as the base class
for the PageContext class. This abstraction is affected because fragments can
not only work with JSP but also with other technologies, and also because the
abstraction allows for an implementation-dependent access. It must be noted
that the collaboration of the fragment and the and the JspContext is preserved
for the duration of the tag invocation in which it is being used.
Invoking a JSP Fragment
After employing any of the two methods above to create a JSP
fragment, it is passed to a tag handler for later invocation. The invocation
of JSP fragments can be done either programmatically from a tag handler written
in Java, or from a tag file using the <jsp:invoke> or <jsp:doBody>
standard action. A bean property of type Jsp-Fragment is used to pass JSP fragments
to tag handlers. These fragments can be invoked by calling the invoke()
method in the JspFragment interface. It is worth noting that it is possible
for a fragment to recursively invoke (indirectly) itself.
The responsibility for setting the values, of all declared
AT_BEGIN and NESTED variables in the JspContext of the calling page/tag, is
taken over by the tag handler to which the JSP Fragment is passed. This happens
before invocation of the JSP Fragment. In the case where the fragment is invoked
using <jsp:invoke> or <jsp:doBody> with the specification of the
var atribute, a custom java.io.Writer is created that can expose the result
of the invocation as a java.lang.String object. If the varReader attribute is
specified, a custom java.io.Writer object is created that can expose the resulting
invocation as a java.io.Reader object.
JspFragment Syntax
The simple syntax for a JspFragment is:
public interface JspFragment
JSP Syntax is used to define JSP Fragments as the body of
a tag for an invocation to a SimpleTag handler, or as the body of a <jsp:attribute>
standard action specifying the value of an attribute that is declared as a fragment,
or to be of type JspFragment in the TLD.
Note that tag library developers and page authors should not
generate Jsp-Fragment implementations manually. Also it is worth noting that
it is not necessary to generate a separate class for each fragment. One possible
implementation is to generate a single helper class for each page that implements
JspFragment. Upon construction, a discriminator can be passed to select which
fragment that instance will execute.