ESP: EcmaScript Pages A Servlet Scripting Tool |
by Ricardo Rocha | |
Java Servlets are a powerful server-side technology providing a versatile mechanism for extending web server functionality. | |
JavaScript (aka EcmaScript) is, by far, the most popular scripting language for the Web. Fesi is a Java-based EcmaScript interpreter developed by Jean-Marc Lugrin. |
ESP (EcmaScript Pages) is a servlet add-on that allows you to write servlets directly in JavaScript and Html while retaining all the power of the Java language and the servlet object model.
This page presents ESP's basics in the following sections:
ESP allows you to write servlets as templates containing regular Html
and embedded EcmaScript code.
Because EcmaScript pages are actually Java servlets, all constructs used in
standard servlet programming are also available within ESP.
ESP is also portable: it should run on any Java servlet engine. So far, it has
been tested on Sun's Java WebServer, LiveSoftware's JRun (under Microsoft's
IIS) and W3c's Jigsaw.
ESP's syntax is somewhat reminiscent of Sun's JSP or Microsoft's ASP.
Because of this, ESP can be rapidly mastered by programmers already
familiar with servlets (or either of the above mentioned
scripting technologies)
as well as by experienced client-side JavaScript developers.
The following scriptlet shows the overall appearance and functionality of
an ESP page:
When processed by the ESP's template processor, the above code will display as:
While this effect could have been achieved in a simpler manner,
I've wanted to emphasize how easy it is to access Java objects
from EcmaScript as well as the overall simplicity of writing an ESP page.
Portions in black are regular Html text. This text is transcribed
to the output verbatim unless subject to selections or
iterations contained in interspersed EcmaScript blocks.
Portions highlighted in blue correspond to embedded EcmaScript codelets.
These come in two flavors: code and expression blocks.
Code blocks (enclosed by <%
and %>) contain
procedural logic in EcmaScript. When executed,
this logic may augment the generated Html output by programatically
printing on the servlet's output stream.
Expression blocks (enclosed by
<%=
and %>)
correspond to non-procedural expressions whose value
is to be substituted inline wherever they occur within regular
Html text.
Scripting languages differ from full-fledged programming languages
like Java in a number of ways. One of them is the "quick'n'dirty"
approach of coding and then testing without the hassle of
setting classpaths, compiling, configuring the web server or,
in general, imposing a complex structure to otherwise simple
programming tasks.
Thanks to the interpreted nature of EcmaScript, ESP is suitable for rapid
prototyping and early design testing. Later in the development cycle,
developers may choose to implement their designs as standard Java servlets
or to deploy the final product as ESP pages.
Star War's aphorism Don't underestimate the power of the Force is
relevant here: EcmaScript provides full access to all Java objects
including, of course, those specifically related to servlets and
servlet programming.
ESP has been successfully tested in complex applications requiring,
for instance, Jdbc database access and RMI interaction with remote
application servers.
Virtually anything achievable using Java can also be done with
EcmaScript. This is so because Fesi's interpreter is written in Java
and was explicitly designed with such compatibility in mind.
Of course, EcmaScript is also completely compatible with JavaScript: they're
actually the same language, except for the so-called "navigator extensions".
Navigator extensions apply only to web browsers and are not relevant in the
context of server-side programming. Thus, typical concerns about compatibility
between Netscape's JavaScript and Microsoft's JScript just don't apply here...
As opposed to the rigor imposed by Java's powerful object-oriented features,
EcmaScript's simplicity makes it easier for newcomers to pick the
language. This is particularly true (and relevant) for client-side web
developers who are typically already fluent in JavaScript.
Finally, the close syntactic resemblance between Java and JavaScript
greatly simplifies moving code between the two languages should this be
necessary, for example, to improve performance for highly active dynamic
web pages.
ESP is not meant to replace either "serious" servlet programming or
JSP. Also, despite its similarity with ASP, ESP doesn't pretend to be a
"bridge" between the two technologies (though it may
be attractive for ASP developers making the transition to servlet technology).
As stated earlier, EcmaScript is an interpreted language. This means
ESP pages can be run immediately after being coded (as long as they're
placed within the Web server's accessible directory structure).
Thanks to this, developing ESP pages is largely a matter of "coding and
hitting Refresh" (or Reload, if you happen to be a Netscape
fan).
In extreme cases, this might impose some penalty to performance-critical pages
but, on the average, the perceived delay tends to be negligible.
All ESP pages are interpreted by the same "physical" servlet
(org.plenix.esp.Servlet). ESP relies on the underlying Web server's
multithreading discipline to ensure proper response time.
ESP uses file caching, so that template files are read and parsed only once
and kept in memory thereafter. Of course, should a template file be modified
after being loaded, ESP will refresh it automatically the next time
the corresponding page is invoked.
A special EcmaScript file (defined by the optional initScript servlet
parameter) is loaded at startup and its contents are made accessible to all
subsequent pages. This file will typically contain EcmaScript library functions
and application-level initializations. Note that the initScript is
NOT an ESP page, it may contain only EcmaScript code; including Html text
in it will cause a runtime error. As usual, this file is refreshed
automatically if changed after being loaded by the ESP servlet.
The object model exposed by ESP coincides entirely with the standard
servlet specification; transparent access to the following objects is
guaranteed:
These objects can be referenced exactly as you would in Java. Thus, the
following are all legal references:
The servlet object corresponds to your Java servlet's
this object. Of course, since the same servlet is shared by all ESP
pages, servlet is actually a global object.
The request and response objects are the same as their
corresponding counterparts in the service method argument list.
These objects are refreshed with each page invocation.
In addition to this fundamental objects, convenient access is also provided to
the following objects:
session is actually a shorthand for request.getSession(true). By
its nature, this object is static for the duration of the client's connection.
As expected,
the session object is typically used to hold session-persistent
data such as Jdbc database connections or RMI object stubs.
input and output are shorthands for request.getInputStream()
and response.getOutputStream() respectively. These two objects are also
refreshed with each page invocation.
I'd have liked to use JSP's in and out names instead but,
alas, in happens to be an EcmaScript reserved word... :-(
Finally, the parameters object contains the collection of parameters
passed to the page through the request's query string. Single-valued
parameters are stored as scalars, multi-valued parameters are stored as arrays.
An individual parameter (for instance, filename) can be referenced as
parameters.filename or (in a more EcmaScript-like fashion) as
parameters["filename"].
Beware, however, that referencing non-existent parameter properties will yield a
runtime error. If you want to be cautious, use the (still deprecated?) form
request.getParameter("filename").
Regular Html text can be freely interspersed within your EcmaScript code,
including conditional or iterative logic as illustrated by the following
snippet:
As expected, Html text enclosed within an if statement scope may
or may not be included in the output depending on the statement's condition.
Similarly, Html text enclosed within while or for statements
will be included in the output as many times as the iteration condition
holds true. In this case, typically, expression blocks will reference variables
successively set to different values during each iteration.
If you're familiar with JavaScript and Html, ESP programming should be
almost immediately obvious. This is also the case for developers with
experience in ASP programming. Note, however, that EcmaScript is the
only scripting language available for ESP; there's no support for
VBScript at all.
For an overview of EcmaScript programming and Java access, please read
Fesi's documentation available
here
ESP is freely available: yours to keep.
I request your feedback about this utility as well as
your suggestions on how to improve it.
ESP was developed based on Sun's Jsdk 2.0.
The template parser was written using Javacc.
ESP comes with a couple of simple examples:
Take a look at the code! There's no documentation like the real thing :-)
Comments can be sent to
Ricardo Rocha.
Enjoy!
Introduction
<%
function getDayTime()
{
var now = java.util.GregorianCalendar.getInstance();
var hour = now.get(java.util.Calendar.HOUR_OF_DAY);
if (hour < 12) return "Morning";
if (hour <= 18) return "Afternoon";
return "Evening";
}
%>
<HTML>
<HEAD>
<TITLE>
Greetings from ESP!
</TITLE>
</HEAD>
<BODY>
<CENTER>
<H1> Good <%=getDayTime()%>! </H1>
<P>
This is an Html page dynamically generated by ESP on
<%=(new java.util.Date()).toString()%>.
</CENTER>
</BODY>
</HTML>
Good Afternoon!
This is an Html page dynamically generated by ESP on
Thu Oct 29 17:16:14 EST 1998.
Why ESP?
How does ESP work?
ESP's Object Model
ESP Authoring Basics
<%
var db = session.getValue("database");
var sqlStatement =
"SELECT deptno, " +
" dname, " +
" loc " +
"FROM dept " +
"ORDER BY deptno";
result = db.executeRetrieval(sqlStatement);
if (!result)
{
output.println("Jdbc Error: " + db.getLastError().toString());
}
else
{
%>
<CENTER>
<TABLE BORDER="1">
<CAPTION>
Department List<HR>
</CAPTION>
<TR>
<TH>Number</TH>
<TH>Name</TH>
<TH>Location</TH>
</TR>
<%
while (result.next())
{
var deptno = result.getColumnItem("deptno");
var dname = result.getColumnItem("dname");
var loc = result.getColumnItem("loc");
%>
<TR>
<TD ALIGN="center">
<A HREF="employees.esp?deptno=<%=deptno.toString()%>">
<%=deptno.toString()%>
</A>
</TD>
<TD><%=dname%></TD>
<TD><%=loc%></TD>
</TR>
<%
}
%>
</CENTER>
</TABLE>
. . .
Wanna give it a try?
To do