JSP Syntax and SemanticsJSP syntax is quite straightforward and compact: it all fits on a double-page syntax card available from Sun at http://java.sun.com/products/jsp/syntax.pdf (see also Appendix F). A JSP page consists of template data and JSP elements. Template data is just HTML or XML; the JSP processor passes it on to output untouched. JSP elements fall into the following groups: directives, scripting elements, comments, and actions. Scripting elements are further subdivided into declarations, expressions and code fragments, or scriptlets. The first three groups have always been part of JSP and they have non-XML syntax, as well as alternative XML/Namespace syntax. The "actions" group is more recent and has only XML/Namespace syntax. Non-XML SyntaxNon-XML syntax of directives, scripting elements and comments is summarized in the table below. You have seen all of them used in our simple example
Alternative XML SyntaxA JSP page that is also a valid XML document opens with the following declarations: <! DOCTYPE root PUBLIC -//Sun Microsystems Inc.//DTD JavaServer Pages Version 1.0//EN "http://java.sun.com/products/jsp/dtd/jspcore_1_0.dtd"> <jsp:root xmlns:jsp="http://java.sun.com/products/jsp/dtd/jsp_1_0.dtd"> XML alternatives to older, non-XML syntax are summarized in the following table:
Directives are empty elements that take a number of attributes. Scripting elements have no attributes, and only PCDATA content. That content will often contain special characters, such as <, & and quotes. These have to be escaped, or else the entire body of the scripting element has to be made into a CDATA section. The same consideration applies to action elements, see below. To us, writing extensive scripting elements seems like an error-prone process in precisely the complex cases where it really matters. It is possible that good "lint"-style tools will appear that will catch a forgotten closing bracket. A better approach is never to write a scripting element that is longer than a line or two, and use Java beans instead. The taglib DirectiveThe one remaining JSP element, the taglib directive, is not mentioned in the table because it does not translate into an XML element, but rather results in a change of namespace. The purpose of the taglib directive is to introduce an additional library of tags. That library is identified by a namespace uri and a namespace prefix, as in: <%@ taglib uri="http://www.mytaglibs.com/tags" prefix="private" %> In the XML document corresponding to JSP pages, the taglib directive is represented as a Namespace attribute (xmlns:name-of-tag-library). The taglib directive is not part of JSP 1.0 but JSP 1.1, so this whole little section may seem premature. The reason we included it is because we believe that, once the directive is implemented, it will become an extremely powerful tool for creating mini-languages. Semantics in Briefq Directives are addressed to the JSP engine. They do not produce any output. q Within scripting elements, Declarations are exactly that, Java declarations and, perhaps, initializations. Declarations do not produce any output. q Expressions are Java expressions; they are evaluated and their values are inserted into the output stream. q Code fragments are stretches of Java code. They don't have to be complete statements or valid expressions. q JSP comments are not sent to the client; they are strictly for documenting code. q You can also use standard XML comments in a JSP page and they will be treated like regular XML comments. You can even include non-XML JSP content in XML-style comments, and it will be treated as part of comments, i.e. ignored. The semantics of scripting elements are easy to understand; it's just Java code. Directives and their attributes require a little more discussion. JSP DirectivesThere are three directives: page, include and taglib. However, taglib is not implemented in version 1.0, so we only use page and include. Page DirectiveThe page directive has a number of attributes; the easiest way to show them all is to quote the DTD definition of the jsp.directive.page element: <!ELEMENT jsp:directive.page EMPTY> <!ATTLIST jsp:directive.page language CDATA java extends CDATA #IMPLIED contentType CDATA text/html; ISO-8859-1 import CDATA #IMPLIED session (true|false)true buffer CDATA 8kb autoFlush (true|false)true isThreadSafe(true|false)true info CDATA #IMPLIED errorPage CDATA #IMPLIED isErrorPage(true|false)false > Let us go through them in order.
Here is an example of using page from the Birthdays application (presented in full later in this chapter): <%@ page import="java.util.*, MyNa.utils.*" errorPage="errorpage.jsp" %> Action ElementsAction elements fall into three groups as follows: q actions having to do with beans: useBean, getProperty, setProperty q include and forward actions, corresponding to the include() and forward() methods of the RequestDispatcher interface in the javax.servlet package (see Chapter 1) q the plugin action, for downloading a plug-in to the client (we don't use it in this book see the documentation for more details) All action tags appear with the jsp: namespace prefix. Some action elements are EMPTY, with a number of attributes; others have content. When action elements appear in a JSP page that is intended to be a well-formed and valid XML document, their content frequently has to be wrapped in a CDATA section. Beans and propertiesHere is an example of using action elements from the Birthdays application which we develop later in this chapter: <jsp:useBean id="bbean" scope="session" class="birthday.BirthdayBean" /> The id attribute of useBean specifies the name of the bean within the application. The scope attribute can have one of the values we discussed above: page, request, session, or application. Finally, the class attribute gives the fully-qualified class name of the bean. As the DTD says: <!ELEMENT jsp:useBean %jsp.body;> <!ATTLIST jsp:useBean id ID #REQUIRED class CDATA #REQUIRED scope (page|session|request|application) page You will notice from the first line that the DTD specifies useBean as having %jsp.body; content. That content can be empty, as in our example, but it may not be. If there is content, it is usually setProperty elements that customize the bean. Alternatively, setProperty elements may follow the useBean element. Here is an example of using setProperty: <jsp:setProperty name="bbean" property="*" /> To set a property, one needs a property name and a value. There are two sources for values. One is the attributes of a setProperty element: <jsp:setProperty name="abean" property="prop1" value="value1" /> More often, the values come from Request parameters, ultimately, from form inputs on the client. In this case, instead of value, you specify the name of the parameter whose value is to be used: <jsp:setProperty name="abean" property="prop1" param="param1" /> If the name of the bean property is the same as the name of the request parameter, then you don't have to specify the parameter name. If you want all request parameters copied to bean properties of the same name, you code property="*", as in the first example we looked at, above. The Include ActionHere's an example that illustrates the include action. The action is performed only if the condition in the preceding scriptlet holds true: <% }else if("change".equals(select)){ %> We have changed <%= bbean.getNumberAffected() %> rows. <%@
include file="continue.jsp" %> Two Include MechanismsIncluding material from other files is an important tool for breaking up JSP pages into manageable components. There are two mechanisms for inclusion, a directive and an action. Their properties are:
We have found the include directive very useful in structuring JSP applications, as you will see in the example later in this chapter. We hope you agree that, with the possible exception of synchronization issues, the syntax and semantics of JSP pages are quite clear and intuitive. (This does not mean that the current generation of JSP engines always behave in clear and intuitive ways.) The main challenge, as we said in the introduction, is in large-scale structuring of JSP applications. This is what we are going to work on now. In the next section we present two possible approaches, then illustrate one of them in a larger example application. |