站内搜索: 请输入搜索关键词
当前页面: 图书首页 > Servlets and JavaServer Pages: The J2EE Technology Web Tier

Servlets and JavaServer Pages: The J2EE Technology Web Tier

[ directory ]Good Use of JavaBeans Summary

JSP. 2.0 Expression Language

One of the main features of JSP 2.0 is a JSP-specific expression language, commonly called the JSP EL. The JSP EL is superior to the JSP expressions described in Chapter 3 because it provides a cleaner syntax and a language designed specially for JSP. Additionally, the JSP EL works well with JSP in XML syntax. As is soon explained, the JSP EL does not require the use of characters that are part of XML markupthis means JSP EL can inherently work with JSP in XML syntax; regular JSP expressions do not.

The benefits of the JSP EL are easy to illustrate. A JSP author can use an expression, such as <%= ... %>, to access a runtime value. The syntax works, but it is awkward when embedded as a tag's attribute value, and the expression directly embeds Java syntax. For example, a custom tag with a dynamic attribute value previously had to be authored as the following:



<ex:tag attribute="<%= pageContext.getAttribute("value") %>">

The syntax is awkward because it complicates the simple custom tag syntax with markup inside a tag. Additionally, the expression must use complete Java syntax which further damages the simplicity of the markup. If the preceding was authored using the JSP EL, it would look like this:



<ex:tag attribute="${value}">

The functionality is the same, but the code is much simpler. Another feature of the JSP EL is that it can be used anywhere in a JSP, not just in a custom tag attribute. This makes the JSP EL a simple, powerful alternative to scripting elements.

Disabling the EL

Before JSP 2.0 the expression syntax, ${...}, used by the JSP EL was not reserved. Because of this the EL might cause backwards compatibility issues with JSP 1.2 and earlier code. To prevent the new EL from causing troubles with old code, by default the JSP EL is disabled for Web Applications that use a web.xml file as defined by Servlets 2.3 or the following. For applications that use the Servlet 2.4 defined web.xml, the JSP EL is automatically enabled. Any individual JSP may enable or disable the JSP EL through use of the isScriptingEnabled page directive as described in Chapter 2. The JSP EL may also be configured application-wide using the scripting-enabled element of the web.xml JSP configuration.

JSP EL Syntax

The JSP Expression Language is designed to be simple, robust, and minimally impact backwards compatibility issues. The expression language handles both expressions and literals. Expressions are always enclosed by the ${ } characters. For example:



<c:if test="${value < 10}" />

Values that do not begin with ${ are still treated as a literal. The value of the literal is parsed to the expected type depending on the tag's TLD (Tag Library Descriptor) entry:



<c:if test="true" />

In cases where a literal value contains the ${ characters, it must be escaped with the $\{ characters.

Attributes

Attributes in the EL are accessed by name, with an optional scope. Members, getter methods, and array items are all treated in the same fashion and replaced with a " . ". Properties accessed using this method may be nested arbitrarily deep. For example, an object a with a member b would be accessed as ${a.b}. Likewise an array a could have the b member accessed with the same expressionin other words, a[b] could be written as ${a.b} using the EL. Additionally, a JavaBean a with a getter method for b would use the same expressionin other words, a.getB() could also be written as ${a.b}. Note that the two syntaxes are interchangeable, that is, ${a.b} is the equivalent of ${a["b"]}.

Objects do not have to be in page scope for the EL to use them. The EL evaluates an identifier by looking up its value as an attribute according to the behavior of PageContext findAttribute() method. For example, ${value} will look for the attribute named value by searching the page, request, session, and application scopes in that order. If the attribute is not found, null is returned.

The EL defines a set of implicit objects with pageContext, page, request, session, and application matching the JSP equivalents. The EL additionally defines the following implicit objects:

When an expression references one of the implicit objects by name, the appropriate object is returned instead of the corresponding attribute. For example, ${request} returns the HttpServletRequest object, even if there is an existing request attribute in some scope.

Literals

The JSTL EL defines the following literals:

Operators

The EL provides the basic arithmetic operators: +, -, *, and /, along with the modulus operator %. The EL also provides logic operators and, or, and not, which correspond to the Java operators &&, ||, and !, respectively. EL support for comparison operations is identical to Java: ==, !=, <, >, <=, >=. Comparisons may be made against other values or against boolean, string, integer, or floating point literals. The abbreviations lt, gt, lte, or gte may also be used as replacements for <, >, <=, and >=, respectively.

The EL operators use the following order of preference from top to bottom, left to right:

Reserved Words

The EL defined a few reserved words that should not be used within EL expressions: and, eq, gt, true, instanceof, or, ne, le, false, empty, not, lt, ge, null, div, and mod. Some of the words currently do not do anything but may be used in future versions of the JSP specification.

EL Functions

A feature of the EL is function binding. An EL function borrows the idea of qualified namespaces, as used, to allow EL syntax to be linked to static Java functions. Functions that are available to be used by the EL must be specified by a TLD by using the function element. For example:



<taglib>
...
  <function>
  <name>foo</name>
  <function-class>com.jspbook.FooFunctions</function-class>
  <function-signature>
    String bar(String)
  </function-signature>
 </function>
</taglib>

The preceding code defines a function that named foo and maps to the bar() static function that must be defined by the com.jspbook.FooFunctions class. The signature of the method is additionally defined by the function-signature element in the TLD so that the EL can appropriately validate input and return the correct type of object. In general, each function is defined using one function element, and a TLD may define as many functions as needed.

EL functions are used by specifying the function name followed by (), with parameter values defined as needed. If the preceding function was being used, with the default namespace, it would be: ${bar('a string')}. The expression would return a String object and could be used in either template text or a custom tag's attribute. Should functions from non-default namespaces be necessary, they must be declared explicitly by placing the appropriate namespace before the function call. For example, assuming the bar function was in a tag library declared with the prefix f, then it would be explicitly declared using: ${f:bar('a string')}.

In theory, EL functions can do all sorts of things and JSTL 1.1 introduced a number of them, in particular string manipulation functions. Chapter 6 details the JSTL and associated functionality.

Good Uses of the JSP EL

There are several use cases where you can accomplish the same task using either traditional JSP expressions, the JSP EL, the JavaBean actions, or a combination of the three. In the one obvious case, putting XML-friendly expression in a JSP authored in XML syntax, always use the JSP EL; there is no reason not to. In most of the other cases, also consider using the JSP EL as a preferred choice. Compared to regular JSP expressions, the JSP EL provides a simpler, non-Java method of accomplishing the same job. Additionally, with JSP EL functions you can literally do anything that a regular JSP expression can do.

The most common use case of JSP expressions, JSP EL expressions, and JavaBeans is to access a scoped Java object and display it as a string. In this case the JSP EL does a great job, and for many practical purposes is all you will ever need the JSP EL to do. A simple ${foo} and a scoped variable, in any scope, will be displayed as a string. The syntax is natural, simple, and most importantly adequate. For these reasons you will notice that almost every single example in the later chapters uses the JSP EL. In general, this book suggests you always prefer the JSP EL over the JavaBean actions and regular JSP expressions for this type of functionality.

Besides the more obvious good uses, the ones that you will find scattered throughout the book, an excellent use of the JSP EL is to not abuse its functionality. The JSP EL is nothing more than an expression language. Yes, the JSP EL can do arithmetic operations, boolean operations, and bind static Java methods; however, do not go out of the way to use this functionality. Keep in mind JSP provides several methods of accomplishing the same goal. If you want to take a stab at what most developers consider "good practice", read through the later chapters of this book. You should note that custom tags and Servlet-related functionality are commonly used to encapsulate a lot of code, and JSP is usually used as a simple presentation layer that only requires the basic ${foo} use of the JSP EL.

The JSP EL Doesn't Require JavaBeans

A handy technique to speed up Web Application development is to use the JSP EL and java.util.Properties objects (or any map object) to replace JavaBeans. A good traditional design practice is to divide up a dynamic page into pure Java code and a simple JSP with as few scripting elements as possible. In order to communicate between the two parts, a JavaBean with the appropriate getter and setter methods would be used. Coding the JavaBean is straightforward; however, it does take a little bit of effort and timepossibly more than a little if you are unfamiliar with Java or don't have a nice build system set up for the Web Application. Take, for example, Listing 5-5 and a JSP logically similar to Listing 5-6, both that were shown previously. Listing 5-6 was an example of the JavaBean actions used to access a scoped JavaBean. We will reuse the JSP but change the code to use the JSP EL and then take the setter methods out of the JSP as shown in Listing 5-8.

Listing 5-8. NoJavaBean.jsp
<html>
  <head>
    <title>useBean Example</title>
  </head>
  <body>
  Hello ${user.name}, welcome to this web page!
  </body>
</html>

Note the page is simplified (as a result of good coding practice suggested in the last section), but we accomplished the same as before. A scoped JavaBean is expected to be available so that the appropriate name value is displayed. Assume the JavaBean is Listing 5-5 that you saw previously, a simple Java class with a few getter and setter methods. Finally assume the code that sets the bean's values is executed sometime before the JSP is invoked (it doesn't matter when or how; later chapters show that Filters are usually used for this). Listing 5-9 shows the changes.

Listing 5-9. NoJavaBean.jsp Bean Setting Logic
...// start of the class or scriptlet
String name = request.getParameter("name");
String password = request.getParameter("password");
// perform an validation required...
User user = new User();
user.setName(name);
user.setPassword(password);
request.setAttribute("user", user);
... // rest of class or scriptlet

The code does nothing surprising; a new instance of the JavaBean is created, populated, and put in request scope. Because the JSP EL expression matches the field "name" to the getName() method of Listing 5-5, the JSP will display the appropriate value.

However, there is no reason a JavaBean needs to be used. We could have just as easily used a java.util.Properties object and completely skipped whatever time and effort are associated with the JavaBean. Listing 5-10 shows what the code might contain.

Listing 5-10. NoJavaBean.jsp Bean Setting Logic, Using a Properties Object
...// start of the class or scriptlet
String name = request.getParameter("name");
String password = request.getParameter("password");
// perform an validation required...
Properties user = new Properties();
user.setProperty("name", name);
user.setProperty("password", password);
request.setAttribute("user", user);
... // rest of class or scriptlet

And now Listing 5-5 would not be needed for the JSP, Listing 5-7, to function properly. What we save is the time and effort required to code and deploy the JavaBean. What is lost is control over what happens during the getter and setter methods, which may or may not be an issue, and we also have the possibility of losing a little performancethe JavaBean is likely going to consume less memory than the Properties object.

However you look at it, the JSP EL does eliminate the need for JavaBeans in most practical situations. Not only do the scoped objects work the same, but it also tends to be easier to default to using java.util.Properties objects instead of JavaBeans. There is less work required to get the project going and less code to worry about maintaining; however, this is a moot point. Properties objects really only work well as a data storage JavaBean, as illustrated in Listing 5-5, and not much else. If you are doing some clever tricks with getter and setter methods, it is likely you will be stuck coding JavaBeans to complement your Web Application, whether you are using the JSP EL or not.

[ directory ]Good Use of JavaBeans Summary