CHAPTER 2

image

JavaServer Pages

The JavaServer Pages (JSP) web framework introduced a great productivity boost for Java web developers over the Java Servlet API. When the JSP technology was introduced in 1999, it was Sun’s answer to PHP and ASP, which provided web developers with a quick way to create dynamic web content. JSPs contain a mix of XML and HTML but can also contain embedded Java code within scripting elements known as scriptlets. Indeed, JSPs are easy to learn and allow developers to quickly create dynamic content and use their favorite HTML editor to lay out nice-looking pages. JSP was introduced several years ago and still remains one of the most important Java web technologies available. Although JSP technology has changed over the years, there are still many applications using older JSP variations in the world today.

Over the years, the creation of dynamic web content has solidified, and the techniques used to develop web applications have become easier to maintain down the road. Whereas early JSP applications included a mix of Java and XML markup within the pages, today the separation of markup from business logic is increasingly important. Newer releases of the JSP technology have accounted for these changes in the web space, and the most recent releases allow developers the flexibility to develop highly dynamic content without utilizing any embedded Java code but, instead, making use of markup and custom tags within pages.

This chapter will show you the ins and outs of JSP development. Starting with creating a simple JSP application, you will learn how to develop applications using JSP technology from the ground up and harness the productivity and power that the technology has to offer. The chapter also brushes upon advanced techniques such as the development of custom JSP tags and the invocation of Java functions utilizing conditional tags. Although entire books have been written on JSP, the recipes within this chapter will lay a solid foundation on which you can begin to develop applications utilizing JSP.

image Note   Utilizing a Java integrated development environment (IDE) can significantly reduce development time, especially when working with Java web technologies such as JSP. To start learning how to create a JSP application using the NetBeans IDE, please see the appendix of this book.

2-1. Creating a Simple JSP Page

Problem

You want to develop a web page using HTML markup that enables you to include dynamic content.

Solution

Use JavaServer Pages to create a web page that combines standard markup with blocks of Java code that are embedded within the markup. The following JSP markup demonstrates how to include dynamic code into a page:

<%--
    Document   : recipe02_01
    Author     : juneau
--%>

<%@page contentType="text/html" pageEncoding="UTF-8"%>
<!DOCTYPE html>
<html>
    <head>
        <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
        <title>JSP Page Example</title>
    </head>
    <body>
        <jsp:useBean id="dateBean" scope="application"         class="org.javaeerecipes.chapter02.recipe02_01.DateBean"/>
        <h1>Hello World!</h1>
        <br/>
        <p>
            The current date is: ${dateBean.currentDate}!
        </p>
    </body>
</html>

The previous JSP code uses a JavaBean to pull the current date into the page. The following Java code is the JavaBean that is used by the JSP code:

package org.javaeerecipes.chapter02.recipe02_01;

import java.util.Date;

/**
 * Recipe 2-1: Creating a Simple JSP
 * @author juneau
 */
public class DateBean {
    
    private Date currentDate = new Date();

    /**
     * @return the currentDate
     */
    public Date getCurrentDate() {
        return currentDate;
    }

    /**
     * @param currentDate the currentDate to set
     */
    public void setCurrentDate(Date currentDate) {
        this.currentDate = currentDate;
    }
    
}

The following output would result. Of course, the page will display the current date when you run the code.

Hello World!
The current date is: Fri Dec 23 10:41:07 CST 2011!

How It Works

The JavaServer Pages technology makes it easy to develop web pages that can utilize both static and dynamic web content by providing a set of tags and value expressions to expose dynamic Java fields to a web page. Using the JSP technology, a page developer can access the underlying JavaBeans classes to pass content between the client and the server. In the example within this recipe, a JSP page is used to display the current date and time, which is obtained from a JavaBean class on the server. Therefore, when a user visits the JSP page in a browser, the current time and date on the server will be displayed.

A JSP page should use a document extension of .jsp if it is a standard HTML-based JSP page. Other types of JSP pages contain different extensions; one of those is the JSP document type. A JSP document is an XML-based well-formed JSP page. You can learn more about JSP documents in Recipe 2-6. JSP pages can contain HTML markup, special JSP tags, page directives, JavaScript, embedded Java code, and more. This example contains the <jsp:useBean> tag, as well as a value expression to display the content of a field that is contained within the JavaBean. The <jsp:useBean> tag is used to include a reference to a Java class that will be referenced in the JSP page. In this case, the class that is referenced is named org.javaeerecipes.chapter02.recipe02_01.DateBean, and it will be referenced as dateBean within the page. For a full description of the <jsp:useBean> tag, please reference Recipe 2-3.

<jsp:useBean id="dateBean" scope="application" class="org.javaeerecipes.chapter02.recipe02_01.DateBean"/>

Since the <jsp:useBean> tag contains a reference to the DateBean Java class, the JSP page that includes the tag can make use of any public fields or methods that are contained within the class or private fields through public “getter” methods. This is demonstrated by the use of the Expression Language (EL) value expression, which is enclosed within the ${} characters. To learn more about JSP EL expressions, please see Recipe 2-4. In the example, the value of the JavaBean field named currentDate is displayed on the page. The value of the private field is retrieved automatically via the pubic “getter” method, getCurrentDate.

The current date is: ${dateBean.currentDate}!

LIFE CYCLE OF A JSP PAGE

The life cycle of a JSP page is very much the same as that of a Java servlet. This is because a JSP page is translated to a servlet (the HttpJspBase JSP servlet class) behind the scenes by a special servlet. When a request is sent to a JSP page, the special servlet checks to ensure that the JSP page’s servlet is not older than the page itself. If it is, the JSP is retranslated into a servlet class and compiled. The JSP-to-servlet translation is automatic, which is one of the most productive reasons to use JSP.

When a JSP page is translated, a servlet with a name such as 0002fjspname_jsp.java is created, where jspname is the name of the JSP page. If errors result during the translation, they will be displayed when the JSP page response is displayed.

Different portions of the JSP page are treated differently during the translation to a Java servlet.

  • Template data is translated into code.
  • JSP scripting elements are inserted into the JSP page’s servlet class.
  • <jsp:XXX .../> elements are converted into method calls.

After translation, the life cycle works similarly to the servlet life cycle:

  • If the JSP page’s servlet does not already exist, then the container does the following:
    1. Loads the servlet class
    2. Instantiates the servlet class
    3. Initializes the servlet instance with a call to the jspInit method

This recipe contains only beginning knowledge of what is possible with the JSP technology. To learn more regarding the technology and best practices when using JSP, please continue reading the recipes in this chapter.

2-2. Embedding Java into a JSP Page

Problem

You want to embed some Java code into a standard JSP web page.

Solution

Use JSP scripting elements to embed Java code into the page and then display Java fields. The following JSP code demonstrates how to import the Java Date class and then use it to obtain the current date without using a server-side JavaBean class:

<%--
    Document   : recipe02_02
    Author     : juneau
--%>

<%@page import="java.util.Date"%>
<%@page contentType="text/html" pageEncoding="UTF-8"%>
<!DOCTYPE html>
<%! Date currDate = null; %>
<% currDate = new Date(); %>
<html>
    <head>
        <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
        <title>Recipe 2-2: Embedding Java in a JSP</title>
    </head>
    <body>
        <h1>Hello World!</h1>
        <br/>
        <br/>
        The current date and time is: <%= currDate %>
        
    </body>
</html>

This page will display the current system date from the server that hosts the JSP application.

How It Works

Using scripting elements within a JSP page allows you to embed Java code directly in a web page. However, it should be noted that this is not the best approach to web development. Scripting element programming used to be one of the best ways to code web applications using JSP technology. However, when it came time to perform maintenance activities on a JSP page or to introduce new developers to a code base that used scripting elements in JSP, nightmares ensued because in order to debug a problem, the developer had to search through scripts embedded within HTML, as well as Java classes themselves. Sometimes it is still nice to have the ability to embed Java code directly into a page, even if for nothing more than testing, so that is why I show how it is done in this recipe. A better approach would be to separate the business logic from the view code, which you will see in Recipe 2-3.

In the example, the current date is pulled into the JSP page via the use of the Java Date class. A new Date instance is assigned to a field that is named currDate. An import page directive is used to import the java.util.Date class into the JSP page using the following line:

<%@page import="java.util.Date"%>

The declaration of currDate is done within a declaration scripting element. Declaration scripting elements begin with the character sequence <%! and end with the character sequence %>. Excerpted from the example, the currDate field is declared in the following line of code:

<%! Date currDate = null; %>

Anything that is contained inside declarations goes directly to the jspService() method of the generated JSP servlet class, creating a global declaration for the entire servlet to make use of. Any variable or method can be declared within declarations’ character sequences.

image Note   Declarations are executed only once for the JSP page, when it is initially converted into a servlet. If any code on the JSP page changes, it will be translated to a servlet again, and the declaration will be evaluated again at that time. If you want for code to be executed each time the JSP page is loaded by the browser, do not place it in a declaration.

In the example for this recipe, you can see that there are no JSP tags used to reference a server-side JavaBean class to create a new instance of the Date class, and that is because the instantiation is done right within the JSP code in between character sequences known as scriptlets, <% %>. Scriptlets basically have the same syntax as declarations, except that they do not include the exclamation point in the first character sequence. Scriptlets are used to embed any Java code that you want to have run each time the JSP is loaded, at request-processing time. At translation time, anything contained within a scriptlet is placed into a method named _jspService within the translated JSP servlet, and that method is executed with each request on the JSP page. Scriptlets are the most common place to use embedded Java in a JSP page. Since in this example you want the current date to be displayed each time the page is loaded, the new Date class is instantiated and assigned to the currDate variable within a scriptlet.

<% currDate = new Date(); %>

Later in the JSP page, the currDate field is displayed using an expression, which is enclosed using the <%= and %> character sequences. Expressions are used to display content, and anything that is contained within an expression is automatically converted to a String when a request is processed. After the String conversion, it is displayed as output on the page.

The current date and time is: <%= currDate %>

image Note   If the code within an expression is unable to be converted into a String, an exception will occur.

While embedding Java code in a JSP page is possible to do, it is frowned upon within the Java community since the Model-View-Controller (MVC) paradigm makes coding much cleaner. To learn more about coding JSP applications without using scripting elements, please see the next recipe, Recipe 2-3.

2-3. Separating Business Logic from View Code

Problem

You want to separate the business logic from the code that is used to create a view within your web application.

Solution

Separate the business logic into a JavaBean class, and use JSP tags to incorporate the logic into the view. In the following example, a JavaBean is referenced from within a JSP page, and one of the JavaBean fields is displayed on the page. Each time the page is refreshed, the field value is updated because the page calls the underlying JavaBean field’s getter method, where the field is initialized.

The following JSP markup contains a reference to a JavaBean named RandomBean and displays a field from the bean on the page:

<%--
    Document   : recipe02_03
    Author     : juneau
--%>

<%@page contentType="text/html" pageEncoding="UTF-8"%>
<!DOCTYPE html>
<html>
    <head>
        <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
        <title>Recipe 2-3: Separating Business Logic from View Code</title>
    </head>
    <body>
        <jsp:useBean id="randomBean" scope="application" class="org.javaeerecipes.chapter02.recipe02_03.RandomBean"/>
        <h1>Display a Random Number</h1>
        <br/>
        <br/>
        <p>
            Your random number is ${randomBean.randomNumber}.  Refresh page to see another!
        </p>
    </body>
</html>

The next code is that of the JavaBean class referenced in the JSP code, known as RandomBean:

package org.javaeerecipes.chapter02.recipe02_03;

import java.util.Random;

/**
 * Recipe 2-3
 * @author juneau
 */
public class RandomBean {
    Random randomGenerator = new Random();
    private int randomNumber = 0;

    /**
     * @return the randomNumber
     */
    public int getRandomNumber() {
        randomNumber = randomGenerator.nextInt();
        return randomNumber;
    }
    
}

The resulting output for the page resembles the following, although the random number will be different every time the page is loaded:

Your random number is -1200578984. Refresh page to see another!

How It Works

Sometimes embedding Java code directly into a JSP page can be helpful, and it can satisfy the requirement. However, in most cases, it is a good idea to separate any Java code from markup code that is used to create the web view. Doing so makes maintenance easier, and it allows a page developer to focus on creating nice-looking web pages rather than wading through Java code. In some organizations, a Java developer can then write the server-side business logic code, and a web developer can focus on the view. In many organizations today, the same person is performing both tasks, and using the MVC methodology can help separate the logic and increase productivity.

In the early days of JSP, embedding Java directly into a JSP page was the only way to go, but as time went on, the MVC paradigm caught on, and JSP has been updated to follow suit. As a best practice, it is good to use JSP tags to separate Java code from page markup. In the example, the <jsp:useBean> element is used to reference a server-side JavaBean class so that the public fields and methods from that class, as well as private fields via public “getter” methods, can be incorporated into the JSP page. The jsp:useBean element requires that you provide an ID and a scope, along with a class name or a beanName. In the example, the id attribute is set to randomBean, and this id is used to reference the bean within the JSP page. The scope attribute is set to application, which means that the bean can be used from any JSP page within the application. Table 2-1 displays all the possible scopes and what they mean. The class attribute is set to the fully qualified name of the Java class that will be referenced via the name that is set with the id attribute, in this case, randomBean.

Table 2-1. jsp:useBean Element Scopes

Scope Description
page (default) The bean can be used within the same JSP page that contains the jsp:useBean element.
request The bean can be used from any JSP page processing the same request.
session The bean can be used from any JSP page within the same session as the JSP page that contains the jsp:useBean element that created the bean. The page that creates the bean must have a page directive with session="true".
application The bean can be used from any JSP within the same application as the JSP page that created it.

After the jsp:useBean element has been added to a page, JavaBean properties can be used in the JSP page, and public methods can be called from the page. The example demonstrates how to display the value of a JavaBean property using the ${ } notation. Any variable that contains a “getter” and a “setter” method in the JavaBean can be accessed from a JSP page by referencing the class member field in between the ${ and } character sequences, better known as an Expression Language expression. To learn more about EL expressions, please see Recipe 2-4. The following excerpt from the example demonstrates how to display the randomNumber field from the JavaBean:

Your random number is ${randomBean.randomNumber}.  Refresh page to see another!

The key to separating business logic from view logic in the JSP technology is the jsp:useBean element. This will allow you to use JavaBean classes from within the JSP page, without embedding the code directly in the page. Separating business logic from view code can help make it easier to maintain code in the future and make the code easier to follow.

2-4. Yielding or Setting Values

Problem

You want to display values from a JavaBean in a JSP page. Furthermore, you want to have the ability to set values in a JSP page.

Solution

Expose the values from a JavaBean in a JSP page using EL expressions with the ${ bean.value } syntax. In the following JSP code, a Java class by the name of EasyBean will be used to hold the value that is entered into a text field by a user. The value will then be read from the bean and displayed on the page using EL expressions.

The following code shows a JSP page that contains an input form and displays the value that is entered into the text box:

<%--
    Document   : recipe02_04
    Author     : juneau
--%>

<%@page contentType="text/html" pageEncoding="UTF-8"%>
<!DOCTYPE html>
<html>
    <head>
        <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
        <title>Recipe 2-4: Yielding and Setting Values</title>
    </head>
    <body>
        <jsp:useBean id="easyBean" scope="page"         class="org.javaeerecipes.chapter02.recipe02_04.EasyBean"/>
        <jsp:setProperty name="easyBean" property="*"/>
        <form method="post">
        Use the input text box below to set the value, and then hit submit.
        <br/><br/>
        Set the field value:
        <input id="fieldValue" name="fieldValue" type="text" size="30"/>
        <br/>
        The value contained within the field is currently:
        <jsp:getProperty name="easyBean" property="fieldValue"/>
        
        <input type="submit">
        </form>
    </body>
</html>

Next, the JavaBean class, which is used to hold the value that is used by the page, looks like the following:

package org.javaeerecipes.chapter02.recipe02_04;

/**
 * Recipe 2-4: Yielding and Setting Values
 * @author juneau
 */
public class EasyBean implements java.io.Serializable {
    private String fieldValue;

    public EasyBean(){
        fieldValue = null;
    }

    /**
     * @return the fieldValue
     */
    public String getFieldValue() {
        return fieldValue;
    }

    /**
     * @param fieldValue the fieldValue to set
     */
    public void setFieldValue(String fieldValue) {
        this.fieldValue = fieldValue;
    }
    
}

This simple example demonstrates how to enter a value, “set” it into the JavaBean variable, and then display it on the page.

How It Works

Perhaps one of the most useful web constructs is the input form, which allows a user to enter information into text boxes on the page and submit them to a server for processing. JSP makes it easy to submit values from an HTML form, and it is equally easy to display them back on a page. To do so, a field is declared in a Java class and accessor methods (aka getters and setters) are provided so that other classes can save values to the field and obtain values that are currently stored in it. Sometimes Java classes that contain fields with accessor methods are referred to as JavaBean classes. The classes can also contain other methods that can be used to perform tasks, but it is a best practice to keep JavaBeans as simple as possible. JavaBean classes should also implement java.io.Serializable so that they can be easily stored and resurrected.

In the example for this recipe, a Java class named EasyBean contains a private field named fieldValue. The accessor methods getFieldValue and setFieldValue can be used to obtain and store the value in fieldValue, respectively. Those accessor methods are declared as public, and thus they can be used from another Java class or JSP page. The JSP page uses the jsp:useBean element to obtain a reference to the EasyBean class. The scope is set to page so that the class can be used only within the JSP page that contains the jsp:useBean element. Table 2-1, which can be found in the previous recipe, lists the different scopes available for use with the jsp:useBean element.

<jsp:useBean id="easyBean" scope="page" class="org.javaeerecipes.chapter02.recipe02_04.EasyBean"/>

Next, an HTML form is defined in the JSP page with the POST method, and it contains an input field named fieldValue, which allows a user to enter a String of text that will be submitted as a request parameter when the form is submitted. Note that the form in the example does not have an action specified; this means that the same URL will be used for form submission, and the same JSP will be used for form submission and will be displayed again once the form is submitted. Since the JSP has a jsp:useBean element specified on the page, all request parameters will be sent to that bean when the page is submitted. The key to ensuring that the value entered into the fieldValue input text field is stored into the fieldValue variable within the Java class is using the jsp:setProperty element within the form. The jsp:setProperty element allows one or more properties to be set in a JavaBean class using the corresponding setter methods. In the example, <jsp:useBean> is used to instantiate the EasyBean Java class, and <jsp:setProperty> is used to set the value that is entered within the fieldValue input text box to the fieldValue variable within the EasyBean class. The jsp:setProperty name attribute must equal the value of the jsp:useBean id attribute. The jsp:setProperty property attribute can equal the name of the field within the Java class that you want to set in the bean, or it can be a wildcard * character to submit all input fields to the bean. The value attribute of jsp:setProperty can be used to specify a static value for the property. The following excerpt from the example shows how the jsp:setProperty tag is used:

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

image Note   The ordering of the JSP elements is very important. <jsp:useBean> must come before <jsp:setProperty> because the jsp:useBean element is responsible for instantiating its corresponding Java class. Since the JSP page is executed from the top of the page downward, the bean would be unavailable for use to any elements prior to when jsp:useBean is specified.

When the user enters a value into the input field and submits the request, it is submitted as a request parameter to the Java class that corresponds to the jsp:useBean element for that page. There are a couple of different ways to display the data that has been populated in the JavaBean field. The example demonstrates how to use the jsp:getProperty element to display the value of the fieldValue variable. The <jsp:getProperty> element must specify a name attribute, which corresponds to the id of the Java class that was specified within the jsp:useBean element. It must also specify a property attribute, which corresponds to the name of the JavaBean property that you want to display. The following excerpt from the example demonstrates the use of the jsp:getProperty tag:

<jsp:getProperty name="easyBean" property="fieldValue"/>

It is also possible to display the value of a JavaBean property using EL expressions, using the id of specified in the jsp:useBean element, along with the property name. To try this, you can replace the jsp:getProperty element with the following EL expression:

${easyBean.fieldValue}

The JSP framework makes the development of web applications using Java technology much easier than using servlets. Input forms such as the one demonstrated in this example show how much more productive JSP is compared to standard servlet coding. As with anything, both servlets and JSP technology have their place in your toolbox. For creating simple data entry forms, JSP definitely takes the cake.

2-5. Invoking a Function in a Conditional Expression

Problem

You want to use a Java function to perform a conditional evaluation within your JSP. However, you do not want to embed Java code into your JSP page.

Solution

Code the function in a JavaBean class and then register the bean with the JSP via the <jsp:useBean> tag. You will then need to register the function within a tag library descriptor (TLD) so that it can be made usable on the JSP page via a tag. Finally, set up a page directive for the TLD in which the function is registered, and use the function tag within the page. In the example that follows, a JSP page will use a function to tell the user whether a given Java type is a primitive type. The user will enter a String value into a text box, and that value will be submitted to a JavaBean field. The contents of the field will then be compared against a list of Java primitive types to determine whether it is a match. If the value entered into the field is a primitive, a message will be displayed to the user.

The following code is the Java class that contains the implementation of the function, which is going to be used from within the JSP. The bean also contains a field that will be used from the JSP page for setting and getting the value that is entered by the user.

package org.javaeerecipes.chapter02.recipe02_05;

/**
 * Recipe 2-5
 * @author juneau
 */
public class ConditionalClass implements java.io.Serializable {
    private String typename = null;
    public static String[] javaTypes = new String[8];
    
    public ConditionalClass(){
        javaTypes[0] = "byte";
        javaTypes[1] = "short";
        javaTypes[2] = "int";
        javaTypes[3] = "long";
        javaTypes[4] = "float";
        javaTypes[5] = "double";
        javaTypes[6] = "boolean";
        javaTypes[7] = "char";
    }
    
    public static boolean isPrimitive(String value){
        boolean returnValue = false;
        for(int x=0; x<=javaTypes.length-1; x++){
            if(javaTypes[x].equalsIgnoreCase(value)){
                returnValue = true;
            }
        }
        return returnValue;
    }

    /**
     * @return the typename
     */
    public String getTypename() {
        return typename;
    }

    /**
     * @param typename the typename to set
     */
    public void setTypename(String typename) {
        this.typename = typename;
    }
}

The field typename will be used from the JSP page to set the value that is entered by the user and to retrieve it for passing to the function named isPrimitive();, which is used to compare the given value to a list of Java primitives. Next is a listing of the TLD that is used to register the function so that it can be used as a tag within the JSP. For simplicity, the TLD file is named functions.tld.

<?xml version="1.0" encoding="UTF-8"?>
<taglib version="2.1" xmlns="http://xmlns.jcp.org/xml/ns/javaee"    
xmlns:xsi="
http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="
http://xmlns.jcp.org/xml/ns/javaee
http://xmlns.jcp.org/xml/ns/javaee/web-jsptaglibrary_2_1.xsd">
    <tlib-version>1.0</tlib-version>
    <short-name>fct</short-name>
    <uri>functions</uri>
    <function>
        <name>isPrimitive</name>
        <function-class>org.javaeerecipes.chapter02.recipe02_05.ConditionalClass</function-class>
        <function-signature>boolean isPrimitive(java.lang.String)</function-signature>
    </function>
</taglib>

Last is the JSP code that contains the page directive for using the TLD and the conditional call to the function isPrimitive() via a tag:

<%--
    Document   : recipe02_05
    Author     : juneau
--%>

<%@page contentType="text/html" pageEncoding="UTF-8"%>
<!DOCTYPE html>
<%@ taglib uri="http://java.sun.com/jcp/jstl/core"
     prefix="c" %>
<%@ taglib uri="/WEB-INF/tlds/functions.tld" prefix="fct" %>
<html>
    <head>
        <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
        <title>Recipe 2-5: Invoking a Function in an Expression</title>
    </head>
    <body>
        
        <form method="get">
            <p>Name one of the primitive Java types:
                <input type="text" id="typename" name="typename" size="40"/>
            </p>
            <br/>
            <input type="submit">
        </form>
        <jsp:useBean id="conditionalBean" scope="page" class="org.javaeerecipes.chapter02.recipe02_05.ConditionalClass"/>
        <jsp:setProperty name="conditionalBean" property="typename"/>
        <c:if test="${fct:isPrimitive(conditionalBean.typename)}" >
            ${ conditionalBean.typename } is a primitive type.
        </c:if>
        
        <c:if test="${conditionalBean.typename ne null and !fct:isPrimitive(conditionalBean.typename)}" >
            ${ conditionalBean.typename } is not a primitive type.
        </c:if>
    </body>
</html>

Following the strategy used in this solution, you can create a conditional test that is usable via a JSP tag for your pages.

How It Works

You need to take a few different steps before a Java function can become accessible from a JSP page. One of the most commonly overlooked conditions is that the function must be declared with a static modifier in the Java class. In the example for this recipe, the function isPrimitive is declared as static, and it returns a boolean value indicating whether the web page user types the name of a Java primitive type.

The next step toward making a function accessible via a JSP page is to register it with a TLD. In the example, a TLD named functions.tld is created, although if there is already a custom TLD in your application, then you could register the function with it rather than creating an additional one if you want. The TLD in this example has a short-name attribute of fct, which will be used from within JSP tags. To actually register the function, you must create a function element within the TLD, provide a function name, indicate the class that the function resides within, and, finally, specify the function signature.

<function>
    <name>isPrimitive</name>
    <function-class>org.javaeerecipes.chapter02.recipe02_05.ConditionalClass</function-class>
    <function-signature>boolean isPrimitive(java.lang.String)</function-signature>
</function>

The function is now ready for use within the JSP. To make the function accessible via the JSP, register the TLD that contains the function element by including a taglib directive specifying the uri and prefix for the TLD. The uri is the path to the TLD, and the prefix should match the name given in the short-name element of the TLD. The following excerpt from the JSP in this example shows the taglib directive:

<%@ taglib uri="/WEB-INF/tlds/functions.tld" prefix="fct" %>

The function will now be accessible via an EL expression within the JSP by specifying the taglib prefix along with the name of the function as it is registered in the TLD. The EL expression in the example calls the function, passing the typename parameter. The isPrimitive function is used to determine whether the text contained within the typename bean field is equal to one of the Java primitive types.

<c:if test="${fct:isPrimitive(conditionalBean.typename)}" >

The solution in this recipe also uses the Java Standard Tag Library (JSTL) core. Depending upon the server environment being used, this may be a separate download. The JSTL provides an extension to the standard set of tags provided with the JSP API. For more information regarding JSTL, please refer to the online documentation, which can be found at www.oracle.com/technetwork/java/index-jsp-135995.html.

The JSTL <c:if> tag can be used to test conditions, executing the markup between its opening and closing tags if the condition test returns a true value. Not surprisingly, the <c:if> tag includes a test attribute that specifies an EL expression that indicates the test that needs to be performed. In the example, the isPrimitive function is called within the EL expression, passing the bean value. If the test returns a true, then a message is printed indicating that the given value is equal to a Java primitive type. Another <c:if> test follows the first in the example, and this time it tests to ensure that the property value is not equal to null and also that it is not a Java primitive type. Expression Language is used to determine whether the property value is equal to null via the ne expression. The and expression ties both the first and second conditional expressions together within the EL expression, meaning that both of the expressions must evaluate to a true value in order for the condition to be met. If both conditions are met, then the value specified by the user is not a Java primitive type, and a corresponding message is printed.

<c:if test="${conditionalBean.typename ne null and !fct:isPrimitive(conditionalBean.typename)}" >
            ${ conditionalBean.typename } is not a primitive type.
</c:if>

It takes only a few easy steps to create a conditional function for use within JSPs. First, in the JavaBean class, you must create a public static function, which returns a boolean value. Second, create a TLD, which will make the function available via a JSP tag. Lastly, use the custom tag from within the JSP page along with JSTL conditional test tags to display the content conditionally.

2-6. Creating a JSP Document

Problem

Rather than using standard HTML format, you want to ensure that your JSP code follows the XML standard and contains only valid HTML and JSP tags.

Solution

Create a JSP document rather than a standard JSP. A JSP document is an XML-based representation of a standard JSP document that conforms to the XML standard. The following JSP document contains the same code that is used in the JSP code for Recipe 2-5, but it uses the JSP document format instead. As you can see, not much is different because well-formed tags were already used to create the standard JSP document. The page is also saved with an extension of jspx rather than jsp.

<!--
    Document   : recipe02_06
    Author     : juneau
-->
<html xmlns:jsp="http://java.sun.com/JSP/Page" version="2.0"
      xmlns:c="http://java.sun.com/jcp/jstl/core"
      xmlns:fct="/WEB-INF/tlds/functions.tld">

    <jsp:directive.page contentType="text/html" pageEncoding="UTF-8"/>

    <body>
        <form method="get">
            <p>Name one of the primitive Java types:
                <input type="text" id="typename" name="typename" size="40"/>
            </p>
            <br/>
            <input type="submit"/>
        </form>
        <jsp:useBean id="conditionalBean" scope="request" class="org.javaeerecipes.chapter02.recipe02_05.ConditionalClass"/>
        <jsp:setProperty name="conditionalBean" property="typename"
                         value="${param.typename}" />
        <c:if test="${fct:isPrimitive(conditionalBean.typename)}" >
            ${ conditionalBean.typename } is a primitive type.
        </c:if>

        <c:if test="${fn.length(conditionalBean.typename) > 0 and !fct:isPrimitive(conditionalBean.typename)}" >
            ${ conditionalBean.typename } is not a primitive type.
        </c:if>

    </body>
</html>

This JSP document will yield the same output as the one in Recipe 2-5. However, a well-formed document will be enforced, and this will exclude the use of scripting elements within the page.

How It Works

As foreshadowed in Recipe 2-3, separating business logic from markup code can be important for many reasons. Standard JSP pages can adhere to the MVC paradigm, but they are not forced into doing so. Sometimes it makes sense to enforce the separation of business logic, by strictly adhering to a well-formed XML document using only JSP tags to work with server-side Java classes. Well-formed means that there should be only one root element, and each starting tag must have a corresponding ending tag. Creating a JSP document is one answer because such documents enforce well-formed XML and do not allow scripting elements to be used within the JSP page.

Several JSP tags can be used to communicate with Java classes, perform JSP-specific functionality, and make markup easy to follow. As such, modern JSP-based applications should make use of well-formed JSP documents utilizing such JSP tags, rather than embedding scripting elements throughout markup. Table 2-2 describes what the different JSP tags do.

Table 2-2. JSP Tags

Tag Description
<jsp:attribute> Defines attributes for a JSP page.
<jsp:body> Defines an element body.
<jsp:declaration> Defines page declarations.
<jsp:directive> Defines page includes and page directives.
<jsp:doBody> Executes the body of the JSP tag that is used by the calling JSP page to invoke the tag.
<jsp:element> Generates an XML element dynamically.
<jsp:expression> Inserts the value of a scripting language expression, converted into a string.
<jsp:forward> Forwards a request to another page.  The new page can be HTML,  JSP, or servlet.
<jsp:getProperty> Obtains the value of a bean property and places it in the page.
<jsp:include> Includes another JSP or web resource in the page.
<jsp:invoke> Invokes a specified JSP fragment.
<jsp:output> Specifies the document type declaration.
<jsp:plugin> Executes an applet or bean with the specified plug-in.
<jsp:root> Defines standard elements and tag library namespaces.
<jsp:scriptlet> Embeds code fragment into a page if necessary.
<jsp:setProperty> Sets specified value(s) into a bean property.
<jsp:text> Encloses template data.
<jsp:useBean> References and instantiates (if needed) a JavaBean class using a name and providing a scope.

Creating a well-formed JSP can lead to easier development, ease of maintenance, and better overall design. Since it is so important, the remaining recipes in this chapter will use the JSP document format.

2-7. Embedding Expressions in EL

Problem

You want to use some conditional expressions and/or arithmetic within your JSP without embedding Java code using scripting elements.

Solution

Use EL expressions within JSP tags to perform conditional and/or arithmetic expressions. This solution will look at two examples of EL expressions. The first example demonstrates how to perform conditional logic using EL expressions. Note that the JSTL tag library is also used in this case, to conditionally display a message on the page if the expression results to true.

<!--
    Document   : recipe02_07a
    Author     : juneau
-->
<html xmlns:jsp="http://java.sun.com/JSP/Page"
      xmlns:c="http://java.sun.com/jcp/jstl/core"
      version="2.0">

    <jsp:directive.page contentType="text/html" pageEncoding="UTF-8"/>
    <head>
        <title>Recipe 2-7: Embedding Expressions in EL</title>
    </head>
    <body>
        <h1>Conditional Expressions</h1>
        <p>
            The following portion of the page will only display conditional expressions
            which result in a true value.
        </p>
        <c:if test="${1 + 1 == 2}">
            The conditional expression (1 + 1 == 2) results in TRUE.
            <br/>
        </c:if>
            
        <c:if test="${'x' == 'y'}">
            The conditional expression (x == y) results in TRUE.
            <br/>
        </c:if>
            
        <c:if test="${(100/10) gt 5}">
            The conditional expression ((100/10) > 5) results in TRUE.
            <br/>
        </c:if>
            
        <c:if test="${20 mod 3 eq 2}">
            The conditional expression (20 mod 3 eq 2) results in TRUE.
            <br/>
        </c:if>
    </body>
</html>

This JSP page will result in the following output being displayed:

...
The conditional expression (1 + 1 == 2) results in TRUE.
The conditional expression ((100/10) > 5) results in TRUE.
The conditional expression (20 mod 3 eq 2) results in TRUE.
...

Arithmetic expressions can also be evaluated using EL. The following JSP code demonstrates some examples of using arithmetic within EL:

<!--
    Document   : recipe02_07b
    Author     : juneau
-->
<html xmlns:jsp="http://java.sun.com/JSP/Page"
      xmlns:c="http://java.sun.com/jcp/jstl/core"
      version="2.0">

    <jsp:directive.page contentType="text/html" pageEncoding="UTF-8"/>
    <head>
        <title>Recipe 2-7: Embedding Expressions in EL</title>
    </head>
    <body>
        <jsp:useBean id="expBean" class="org.javaeerecipes.chapter02.recipe02_07.Expressions"/>
        <h1>Arithmetic Expressions</h1>
        <p>
            The following expressions demonstrate how to perform arithmetic using EL.
        </p>
        10 - 4 = ${10 - 4}
        <br/>
        85 / 15 = ${85 / 15}
        <br/>
        847 divided by 6 = ${847 div 6}
        <br/>
        ${expBean.num1} * ${expBean.num2} = ${expBean.num1 * expBean.num2}
        
    </body>

</html>

The preceding JSP will result in the following output being displayed:

...
10 - 4 = 6
85 / 15 = 5.666666666666667
847 divided by 6 = 141.16666666666666
5 * 634.324 = 3171.62
...

How It Works

The JSP technology makes it easy to work with expressions. Conditional page rendering can be performed using a combination of EL value expressions, which are enclosed within the ${ } character sequences, and JSTL tags. Arithmetic expressions can also be performed using EL expressions. To make things easier, the Expression Language contains keywords or characters that can be used to help form expressions. The example for this recipe contains various expressions and conditional page rendering using the JSTL <c:if> tag.

In the first JSP page displayed in the example, there are some examples of conditional page rendering. To use the <c:if> tag to perform the conditional tests, you must be sure to import the JSTL tag library with the JSP page. To do so, add an import for the JSTL tag library and assign it to a character or string of characters. In the following excerpt from the recipe, the JSTL library is assigned to the character c:

<html xmlns:jsp="http://java.sun.com/JSP/Page"
      xmlns:c="http://java.sun.com/jcp/jstl/core"
      version="2.0">

An EL value expression is contained within the ${ and } character sequences. Anything within these characters will be treated as EL, and as such, the syntax must be correct, or the JSP page will not be able to compile into a servlet, and it will throw an error. All expressions using the ${ } syntax are evaluated immediately, and they are read-only expressions. That is, no expressions using this syntax can be used to set values into a JavaBean property. The JSP engine first evaluates the expression, and then it converts into a String and lastly returns the value to the tag handler. Four types of objects can be referenced within a value expression. Those are JavaBean components, collections, enumerated types, and implicit objects. If using a JavaBean component, the JavaBean must be registered with the JSP page using the jsp:useBean element (see Recipe 2-3 for details). Collections or enumerated types can also be referenced from a JavaBean that has been registered with the page. Implicit objects are those that allow access to page context, scoped variables, and other such objects. Table 2-3 lists different implicit objects that can be referenced from within EL expressions.

Table 2-3. Implicit JSP Objects

Object Type Description
pageContext Context Provides access to the context of the page and various subobjects
servletContext Page context Context for JSP page servlet and web components
session Page context Session object for the client
request Page context Request that invoked the execution of the page
response Page context Response that is returned by the JSP
param N/A Responsible for mapping parameter names to values
paramValues N/A Maps request parameter to an array of values
header N/A Responsible for mapping a header name to a value
headerValues N/A Maps header name to an array of values
cookie N/A Maps a cookie name to a single cookie
initParam N/A Maps a context initialization parameter to a value
pageScope Scope Maps page scope variables
requestScope Scope Maps request scope variables
sessionScope Scope Maps session scope variables
applicationScope Scope Maps application scope variables

The following are some examples of expressions that make use of JavaBean components, collections, enumerated types, and implicit objects:

// Displays the value of a variable named myVar within a JavaBean referenced as elTester
${ elTester.myVar }
// Does the same thing as the line above
${ elTester["myVar"] }

// Evaluates an Enumerated Type in which myEnum is an instance of MyEnum
${ myEnum == "myValue" }
// Reference a getter method of the Enum named getTestVal()
${ myEnum.testVal}

// References a collection named myCollection within the JavaBean referenced as elTester
${ elTester.myCollection }

// Obtain the parameter named "testParam"
${ param.testParam }  // Same as: request.getParameter("testParam")
// Obtain session attribute named "testAttr"
${ sessionScope.testAttr } // Same as: session.getAttribute("testAttr")

In the recipe example, the <c:if> tag is used to test a series of value expressions and conditionally display page content. The test attribute of <c:if> is used to register a test condition, and if the test condition returns a true result, then the content contained between the <c:if> starting and ending tags is displayed. The following excerpt from the example demonstrates how a test is performed:

<c:if test="${'x' == 'y'}">
        The conditional expression (x == y) results in TRUE.
        <br/>
</c:if>

EL expressions can contain a series of reserved words that can be used to help evaluate the expression. For instance, the following expression utilizes the gt reserved word to return a value indicating whether the value returned from the calculation of 100/10 is greater than 5:

<c:if test="${(100/10) gt 5}">
        The conditional expression ((100/10) > 5) results in TRUE.
        <br/>
</c:if>

Table 2-4 lists all the JSP EL expression reserved words and their meanings.

Table 2-4. EL Expression Reserved Words

Reserved Word Description
and Combines expressions and returns true if all of them evaluate to true
or Combines expressions and returns true if one of them evaluates to true
not Negates an expression
eq Equal
ne Not equal
lt Less than
gt Greater than
le Less than or equal
ge Greater than or equal
true True value
false False value
null Null value
instanceof Used to test whether an object is an instance of another object
empty Determines whether a list or collection is empty
div Divided by
mod Modulus

Arithmetic expressions are demonstrated by the second example in this recipe. The following arithmetic operators can be utilized within expressions:

  • + (addition), - (binary and unary), * (multiplication), / and div (division), %, and mod (modulus)
  • and, &&, or, ||, not, !
  • ==, !=, <, >, <=, >=
  • X ? Y : Z (ternary conditional)

Entire chapters of books have been written on the use of EL expressions within JSPs. This recipe only touches upon the possibilities of using value expressions. The best way to get used to expressions is to create a test JSP page and experiment with the different options that are available.

2-8. Accessing Parameters in Multiple Pages

Problem

You want to access a parameter from within multiple pages of your web application.

Solution

Create an input form to submit parameters to the request object, and then utilize the request object to retrieve the values in another page. In the example that follows, a JSP page that contains an input form is used to pass values to another JSP page by setting the HTML form action attribute to the value of the JSP page that will utilize the parameters. In the case of this example, the receiving JSP page merely displays the parameter values, but other work could be performed as well.

The following JSP code demonstrates the use of an input form to save parameters into the request object and pass them to a page named recipe02_08b.jspx:

<!--
    Document   : recipe02_08a
    Author     : juneau
-->
<html xmlns:jsp="http://java.sun.com/JSP/Page"
      xmlns:c="http://java.sun.com/jcp/jstl/core"
      version="2.0">

    <jsp:directive.page contentType="text/html" pageEncoding="UTF-8"/>
    <head>
        <title>Recipe 2-8: Passing Parameters</title>
    </head>
    <body>
        
        <h1>Passing Parameters</h1>
        <p>
            The following parameters will be passed to the next JSP.
        </p>
        <form method="get" action="recipe02_08b.jspx">
        Param 1: <input id="param1" name="param1" type="text" value="1"/>
        <br/>
        Param 2: <input id="param2" name="param2" type="text" value="2 + 0"/>
        <br/>
        Param 3: <input id="param3" name="param3" type="text" value="three"/>
        <br/>
        <input type="submit" value="Go to next page"/>
        </form>
    </body>

</html>

The next JSP code receives the parameters and displays their values:

<!--
    Document   : recipe02_08b
    Author     : juneau
-->
<html xmlns:jsp="http://java.sun.com/JSP/Page"
      xmlns:c="http://java.sun.com/jcp/jstl/core"
      version="2.0">

    <jsp:directive.page contentType="text/html" pageEncoding="UTF-8"/>
    <head>
        <title>Recipe 2-8: Passing Parameters</title>
    </head>
    <body>
        
        <h1>Passing Parameters</h1>
        <p>
            The following parameters will were passed from the original JSP.
        </p>
        <form method="post" action="recipe02_08a.jspx">
        Param 1: <jsp:expression>request.getParameter("param1") </jsp:expression>
        <br/>
        Param 2: <jsp:expression> request.getParameter("param2") </jsp:expression>
        <br/>
        Param 3: <jsp:expression> request.getParameter("param3") </jsp:expression>
        <br/>
        OR using value expressions
        <br/>
        Param 1: ${ param.param1 }
        <br/>
        Param 2: ${ param.param2 }
        <br/>
        Param 3: ${ param.param3 }
        <br/>
        
        <input type="submit" value="Back to Page 1"/>
        </form>
    </body>

</html>

As you can see, a couple of variations can be used to display the parameter values. Both of the variations will display the same result.

How It Works

Request parameters are one of the most useful features of web applications. When a user enters some data into a web form and submits the form, the request contains the parameters that were entered into the form. Parameters can also be statically embedded within a web page or concatenated onto a URL and sent to a receiving servlet or JSP page. The data contained in request parameters can then be inserted into a database, redisplayed on another JSP page, used to perform a calculation, or a myriad of other possibilities. The JSP technology provides an easy mechanism for using request parameters within other JSP pages, and the example in this recipe demonstrates how to do just that.

image Note   Request parameters are always translated into String values.

Note that in the example, the first JSP page uses a simple HTML form to obtain values from a user and submit them to the request. Another JSP page named recipe02_08b.jspx is set as the form action attribute, so when the form is submitted, it will send the request to recipe02_08b.jspx. The input fields on the first JSP page specify both an id attribute and a name attribute, although only the name attribute is required. The name that is given to the input fields is the name that will be used to reference the value entered into it as a request parameter.

image Note   It is a good programming practice to always include an id attribute. The ID is useful for performing work with the DOM and for referencing elements via a scripting language such as JavaScript.

The receiving action, recipe02_08b.jspx in this example, can make a call to response.getParameter(), passing the name of a parameter (input field name) to obtain the value that was entered into its corresponding text field. To adhere to JSP document standards, the scriptlet containing the call to response.getParameter() must be enclosed within <jsp:expression> tags. The following excerpt demonstrates how this is done:

Param 1: <jsp:expression>request.getParameter("param1") </jsp:expression>

Optionally, an EL expression can contain a reference to the implicit param object and obtain the request parameter in the same way. When the expression ${param.param1} is called, it is evaluated by the JSP engine, and it is translated into response.getParameter("param1"). The following excerpt demonstrates this use of EL expressions:

Param 1: ${ param.param1 }

Either technique will perform the same task; the named request parameter will be obtained and displayed on the page.

2-9. Creating a Custom JSP Tag

Problem

You want to create a JSP tag that provides custom functionality for your application.

Solution

Create a custom JSP tag using JSP 2.0 simple tag support. Suppose you want to create a custom tag that will insert a signature into the JSP where the tag is placed. The custom tag will print out a default signature, but it will also accept an authorName attribute, which will include a given author's name to the signature if provided. To get started, you'll first need to define a Java class that extends the SimpleTagSupport class. This class will provide the implementation for your tag. The following code is the implementation for a class named Signature, which provides the implementation for the custom tag.

image Note   To compile the following code, you will need to add javax.servlet.jsp to classpath:

cd recipe02_09
javac -cp ...glassfish4glassfishmodulesjavax.servlet.jsp-api.jar *.java

package org.javaeerecipes.chapter02.recipe02_09;

import javax.servlet.jsp.JspException;
import javax.servlet.jsp.JspWriter;
import javax.servlet.jsp.PageContext;
import javax.servlet.jsp.tagext.SimpleTagSupport;

/**
 * Recipe 2-9:  Creating a Custom JSP Tag
 * @author juneau
 */
public class Signature extends SimpleTagSupport {
    
    private String authorName = null;

    /**
     * @param authorName the authorName to set
     */
    public void setAuthorName(String authorName) {
        this.authorName = authorName;
    }
    
    @Override
    public void doTag() throws JspException {
        PageContext pageContext = (PageContext) getJspContext();
        JspWriter out = pageContext.getOut();
            
        try {
            if(authorName != null){
                out.println("Written by " + authorName);
                out.println("<br/>");
            }
            out.println("Published by Apress");
                
        } catch (Exception e) {
            System.out.println(e);
        }
            
    }
}

Next, a TLD  to be created to map the Signature class tag implementation to a tag. The TLD that includes the custom tag mapping is listed here:

<?xml version="1.0" encoding="UTF-8"?>
<taglib version="2.1" xmlns="http://xmlns.jcp.org/xml/ns/javaee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaeehttp://xmlns.jcp.org/xml/ns/javaee/web-jsptaglibrary_2_1.xsd">
  <tlib-version>1.0</tlib-version>
  <short-name>cust</short-name>
  <uri>custom</uri>
  <tag>
   <name>signature</name>
   <tag-class>org.javaeerecipes.chapter02.recipe02_09.Signature</tag-class>
   <body-content>empty</body-content>
   <attribute>
       <name>authorName</name>
       <rtexprvalue>true</rtexprvalue>
       <required>false</required>
    </attribute>
 </tag>
</taglib>

Once the class implementation and the TLD are in place, the tag can be used from within a JSP page. The following JSP code is an example of using the custom tag on a page:

<!--
    Document   : recipe02_09
    Author     : juneau
-->
<html xmlns:jsp="http://java.sun.com/JSP/Page"
      xmlns:c="http://java.sun.com/jcp/jstl/core"
      xmlns:cust="custom"
      version="2.0">

    <jsp:directive.page contentType="text/html" pageEncoding="UTF-8"/>
    <head>
        <title>Recipe 2-9: Creating a Custom JSP Tag</title>
    </head>
    <body>
        
        <h1>Custom JSP Tag</h1>
        <p>
            The custom JSP tag is used as the footer for this page.
            <br/>
        </p>
        <cust:signature authorName="Josh Juneau"/>
        
    </body>

</html>

The custom tag output will now be displayed in place of the cust:signature element within the JSP page.

How It Works

One of the most useful new features of JSP 2.0 was the inclusion of the SimpleTagSupport class, which provides an easier way for developers to create custom tags. Prior to the 2.0 release, custom tag creation took a good deal of more work, because the developer had to provide much more code to implement the tag within the tag's implementation class. The SimpleTagSupport class takes care of much implementation for the developer so that the only thing left to do is implement the doTag method in order to provide an implementation for the custom tag.

In the example for this recipe, a custom tag is created that will print out a signature on the JSP page in the position where the tag is located. To create a custom tag implementation, create a Java class that will extend the SimpleTagSupport class, and provide an implementation for the doTag method. The example class also contains a field named authorName, which will be mapped within the TLD as an attribute for the custom tag. In the doTag method, a handle on the JSP page context is obtained by calling the getJspContext method. getJspContext is a custom method that is implemented for you within SimpleTagSupport and makes it easy to get ahold of the JSP page context. Next, to provide the ability to write to the JSP output, a handle is obtained on the JspWriter by calling PageContext's getOut method.

PageContext pageContext = (PageContext) getJspContext();
JspWriter out = pageContext.getOut();

The next lines within doTag provide the implementation for writing to the JSP output via a series of calls to out.println. Any content that is passed to out.println will be displayed on the page. Note that in the example, the authorName field is checked to see whether it contains a null value. If it does not contain a null value, then it is displayed on the page; otherwise, it is omitted. Therefore, if the tag within the JSP page contains a value for the authorName attribute, then it will be printed on the page. The out.println code is contained within a try-catch block in case any exceptions occur.

image Note   To allow your tag to accept scriptlets, you will need to use the Classic Tag Handlers. The Classic Tag handlers existed before the JSP 2.0 era and can still be used today alongside the Simple Tag Handlers. The Simple Tag Handlers revolve around the doTag() method, whereas the Classic Tag Handlers deal with a doStartTag() method and a doEndTag() method, as well as others. Since the Simple Tag Handlers can be used alongside the Classic Tag Handlers, it is possible to use some of the more complex Classic Tag methods, while utilizing Simple Tag methods in the same application. This eases the transition from the Classic Tag Handlers to the Simple Tag Handlers. For more information regarding the differences between the two APIs, please see some online documentation by searching for the keywords Simple vs. Classic Tag Handlers.

That's it; the implementation for the tag is complete. To map the implementation class to the Document Object Model (DOM) via a tag name, a TLD must contain a mapping to the class. In the example, a TLD is created named custom.tld, and it contains the mapping for the class. The short-name element specifies the name that must be used within the JSP page to reference the tag. The uri element specifies the name of the TLD, and it is used from within the JSP page to reference the TLD file itself. The meat of the TLD is contained within the tag element. The name element is used to specify the name for the tag, and it will be used within a JSP page in combination with the short-name element to provide the complete tag name. The tag-class element provides the name of the class that implements the tag, and body-content specifies a value to indicate whether the body content for the JSP page will be made available for the tag implementation class. It is set to empty for this example. To specify an attribute for the tag, the attribute element must be added to the TLD, including the name, rtexprvalue, and required elements. The name element of attribute specifies the name of the attribute, rtexprvalue indicates whether the attribute can contain an EL expression, and required indicates whether the attribute is required.

To use the tag within a JSP page, the custom.tld TLD must be mapped to the page within the <html> element in a JSP document or a taglib directive within a standard JSP. The following lines show the difference between these two:

<!—JSP Document syntax -->
xmlns:cust="custom"

<!—JSP syntax -->
<%@taglib prefix="cust" uri="custom" %>

To use the tag within the page, simply specify the TLD short-name along with the mapping name for the tag implementation and any attributes you want to provide.

<cust:signature authorName="Josh Juneau"/>

Creating custom tags within JSP is easier than it was in the past. Custom tags provide developers with the ability to define custom actions and/or content that can be made accessible from within a JSP page via a tag rather than scriptlets. Custom tags help developers follow the MVC architecture, separating code from business logic.

2-10. Including Other JSPs into a Page

Problem

Rather than coding the same header or footer into each JSP, you want to place the content for those page sections into a separate JSP page and then pull them into JSP pages by reference.

Solution

Use the <jsp:include> tag to embed other static or dynamic pages in your JSP page. The following example demonstrates the inclusion of two JSP pages within another. One of the JSP pages is used to formulate the header of the page, and another is used for the footer. The following page demonstrates the main JSP page, which includes two others using the <jsp:include> tag. The JSPX files named recipe02_10-header.jspx and recipe02_10-footer.jspx are included within the body of the main JSP page in order to provide the header and footer sections of the page.

<html xmlns:jsp="http://java.sun.com/JSP/Page"
      xmlns:c="http://java.sun.com/jcp/jstl/core"
      version="2.0">

    <jsp:directive.page contentType="text/html" pageEncoding="UTF-8"/>
    <head>
        <title>Recipe 2-09: Including Other JSPs into a Page</title>
    </head>
    <body>
        <jsp:include page="recipe02_10-header.jspx" />
        <h1>This is the body of the main JSP.</h1>
        <p>
            Both the header and footer for this page were created as separate JSPs.
        </p>
        <jsp:include page="recipe02_10-footer.jspx"/>

    </body>

</html>

Next is the JSP code that comprises the page header. It’s nothing fancy but is a separate JSP page nonetheless.

<html xmlns:jsp="http://java.sun.com/JSP/Page" version="2.0">

    <jsp:directive.page contentType="text/html" pageEncoding="UTF-8"/>

    <p>This is the page header</p>
</html>

The next JSP code makes up the page footer:

<html xmlns:jsp="http://java.sun.com/JSP/Page" version="2.0">

    <jsp:directive.page contentType="text/html" pageEncoding="UTF-8"/>

    <p>This is the page footer</p>

</html>

In the end, these three pages create a single page that contains a header, a body, and a footer.

How It Works

Including other JSP pages helps increase developer productivity and reduces maintenance time. Using this technique, a developer can extract any JSP features that appear in multiple pages and place them into a separate JSP page. Doing so will allow a single point of maintenance when one of these features needs to be updated.

To include another page within a JSP page, use the <jsp:include> tag. The <jsp:include> tag allows embedding a static file or another web component. The tag includes a page attribute, which is used to specify the relative URL or an expression that results in another file or web component to include in the page.

image Note   The tag also has an optional flush attribute, which can be set to either true or false to indicate whether the output buffer should be flushed prior to the page inclusion. The default value for the flush attribute is false.

Optionally, <jsp:param> clauses can be placed between the opening and closing <jsp:include> tags to pass one or more name-value pairs to the included resource if the resource is dynamic. An example of performing this technique would resemble something like the following lines of code. In the following lines, a parameter with a name of bookAuthor and a value of Juneau is passed to the header JSP page.

<jsp:include page="header.jspx">
    <jsp:param name="bookAuthor" value="Juneau"/>
</jsp:include>

The ability to include other content within a JSP page provides a means to encapsulate resources and static content. This allows developers to create content once and include it in many pages.

2-11. Creating an Input Form for a Database Record

Problem

You want to create a JSP page that will be used to input information that will be inserted as a database record.

Solution

Create an input form and use a Java servlet action method to insert the values into the database. This solution requires a JSP document and a Java servlet in order to complete the database input form. In the following example, an input form is created within a JSP document to populate records within a database table named RECIPES. When the user enters the information into the text fields on the form and clicked the submit button, a servlet is called that performs the database insert transaction.

The following code is the JSP document that is used to create the input form for the database application:

<!--
    Document   : recipe02_11
    Author     : juneau
-->
<html xmlns:jsp="http://java.sun.com/JSP/Page"
      xmlns:c="http://java.sun.com/jcp/jstl/core"
      version="2.0">

    <jsp:directive.page contentType="text/html" pageEncoding="UTF-8"/>
    <head>
        <title>Recipe 2-11: Creating an Input Form</title>
    </head>
    <body>
        <h1>Recipe Input Form</h1>
        <p>
            Please insert recipe details using the text fields below.
        </p>
        ${ recipeBean.message }
        <form method="POST" action="/JavaEERecipes/RecipeServlet">
            Recipe Number: <input id="recipeNumber" name="recipeNumber" size="30"/>
            <br/>
            Recipe Name: <input id="name" name="name" size="30"/>
            <br/>
            Recipe Description: <input id="description" name="description" size="30"/>
            <br/>
            Recipe Text: <input id="text" name="text" size="30"/>
            <br/>
            <br/>
            <input type="submit"/>
        </form>
    </body>
</html>

Next is the code for a servlet named RecipeServlet. It is responsible for reading the request parameters from the JSP document input form and inserting the fields into the database.

package org.javaeerecipes.chapter02.recipe02_11;

import java.io.IOException;
import java.io.PrintWriter;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.SQLException;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

/**
 * Recipe 2-11:  Creating an Input Form
 * @author juneau
 */
@WebServlet(name = "RecipeServlet", urlPatterns = {"/RecipeServlet"})
public class RecipeServlet extends HttpServlet {

 
    /**
     * Processes requests for both HTTP
     * <code>GET</code> and
     * <code>POST</code> methods.
     *
     * @param request servlet request
     * @param response servlet response
     * @throws ServletException if a servlet-specific error occurs
     * @throws IOException if an I/O error occurs
     */
    protected void processRequest(HttpServletRequest request, HttpServletResponse response)
            throws ServletException, IOException {
        response.setContentType("text/html;charset=UTF-8");
        PrintWriter out = response.getWriter();
        int result = -1;
        try {
            /*
             * TODO Perform validation on the request parameters here
             */
            result = insertRow (request.getParameter("recipeNumber"),
                       request.getParameter("name"),
                       request.getParameter("description"),
                       request.getParameter("text"));
            out.println("<html>");
            out.println("<head>");
            out.println("<title>Servlet RecipeServlet</title>");
            out.println("</head>");
            out.println("<body>");
            out.println("<h1>Servlet RecipeServlet at " + request.getContextPath() + "</h1>");
            out.println("<br/><br/>");
            
            if(result > 0){
                out.println("<font color='green'>Record successfully inserted!</font>");
                out.println("<br/><br/><a href='/JavaEERecipes/chapter02/recipe02_11.jspx'>Insert another record</a>");
            } else {
                out.println("<font color='red'>Record NOT inserted!</font>");
                out.println("<br/><br/><a href='/JavaEERecipes/chapter02/recipe02_11.jspx'>Try Again</a>");
            }

            out.println("</body>");
            out.println("</html>");
        } finally {
            out.close();
        }
    }
    
    public int insertRow(String recipeNumber,
                         String name,
                         String description,
                         String text) {
        
        String sql = "INSERT INTO RECIPES VALUES(" +
                     "RECIPES_SEQ.NEXTVAL,?,?,?,?)";
        PreparedStatement stmt = null;
        int result = -1;
        try {
            CreateConnection createConn = new CreateConnection();
            Connection conn = createConn.getConnection();
            stmt = (PreparedStatement) conn.prepareStatement(sql);
            stmt.setString(1, recipeNumber);
            stmt.setString(2, name);
            stmt.setString(3, description);
            stmt.setString(4, text);
            // Returns row-count or 0 if not successful
            result = stmt.executeUpdate();
            if (result > 0){
                 System.out.println("-- Record created --");
            } else {
                System.out.println("!! Record NOT Created !!");
            }
        } catch (SQLException e) {
            e.printStackTrace();
        } finally {
            if (stmt != null) {
                try {
                    stmt.close();
                } catch (SQLException ex) {
                    ex.printStackTrace();
                }
            }
            
        }
        return result;
    }

 
    @Override
    protected void doGet(HttpServletRequest request, HttpServletResponse response)
            throws ServletException, IOException {
        processRequest(request, response);
    }

 
    @Override
    protected void doPost(HttpServletRequest request, HttpServletResponse response)
            throws ServletException, IOException {
        processRequest(request, response);
    }
}

If the request is successful, the record will be inserted into the database, and the user will be able to click a link to add another record. Of course, in a real-life application, you would want to code some validation using JavaScript either within the input form or within the server-side Java code to help ensure database integrity.

How It Works

A fundamental task to almost every enterprise application is the use of a database input form. Database input forms make it easy for end users to populate database tables with data. When using JSP technology along with servlets, this operation can become fairly simple. As you have seen in the example to this recipe, writing a JSP input form is straightforward and can be coded using basic HTML. The key is to set up a Java servlet to receive a submitted request and process the records using the servlet. This provides an easy mechanism for separating web content from the application logic.

In the example, a JSP document named recipe02_11.jspx contains a standard HTML form with a method of POST and an action of /JavaEERecipes/RecipeServlet. The input form contains four fields, which map to database columns into which the data will eventually be inserted. The input tags contain the name of four corresponding fields (recipeNumber, name, description, and text), which will be passed to the form action when submitted. As you can see, the only reference to the Java code is the name of the servlet that is contained within the form action attribute.

The Java servlet named RecipeServlet is responsible for obtaining the request parameters that were submitted via the JSP document, validating them accordingly (not shown in the example), and inserting them into the database. When the page is submitted, RecipeServlet is invoked, and the request is sent to the doPost method since the HTML action method is POST. Both the doGet and doPost methods are really just wrapper methods for a processing method named processRequest, which is responsible for most of the work. The processRequest method is responsible for obtaining the request parameters, inserting them into the database, and sending a response to the client. A PrintWriter object is declared and created by making a call to response.getWriter() first because this object will be used later to help form the response that is sent to the client. Next, an int value named result is set up and initialized to -1. This variable will be used for determining whether the SQL insert worked or failed. After those declarations, a try-catch block is opened, and the first line of the try block is a call to the insertRow method, passing the request parameters as values. The result variable is going to accept the int value that is returned from the execution of the insertRows method, indicating whether the insert was successful.

result = insertRow (request.getParameter("recipeNumber"),
                       request.getParameter("name"),
                       request.getParameter("description"),
                       request.getParameter("text"));

As such, an SQL insert statement is assigned to a String named sql, and it is set up using the PreparedStatement format. Each question mark in the SQL string corresponds to a parameter that will be substituted in the string when the SQL is executed.

String sql = "INSERT INTO RECIPES VALUES(" +
                     "RECIPES_SEQ.NEXTVAL,?,?,?,?)";

Next, a PreparedStatement and int values are initialized, and then a try-catch-finally block is opened, which will contain the SQL insert code. Within the block, a Connection object is created by calling a helper class named CreateConnection. If you want to read more about this helper class, then you can read Chapter 7 on JDBC. For now, all you need to know is that CreateConnection will return a database connection that can then be used to work with the database. If for some reason the connection fails, the catch block will be executed, followed by the finally block. A PreparedStatement object is created from the successful connection, and the SQL string that contains the database insert is assigned to it. Each of the request parameter values, in turn, is then set as a parameter to the PreparedStatement. Lastly, the PreparedStatement’s executeUpdate method is called, which performs an insert to the database. The return value of executeUpdate is assigned to the result variable and then returned to the processRequest method. Once the control is returned to processRequest, the servlet response is created using a series of PrintWriter statements. If the insert was successful, then a message indicating success is displayed. Likewise, if unsuccessful, then a message indicating failure is displayed.

Developing database input forms with JSP is fairly easy to do. To preserve the MVC structure, using a Java servlet for handing the request and database logic is the best choice.

2-12. Looping Through Database Records Within a Page

Problem

You want to display the records from a database table on your JSP page.

Solution

Encapsulate the database logic in a Java class and access it from the JSP page. Use the JSTL c:forEach element to iterate through the database rows and display them on the page. Two Java classes would be used for working with the data in this situation. One of the classes would represent the table, which you are querying from the database, and it would contain fields for each column in that table. Another JavaBean class would be used to contain the database business logic for querying the database.

The example for this recipe will display the first and last names of each author contained within the AUTHORS database table. The following code is used to create the JSP document that will display the data from the table using a standard HTML-based table along with the JSTL <c:forEach> tag to loop through the rows:

<!--
    Document   : recipe02_12
    Author     : juneau
-->
<html xmlns:jsp="http://java.sun.com/JSP/Page"
      xmlns:c="http://java.sun.com/jcp/jstl/core"
      version="2.0">

    <jsp:directive.page contentType="text/html" pageEncoding="UTF-8"/>
    <jsp:useBean id="authorBean" scope="session"     class="org.javaeerecipes.chapter02.recipe02_12.AuthorBean"/>
    <head>
        <title>Recipe 2-12: Looping Through Database Records within a Page </title>
    </head>
    <body>
        <h1>Authors</h1>
        <p>
            The authors from the books which Josh Juneau has worked on are printed below.
        </p>
        <table border="1">
            
        <c:forEach items="${authorBean.authorList }" var="author">
            <tr>
                <td> ${ author.first } ${ author.last }</td>
            </tr>
        </c:forEach>
        </table>
    </body>
</html>

As you can see, <c:forEach> is used to loop through the items contained within ${authorBean.authorList}. Each item within the list is an object of type Author. The following Java code is that of the Author class, which is used for holding the data contained within each table row:

package org.javaeerecipes.chapter02.recipe02_12;

/**
 *
 * @author juneau
 */
public class Author implements java.io.Serializable {
    private int id;
    private String first;
    private String last;
    
    public Author(){
        id = -1;
        first = null;
        last = null;
    }

    /**
     * @return the id
     */
    public int getId() {
        return id;
    }

    /**
     * @param id the id to set
     */
    public void setId(int id) {
        this.id = id;
    }

    /**
     * @return the first
     */
    public String getFirst() {
        return first;
    }

    /**
     * @param first the first to set
     */
    public void setFirst(String first) {
        this.first = first;
    }

    /**
     * @return the last
     */
    public String getLast() {
        return last;
    }

    /**
     * @param last the last to set
     */
    public void setLast(String last) {
        this.last = last;
    }
}

Lastly, the JSP document makes reference to a JavaBean named AuthorBean, which contains the business logic to query the data and return it as a list to the JSP page. The following code is what is contained within the AuthorBean class:

package org.javaeerecipes.chapter02.recipe02_12;

import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.List;
import org.javaeerecipes.common.CreateConnection;

/**
 * Recipe 2-12
 * @author juneau
 */
public class AuthorBean implements java.io.Serializable {
    
    public static Connection conn = null;
    private List authorList = null;
    

    public AuthorBean(){
        
    }

    public List queryAuthors(){
        String sql = "SELECT ID, FIRST, LAST FROM BOOK_AUTHOR";
        List <Author> authorList = new ArrayList<Author>();
        PreparedStatement stmt = null;
        ResultSet rs = null;
        int result = -1;
        try {
            CreateConnection createConn = new CreateConnection();
            conn = createConn.getConnection();
            stmt = (PreparedStatement) conn.prepareStatement(sql);
            
            // Returns row-count or 0 if not successful
             rs = stmt.executeQuery();
             while (rs.next()){
                 Author author = new Author();
                 author.setId(rs.getInt("ID"));
                 author.setFirst((rs.getString("FIRST")));
                 author.setLast(rs.getString("LAST"));
                 authorList.add(author);
             }
        } catch (SQLException e) {
            e.printStackTrace();
        } finally {
            if (stmt != null) {
                try {
                    stmt.close();
                } catch (SQLException ex) {
                    ex.printStackTrace();
                }
            }
            
        }
        return authorList;
    }
    
    public List getAuthorList(){
        authorList = queryAuthors();
        return authorList;
    }
}

The names of the authors contained within the records in the table will be displayed on the page.

How It Works

Almost any enterprise application performs some sort of database querying. Oftentimes results from a database query are displayed in a table format. The example in this recipe demonstrates how to query a database and return the results to a JSP page for display in a standard HTML table. The JSP page in this example makes use of the JSTL c:forEach element to iterate through the results of the database query. Note that there is more than one way to develop this type of database query using JSP; however, the format demonstrated in this recipe is most recommended for use in a production enterprise environment.

As mentioned previously, the JSP page in this recipe uses a combination of the jsp:useBean element and the c:forEach element to iterate over the results of a database query. The logic for querying the database resides within a server-side JavaBean class that is referenced within the jsp:useBean element on the page. In the example, the JavaBean is named AuthorBean, and it is responsible for querying a database table named AUTHORS and populating a list of Author objects with the results of the query. When the c:forEach element is evaluated with the items attribute set to ${authorBean.authorList}, it calls upon the JavaBean method named getAuthorList because JSP expressions always append "get" to a method call behind the scenes and also capitalizes the first letter of the method name within the call. When the getAuthorList method is called, the authorList field is populated via a call to queryAuthors. The queryAuthors method utilizes a Java Database Connectivity (JDBC) database call to obtain the authors from the AUTHORS table. A new Author object is created for each row returned by the database query, and each new Author object is, in turn, added to the authorList. In the end, the populated authorList contains a number of Author objects, and it is returned to the JSP page and iterated over utilizing the c:forEach element.

The c:forEach element contains an attribute named var, and this should be set equal to a string that will represent each element in the list that is being iterated over. The var is then used between the opening and closing c:forEach element tags to reference each element in the list, printing out each author's first and last names.

This recipe provides some insight on how to combine the power of JSTL tags with other technologies such as JDBC to produce very useful results. To learn more about the different JSTL tags that are part of JSP, please visit the online documentation at www.oracle.com/technetwork/java/jstl-137486.html. To learn more about JDBC, please read Chapter 7 of this book.

2-13. Handling JSP Errors

Problem

You want to display a nicely formatted error page if a JSP page encounters an error.

Solution

Create a standard error page, and forward control to the error page if an exception occurs within the JSP page. The following JSP document, in JSP format (not JSPX), demonstrates a standard error page to display if an error occurs within a JSP application. If an exception occurs within any JSP page in the application, the following error page will be displayed.

image Note   The example in the solution for this recipe uses the JSTL fmt library, which provides convenient access to formatting capabilities that allow for localization of text as well as date and number formatting. Text localization capabilities allow locales to be set so that text can be formatted into different languages, depending upon the user locale. Tags used for date manipulation make it easy for developers to format dates and times easily within a JSP page and also provide a way to parse dates and times for data input. Lastly, number-formatting tags provide a way to format and parse numeric data within pages. To learn more about the JSTL fmt tag library, please refer to the online documentation at http://jstl.java.net/.

<%--
    Document   : recipe02_13_errorPage
    Author     : juneau
--%>

<%@ page contentType="text/html" pageEncoding="UTF-8"%>
<%@ page isErrorPage="true" %>
<%@ taglib uri="http://java.sun.com/jcp/jstl/core"
     prefix="c" %>
<%@ taglib uri="http://java.sun.com/jcp/jstl/fmt"
     prefix="fmt" %>
<!DOCTYPE html>
<html>
    <head>
        <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
        <title>JSP Error Page</title>
    </head>
    <body>
        <h1>Error Encountered</h1>
        <br/>
        <br/>
        <p>
            The application has encountered the following error:
            <br/>
            <fmt:message key="ServerError"/>: ${pageContext.errorData.statusCode}

        </p>
    </body>
</html>

For example, the following JSP would create an error (NullPointerException) if the parameter designated as param is null. If this occurs, the indicated error page would be displayed.

<!--
    Document   : recipe02_13
    Author     : juneau
-->
<html xmlns:jsp="http://java.sun.com/JSP/Page"
      xmlns:c="http://java.sun.com/jcp/jstl/core"
      version="2.0">

    <jsp:directive.page contentType="text/html" pageEncoding="UTF-8"/>
    <jsp:directive.page errorPage="recipe02_13_errorPage.jsp"/>
    
    <head>
        <title>Recipe 2-13:  </title>
    </head>
    <body>
        <h1>There is an error on this page</h1>
        <p>
            This will produce an error:
            <jsp:scriptlet>
             if (request.getParameter("param").equals("value")) {
                System.out.println("test");
             }
            </jsp:scriptlet>
        </p>
    </body>

</html>

How It Works

One of the most annoying issues for users while working with applications is when an error is thrown. A nasty, long stack trace is often produced, and the user is left with no idea how to resolve the error. It is better to display a nice and user-friendly error page when such an error occurs. The JSP technology allows an error page to be designated by adding a page directive to each JSP page that may produce an error. The directive should designate an error page that will be displayed if the page containing the directive produces an error.

The second JSP document in the solution to this recipe demonstrates a JSP page that will throw an error if the parameter being requested within the page is null. If this were to occur and there were no error page specified, then a NullPointerException error message would be displayed. However, this JSP indicates an error page by designating it within a page directive using the following syntax:

<jsp:directive.page errorPage="recipe02_13_errorPage.jsp"/>

When an error occurs on the example page, recipe02_13.errorPage.jsp is displayed. The first JSP document listed in the solution to this recipe contains the sources for the recipe02_13.errorPage.jsp page. It is flagged as an error page because it includes a page directive indicating as such:

<%@ page isErrorPage="true" %>

An error page is able to determine the error code, status, exception, and an array of other information by using the pageContext implicit object. In the example, the ${pageContext.errorData.statusCode} expression is used to display the status code of the exception. Table 2-5 displays the other possible pieces of information that can be gleaned from the pageContext object.

Table 2-5. pageContext Implicit Object Exception Information

Expression Value
pageContext.errorData Provides access to the error information
pageContext.exception Returns the current value of the exception object
pageContext.errorData.requestURI Returns the request URI
pageContext.errorData.servletName Returns the name of the servlet invoked
pageContext.errorData.statusCode Returns the error status code
pageContext.errorData.throwable Returns the throwable that caused the error

Providing user-friendly error pages in any application can help create a more usable and overall more functional experience for the end user. JSP and Java technology provide robust exception handling and mechanisms that can be used to help users and administrators alike when exceptions occur.

2-14. Disabling Scriptlets in Pages

Problem

You want to ensure that Java code cannot be embedded into JSP pages within your web application.

Solution

Set the scripting-invalid element within the web deployment descriptor to true. The following excerpt from a web.xml deployment descriptor demonstrates how to do so:

<jsp-config>
    <jsp-property-group>
        <scripting-invalid>true</scripting-invalid>
    </jsp-property-group>
</jsp-config>

How It Works

When working in an environment that encourages the use of the Model-View-Controller architecture, it can be useful to prohibit the use of scriptlets within JSP pages and documents. When JSP 2.1 was released, it provided solutions to help developers move Java code out of JSP pages and into server-side Java classes where it belonged. In the early years of JSP, pages were cluttered with scriptlets and markup. This made it difficult for developers to separate business logic from content, and it was hard to find good tools to help develop such pages effectively. JSP 2.1 introduced tags, which make it possible to eliminate the use of scriptlets within JSP pages, and this helps maintain the use of the MVC architecture.

To prohibit the use of scriptlets within JSP pages in an application, add the jsp-config element within the web.xml file of the application of which you want to enforce the rule. Add a subelement of jsp-property-group along with the scripting-invalid element. The value of the scripting-invalid element should be set to true.

2-15. Ignoring EL in Pages

Problem

You want to turn off EL expression translation within your JSP page so that older applications will be able to pass through expressions verbatim.

Solution #1

Escape the EL expressions within the page by using the character before any expressions. For instance, the following expressions will be ignored because the character appears before them:

${elBean.myProperty}
${2 + 4}

Solution #2

Configure a JSP property group within the web.xml file for the application. Within the web.xml file, a <jsp-property-group> element can contain child elements that characterize how the JSP page evaluates specified items. By including an <el-ignored>true</el-ignored> element, all EL within the application's JSP documents will be ignored and treated as literals. The following excerpt from web.xml demonstrates this feature:

<jsp-property-group>
     <el-ignored>true</el-ignored>
</jsp-property-group>

Solution #3

Include a page directive including the isELIgnored attribute, and set it to true. The following page directive can be placed at the top of a given JSP document to allow each EL expression to be treated as a literal:

<jsp:directive.page isELIgnored="true"/>

or in a standard JSP:

<%@ page isELIgnored="true" %>

How It Works

There may be a situation in which the evaluation of JSP EL expressions should be turned off. This occurs most often in cases of legacy applications using older versions of JSP technology; EL expressions were not yet available. There are a few different ways to turn off the evaluation of EL expressions, and this recipe demonstrates each of them.

In the first solution to this recipe, the escape technique is demonstrated. An EL expression can be escaped by placing the character directly before the expression, as shown in the example. Doing so will cause the JSP interpreter to treat the expression as a string literal, and the output on the page will be the expression itself, rather than its evaluation. The second solution to this recipe demonstrates adding a jsp-property-group to the web.xml deployment descriptor in order to ignore EL. All EL within an application will be ignored by including the isELIgnored element and providing a true value for it. Lastly, the final solution demonstrates how to ignore EL on a page-by-page basis by including a page directive with the isELIgnored attribute set to true.

Each of the different solutions for ignoring EL allows coverage to different parts of the application. The solution you choose should depend upon how broadly you want to ignore EL throughout an application.

..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset
3.129.210.91