Java Server Pages Frequently Asked Questions

Maintainer: Richard Vowles, rvowles@esperanto.org.nz (http://www.esperanto.org.nz)

For text users of this document, there is now an HTML version at the above web address.

 Version 6
  • Added questions 42 onwards
  • Updated reference for the 1.1 spec of JSP
  • Updated question 41 - watch out for 64k limitations in the Virtual Machine
  • Updated 23 with Cached row sets
  • Replaced answer to question 11 with more detailed answer
   
 Version 5
  • Updated the book group
  • Added questions 40 onwards
  • Updated web servers that support JSP 1.0
   
 Version 4
  • Updated GnuJSP (Free + Open Source)
  • Fixed getResourceDispatcher to getRequestDispatcher in (10)
  • Questions 37 onwards
  • Added 2nd example to (13)
   
 Version 3
  •  Questions 23 onwards
  • New JSP capable web server (Orion)
  • GNUJSP's site has changed
  • Clarified the Reference implementation in (3)
  • Added in a connection pool example (13)
  • Updated PolyJSP in (4)
   

Questions

  1. What is JSP?
  2. What version is the current version of JSP?
  3. Where can I get the specification for JSP?
  4. Who supports JSP?
  5. What books are available for JSP?
  6. Is JSP better than ASP (Microsoft's Active Server Pages)?
  7. What HTML editors support JSP?
  8. Yes, but how does it perform?
  9. How to invoke a JSP page directly from by browser?
  10. How do you invoke a JSP page from a servlet?
  11. How do you pass data (including beans) to a JSP from a servlet?
  12. How does JSP actually work?
  13. How can I pool connections to my database?
  14. How do I use other languages in my JSP?
  15. How can I set a cookie in JSP?
  16. Can JSP and Servlet share same Session and Beans?
  17. Help! JWS (Java Web Server) won't work with JSP 0.92!
  18. How do I use ERRORPAGE in JSP 0.92?
  19. How do I plug JSP into Microsoft's IIS Web Server?
  20. Are there any newsgroups that discuss JSP?
  21. What do the differing levels of bean storage (page, session, app) mean?
  22. Where can I find the mailing list archives?
  23. What are the important steps in using JDBC in JSP?
  24. How does variable scope work in JSP?
  25. How do I forward to an HTML page?
  26. Are there any white papers or documents explaining how JSP fits?
  27. How to I create dynamic GIFs for my JSP?
  28. Do you know where I could get some code that would encode something to the HTML DTD standard?
  29. What is page compilation?
  30. How are servlets and JSP pages related?
  31. Any good web sites for up to date activities in the Java/JSP/Servlet world?
  32. How do I force a user to log in?
  33. So how can a newbie get started with JSP?
  34. How can I ensure that session objects stay in existence when the web server restarts?
  35. How can I include one JSP inside another JSP?
  36. Is there some sort of event that happens when a session object gets bound or unbound to the session?
  37. Is there a way to execute a JSP from the comandline or from my own application?
  38. What should I use, Model 1 or Model 2?
  39. How do I delete a cookie with JSP?
  40. Help! JSP Reference implementation doesn't work!
  41. Are there tips on things to watch out for in JSP?
  42. How do you get started with JSP on the Macintosh?
  43. What Application Servers support JSP?
  44. What happened to the LOOP and DISPLAY tags from JSP 0.92?
  45. I cannot seem to import my classes in the 1.0 reference implementation!
  46. Does JSP have a bean providing File Upload features like ActiveX upload control?
  47. So how do I use EJB from JSP?
  48. Can I just abort processing a JSP?

Other topics + descriptions & additions gladly accepted. Looking for information on:

1) What is JSP? TOC

JSP is a dynamic scripting capability for web pages that allows Java as well as a few special tags to be embedded into a web file (HTML/XML, etc). The suffix traditionally ends with .jsp to indicate to the web server that the file is a JSP file. JSP is a server side technology - you can't do any client side validation with it.

JSP files actually get compiled into Servlets, so what is the point? Why not just write Servlets?

For most people, the benefit is twofold:

In the past, people have used servlets because of the problem of redirection - because by the time the JSP engine gets around to writing information back down the HTTP pipe, you could not do a redirect effectively in JSP - leading to the concepts of Model 1 vs Model 2 (see question 38). This has been fixed in JSP 1.0 with the addition of buffered output streams.

JavaSoft also has a FAQ, covering different questions, and it is located at http://java.sun.com/products/jsp/faq.html.

2) What version is the current version of JSP? TOC

The current version of JSP is 1.0. It is available from http://java.sun.com/products/jsp.

The public draft of JSP 1.1 is available from http://java.sun.com/products/jsp/techinfo.html.

The 0.92 spec is available from http://java.sun.com/products/jsp/jsp092.html

The 0.91 spec is a popular version though, and much software that supports the JSP pre-standard actually supports 0.91 of JSP.

The 0.91 spec is available from http://www.burridge.net/jsp/Spec91/jsp_spec.html

3) Where can I get the specification for JSP? TOC

You can get the current spec from http://java.sun.com/products/jsp. This is along with the reference implementation which works with its own web server.

4) Who supports JSP? TOC

There are the following implementations available:

 Name

Version of JSP Supported
Location

Cost

Comments
JSP Reference 1.0 PD** http://java.sun.com/products/jsp free  
GNU JSP 0.91 http://www.klomp.org/gnujsp/  free, open source   
 Java Web Server 2.0 1.0 http://java.sun.com/products/jws commercial JavaSoft's own Java Web Server. Being replaced with iPlanet (Alliance)
PolyJSP 0.92 http://www.plenix.org/polyjsp  free, open source  PolyJsp is based on XML/XSL and has been designed to be extensible. Now supports WebL  
Resin  1.0  http://www.caucho.com/ free for personal use  A 0.92 implementation for compiled JavaScript 
SJSP 1.1 http://web.iol.cz/sator/projects/sjsp-1-1/index.html free for personal use  Uses compile time introspection
zJSP 0.91 http://www.zachary.com/creemer/zjsp.html     
JRUN 0.92, 1.0PD http://www.livesoftware.com/  commercial  LiveSoftware are key players in the JSP standards process .
WebSphere  0.92 http://www.software.ibm.com/webservers/  commercial  IBM's WebSphere is part of a larger Application Server product.
Orion  0.92, 1.0PD http://orion.evermind.net/  commercial   Orion is a web server that implements JSP internally.
ServletExec 1.0 http://orion.evermind.net/ commercial  Supports large number of web servers
RocketJSP 1.0 http://rocketjsp.homepage.com/  GPL Java implementation
         

1.0PD = JSP 1.0 Public Draft

** - when I went to download it again after the full release announcement, it hadn't changed in size. This leads me to believe it still supports the public draft specification.

5) What books are available for JSP? TOC

There are now a number of books available on JSP from various publishers.

There is a group of people working on a Web book for JSP - information is located at http://www.esperanto.org.nz/jspbook. There is another at http://www.aptura.com/technology/jspBook_Architectures.html.

6) Is JSP better than ASP (Microsoft's Active Server Pages)? TOC

This is a matter of great debate. Many punters think that JavaSoft has the benefit of hindsight - what works well and what does't. ASP is very complex but supports multiple scripting languages and the ActiveX model of Microsoft. Although ASP _is_ available on many platforms, the ActiveX library support that makes it as powerful as it is is missing and thus makes ActiveX only feasible for an NT platform.

According to recent statistics (see the RedHat site), 22% of web servers are NT, (21% are Linux), that means there is 78% needing something else, and JSP advocates believe that JSP fits the bill nicely that you very much.

7) What HTML editors support JSP? TOC

Most of the visual developers do not support JSP in any way, shape or form, they mess up the tags totally. The following HTML editors have been known to work with JSP:

 Product

Location

Comments
 HomeSite http://www.allaire.com/  JSP colour coding will be in HS 4.0.1, but you can get a plug in now from http://www.burridge.net/jsp/homesite.html
 NetObjects ScriptBuilder 3.0 http://www.netobjects.com/products/html/nsb3.html  Win32 product supports JSP 0.91
Any text editor    
 DrumBeat 2000    For use with WebSphere and DB2

There is some rumour that DreamWeaver 2 is also able to support JSP - any confirmation?

8) Yes, but how does it perform? TOC

I have been picking up some comments:

Brian Burridge, brian_burridge@VALPAK.COM
"Our extranets for 300 franchises, 500+ users, our Intranet for thousands of employees, 
and eventually all of our other web sites. New Atlanta has been running for 6 weeks 
now without even one problem. Programming in JSP has turned out to be as easy as Perl, 
yet all our tests show it to be up to 10x faster."

9) How to invoke a JSP page directly from by browser? TOC

JSP files are just like HTML files, so if your index.jsp file is in your root directory of your web site, use http://localhost/index.jsp

10) How do you invoke a JSP page from a servlet? TOC

(Contributed by: Thomas-Bernhard.O-Hare@Dresdner-Bank.com)

After scanning through archives of the JSP mailing list to no effect I finally remembered that I'd pasted this example into a document I wrote. It was originally sent by Satish Dharmaraj of Sun to show the model 2 approach (as described in the 0.92 specification): how to pass data from a servlet
to a JSP.

Create a directory called model1/ under the samples/ directory. Place foo.jsp and Foo.java inside this directory.

Compile FooServlet.java and place FooServlet.class in TOP/servlets/directory.

Then invoke using http://host:8080/servlet/FooServlet

In this example, FooServlet creates a list and then stores the result in Foo.class. Foo.Class is then passed as a datasource to foo.jsp.

The sources are:

1) FooServlet.java

import java.io.*;
import javax.servlet.*;
import javax.servlet.http.*;
import model1.Foo;

public class FooServlet extends HttpServlet
{
public void service(HttpServletRequest req, HttpServletResponse res)
throws ServletException, IOException
{
 String s[] = new String[] {"blue", "green", "red"};
 Foo f = new Foo(s);
 req.setAttribute("foo", f);

 getServletContext().getRequestDispatcher("/samples/model1/foo.jsp").forward
 (req, res);
}
}

2) foo.jsp

<html>
<usebean name=foo type=model1.Foo lifespan=page>
</usebean>
<ul>
<loop property=foo:list propertyelement=x>
<li> <display property=x>
</loop>
</ul>
</html>

3) Foo.java

package model1;

public class Foo {
String s[];
public String[] getList() { return s; }
public Foo(String s[]) { this.s = s; }
}
(from "O¢¥Hare, Thomas Bernhard" <Thomas-Bernhard.O-Hare@Dresdner-Bank.com>)

11) How do you pass data (including beans) to a JSP from a servlet? TOC

There are actually three different ways to do it, depending on how long the reference should last, and which JSP pages (and servlets, for that matter) should be able to see it. In each of the cases, assume that "myBean" is a reference to the bean you want to send, and that "theBean" is the key I'm going to use to store the bean under (from the servlet perspective), and use as the identity of the bean in the JSP page.

These techniques are portable to any environment compliant with the servlet API 2.1 and JSP 1.0 specifications. In each case, the passing
works from servlet->JSP, servlet->servlet, JSP->JSP, or JSP->servlet transitions.

(1) Request Lifetime

Use this technique to pass beans that are relevant to this particular request to a bean you are calling through a request dispatcher (using either "include" or "forward"). This bean will disappear after processing this request has been completed.

SERVLET:
    request.setAttribute("theBean", myBean);
    RequestDispatcher rd =
        getServletContext().getRequestDispatcher('/thepage.jsp");
    rd.forward(request, response);
JSP PAGE:
    <jsp:useBean id="theBean" scope="request" class="....." />

(2) Session Lifetime

Use this technique to pass beans that are relevant to a particular session (such as in individual user login) over a number of requests. This bean will disappear when the session is invalidated or it times out, or when you remove it.

SERVLET:
    HttpSession session = request.getSession(true);
    session.putValue("theBean", myBean);
    /* You can do a request dispatcher here,
        or just let the bean be visible on the
        next request */
JSP PAGE:
    <jsp:useBean id="theBean" scope="session" class="..." />

(3) Application Lifetime

Use this technique to pass beans that are relevant to all servlets and JSP pages in a particular app, for all users. For example, I use this to make a JDBC connection pool object available to the various servlets and JSP pages in my apps. This bean will disappear when the servlet engine is shut down, or when you remove it.

SERVLET:
    getServletContext().setAttribute("theBean", myBean);
JSP PAGE:
    <jsp:useBean id="theBean" scope="application" class="..." />

Craig McClanahan

12) How does JSP actually work? TOC

It depends on your JSP server, but generally, JSP works by compiling your JSP file into a servlet, then executing that servlet. The JSP server checks for changes between the compiled servlet and the JSP page each time there is a request. See (30) for more info.

13) How can I pool connections to my database? TOC

Controlling connections to the database is a desirable thing - having to connect to the database for each page is is expensive, and keeping a connection in a session variable is far too expensive in terms of client connections to the database. Thus, people often create pools for connections to the database that the client comes in and gets and then returns when complete (making sure a try/catch is used to ensure the connection is returned!).

My personal bias indicates that you shouldn't pool connections to your database inside JSP, you should be using a middleware layer and communicating to it (like RMI or CORBA). However, people do write entire applications in JSP and beans that reside in the web server, so how do you do it?

From: Bradley Wood <Brad@MARKETING.CO.UK>

probably instantiate this as a singleton in the global.jsa and then call it.

for more on this and how its called check the downloadable code examples for this book at www.ora.com

import java.sql.*;
import java.util.*;

public class ConnectionPool {
private Hashtable connections;
private int increment;
private String dbURL, user, password;

public ConnectionPool(String dbURL,
String user,
String password,
String driverClassName,
int initialConnections,
int increment)
// int max?
throws SQLException, ClassNotFoundException {
  // Load the specified driver class
  Class.forName(driverClassName);
  this.dbURL = dbURL;
  this.user = user;
  this.password = password;
  this.increment = increment;
  connections = new Hashtable();

  // Put our pool of Connections in the Hashtable
  // The FALSE value indicates they're unused
  for(int i = 0; i < initialConnections; i++) {
  connections.put(DriverManager.getConnection(dbURL, user, password),
    Boolean.FALSE);
  }
}

public Connection getConnection() throws SQLException {
  Connection con = null;
  Enumeration cons = connections.keys();
  synchronized (connections) {
    while(cons.hasMoreElements()) {
      con = (Connection)cons.nextElement();
      Boolean b = (Boolean)connections.get(con);
      if (b == Boolean.FALSE) {
        // So we found an unused connection.
        // Test its integrity with a quick setAutoCommit(true) call.
        // For production use, more testing should be performed,
        // such as executing a simple query.
        try {
          con.setAutoCommit(true);
        }
        catch(SQLException e) {
          // Problem with the connection, replace it.
          con = DriverManager.getConnection(dbURL, user, password);
        }

        // Update the Hashtable to show this one's taken
        connections.put(con, Boolean.TRUE);
        // Return the connection
        return con;
     } // if
   } // while
 } // synchro

 // If we get here, there were no free connections.
 // We've got to make more.
 for(int i = 0; i < increment; i++) {
   connections.put(DriverManager.getConnection(dbURL, user, password),
     Boolean.FALSE);
 }

 // Recurse to get one of the new connections.
 return getConnection();
}

public void returnConnection(Connection returned) {
  Connection con;
  Enumeration cons = connections.keys();
  while (cons.hasMoreElements()) {
    con = (Connection)cons.nextElement();
    if (con == returned) {
      connections.put(con, Boolean.FALSE);
      break;
    }
  }
} // returnConnection

} // class

From: Andre Richards <AndreRic@mweb.co.za>

A very good example on connection pooling when using Servlets can be found at :

http://webdevelopersjournal.com/columns/connection_pool.html

I succesfully used it in JSP 0.91 as follows :

<script RUNAT="SERVER">
DBConnectionManager connMgr = DBConnectionManager.getInstance();
</script>

<%
Connection con = connMgr.getConnection("freetds"); 
if (con == null) { 
out.println("Can't get connection");
return;
}
try {
Statement stmt = con.createStatement();
ResultSet rs = stmt.executeQuery ("SELECT Hello FROM World");
while(rs.next()) {
out.println(rs.getString("Hello"));
}
stmt.close();
rs.close();}
catch (SQLException e) {
e.printStackTrace(out)
}
connMgr.freeConnection("freetds", con);
%>

14) How do I use other languages in my JSP? TOC

JSP is *Java* Server Pages, and the tags for other languages were taken out in 0.92. That said, two implementations (as of writing) support other languages:

- PolyJsp, 0.92, http://www.plenix.org/polyjsp, free + open source
- Resin. A JSP 0.92 implementation for compiled JavaScript, http://www.caucho.com/, free for personal use

15) How can I set a cookie in JSP? TOC

This should work:

response.setHeader("Set-Cookie", "cookie string");

To give the response-object to a bean, write a method setResponse
(HttpServletResponse response)
- to the bean, and in jsp-file:

<%
bean.setResponse (response);
%>

(from Aapo Kyrölä <aapo.kyrola@SATAMA.COM>)

16) Can JSP and Servlet share same Session and Beans? TOC

Example: I used Beans and Session with my servlet, JSP can use same Beans and Session or not?

From: Robert Hodges <hodges@TILDENPARK.COM>

This can be done, but you are likely to run into problems with class loaders. For instance, we have Apache/JServ which uses the AdaptiveClassLoader along with GNU-JSP which has a different class loader. If you just casually allocate objects in a servlet and then pick them up in JSP pages, you'll most likely get the dreaded ClassCastException, which signals the VM's pleasure when you try to cast a class that was brought in by a different class loader.

Note that there are sometimes problems even within JSP, as GNU-JSP drops the class loader every time you recompile a page, so if you allocated a class instance using one version of the page, then recompiled and tried to fish that instance back again, you would either (1) not find it or (2) get the ClassCastException (but see para #1 above).

If you really need to pass information around, the best way for Apache and GNU-JSP is to do the following:

  1. Have one server per person when developing.
  2. Make sure that all your Java classes, including servlet code, load through the system class path. This means they load through the primordial loader, which does not go away or change.
  3. Make sure that your compiled JSP pages go to another location than your regular Java classes. That way, the JSP loader will just pick them up through the primordial loader.

In this scheme, you will need to reboot the Web server each time you make a change to the regular Java classes or else great confusion will ensue. (And possibly outrage among your users, I might add.)

If you need to share a Web Server between multiple people, or cannot reboot whenever you make class changes, the solution is much more complex. I can post a treatise on one approach at a later time (big project, deadline Friday) if there is interest.

17) Help! JWS won't work with JSP 0.92! TOC

JSP spec 0.92 wont work with JWS 1.x. There is a version mismatch in the Servet API releases and JWS (till 1.1.2) does not support JSP.

Try an implementation of JSP 0.91 with JWS.

(From: Anand Kumar S <anandsan@WIPSYS.SOFT.NET>)

Note, JWS 2.0 is now in beta and can be downloaded from Sun's site. It supports JSP 1.0PD.

18) How do I use ERRORPAGE in JSP 0.92? TOC

(Contributed by: Thomas-Bernhard.O-Hare@Dresdner-Bank.com)

Using ERRORPAGE in JSP 0.92

I'm not sure if I'm using the correct approach here but in the application I'm developing each JSP page includes the line

<%@ ERRORPAGE="01_error.jsp" %>

and the 01_error.jsp page reads:

<HTML>
<USEBEAN name = "AISRB" type = "prj.servlet_utils.PresentError" lifespan =
page>
</USEBEAN>
<HEAD>
<TITLE><DISPLAY PROPERTY=AISRB:Error PLACEHOLDER="--Error Title--"></TITLE>
</HEAD>
<BODY>
<BLOCKQUOTE>
<TABLE BORDER="0">
<TR>
<TD><img src="icon/oops.gif"></TD>
<TD><FONT SIZE="5">
<DISPLAY PROPERTY=AISRB:Error PLACEHOLDER="--Error Title--">
</FONT></CENTER></TD>
</TR>
</TABLE>
<P>
<BR>
<DISPLAY PROPERTY=AISRB:Error_Line PLACEHOLDER="--Error Line--">
<BR>
<%= exception.getMessage() %> 
<!DISPLAY PROPERTY=exception:message PLACEHOLDER="--Error Message--"> 
<BR>
<P>
<HR size ="1">
<FONT SIZE="1">Footer</FONT>
<BR>
</BLOCKQUOTE>
</BODY>
</HTML>

The bean is always present in the current request (placed there by preceding servlet); I'm actually using this approach for internationalization - the bean contains strings callled Error_line etc to say "An error has occurred" in the appropriate language. Of course, it doesn't actually contain any information on the error - this is supposed to be supplied by the exception bean.

Speaking of which, I wanted to use the line

<DISPLAY PROPERTY=exception:message PLACEHOLDER="--Error Message--">

to display the exception but that didn't seem to work so now I'm using

<%= exception.getMessage() %>

instead because it does seem to work.

I rather suspect ths is not the best aprroach to reporting unexpected errors so you may not want to put it in the FAQ. If you have something better I'd
be pleased to hear about it.

19) How do I plug JSP into Microsoft's IIS Web Server? TOC

IBM's WebSphere, LiveSoftware's JRun and New Atlanta's ServletExec all provide plug ins for IIS 4.0.

20) Are there any newsgroups that discuss JSP? TOC

Live Software has a new newsgroup for JSP discussion at news://news.livesoftware.com/livesoftware.jsp

21) What do the differing levels of bean storage (page, session, app) mean? TOC

From: Joe Shevland <J_Shevland@TurnAround.com.au>

The spec is not clear on what the Application level scope actually means, but the general discussion has it that an Application is a single JSP whose beans persist from call to call - unlike those beans which have the "page" scope. That said, the 0.92 spec still stores "application" beans at the servlet level so they can actually be used by multiple servlets.

(From Gabriel Wong <gabrielw@EZWEBTOOLS.COM>)
In purely Servlet terms, they mean:

22) Where can I find the mailing list archives? TOC

Archives of the JSP mailing list are available at http://archives.java.sun.com/archives/jsp-interest.html

These archives are searchable.

23) What are the important steps in using JDBC in JSP? TOC

1) Instantiate an instance of the JDBC driver you're trying to use (jdbc-odbc bridge name from memory so pls check):

Class.forName( "sun.jdbc.odbc.JdbcOdbcDriver" ).newInstance();

This determines if the class is available and instantiates a new instance of it, making it available for the next step.

2) Ask the DriverManager for a Connection object based on the JDBC URL you are using:

Connection connDB = DriverManager.getConnection( "jdbc:odbc:MyDSN",
"username", "password" );

DriverManager searches through any registered drivers (instantiating a new instance above is enough to register a driver with the DriverManager, as each implementation is required to) and, based on the JDBC URL you are using, returns the appropriate implementation of Connection.

3) Create a Statement object to retrieve a ResultSet

Statement smentDB = connDB.createStatement();
ResultSet rsDB = connDB.executeQuery( "SELECT * FROM Foo" );
or
rsDB = connDB.executeUpdate( "UPDATE Foo SET Bar = NULL" );

4) Close down connections to free resources:

rsDB.close();
smentDB.close();
connDB.close();

Note smentDB.close() closes the rsDB object, and connDB will close smentDB, cascading down, so you can really just: connDB.Close(). Also note there's no exception handling given here.

With the release of the JDBC 2.0 API, there is a CachedResultSet capability which would provide some assistance in making your pages perform better:

From: DIGNE Marc <jmdigne@MEUDON.NETCABLE.TM.FR>

I tested the JDBC CachedRowSet http://developer.java.sun.com/developer/earlyAccess/crs/index.html

"JDBCTM CachedRowSet is an implementation of the Rowset interface. The Rowset interface is part of the JDBC 2.0 Standard Extension API.

CachedRowSet provides a disconnected, serializable, scrollable container for tabular data. A CachedRowSet object can be thought of as a disconnected set of rows that are being cached outside of a data source.

Data contained in a CachedRowSet may be updated and then resynchronized with the underlying tabular data source. "

24) How does variable scope work in JSP? TOC

From: Alexander Yavorskiy <Alexander_Yavorskiy@VANTIVE.COM>

Hi,
An interesting observation about the variables declared in JSP pages.

Any variable declared inside <% .... %> is local to the page and is not visible to outside functions, even those declare on the same JSP.

Example:

<%
int evilVariable = "666";
%>
...
function testFunction() {
// do not see evilVariable from here
}

Why? evilVariable eventually becomes a local variable in the service() method of the resulting servlet and so is not accessible by other methods of that servlet.

Any variable declared inside <%! %> become global for any function declared in the servlet.

Example:
<%!
int evilVariable = "666";
%>
...
function testFunction() {
int x = evilVariable; //can get to it
}

Why? evilVariable declared this way becomes a private member variable of the resulting servlet and so is accessible by all other methods of that servlet.

Conclusion

It is important to understand this difference because in servlet environment there will only be a single(!!!) instance of the resulting servlet running and serving all requests for a particular page. Thus, potentially all of the member variables of that servlet will be share across the requests as opposed to variables local to the service() method that will be recreated for each request. So, we should be careful about putting none constant variables in <SERVER></SERVER>. At the same time, it might be useful to do so in some situations.

25) How do I forward to an HTML page? TOC

The method forward() in the Servlet API works for JSP pages, but this is only true for resources with _active_ content, like JSP pages.

If you wish to forward to an HTML page, you have to use a different method:

From: Volker Stiehl <stiehl@ZNNBG.SIEMENS.DE>

In order to access HTML files you have to use the new "resource abstraction" feature of 2.1.
Try the following:

URL url = getServletContext().getResource("/abc/xyz.html");
out.println(url.getContent());

26) Are there any white papers or documents explaining how JSP fits? TOC

From: "Craig R. McClanahan" <cmcclanahan@mytownnet.com>

http://www.software.ibm.com/ebusiness/pm.html

It is titled "The Web Application Programming Model", and provides a nice overview of the basic architecture IBM proposes for web applications (essentially the "Model 2" approach from the JSP specification). There are few IBM-specific product references in this document -- simply translate their term "dynamic server pages" into JSP, and generalize "WebSphere" to any useful combination of web server, servlet engine, and app server components. There are more IBM-specific references in several of the other white papers, but they still provide a useful overview of the technology basis for large scale web-based application development and deployment. The white paper index is at:

http://www.software.ibm.com/ebusiness/library.html

27) How to I create dynamic GIFs for my JSP? TOC

From: Matti Kotsalainen <matti@RAZORFISH.COM>

If you want to create GIFs, use ACME labs excellent free gifencoder(http://www.acme.com/), and then do something like this:

Frame frame = null;
Graphics g = null;
FileOutputStream fileOut = null;
try {
//create an unshown frame
frame = new Frame();
frame.addNotify();
//get a graphics region, using the frame
Image image = frame.createImage(WIDTH, HEIGHT);
g = image.getGraphics();
//manipulate the image
g.drawString("Hello world", 0, 0);
//get an ouputstream to a file
fileOut = new FileOutputStream("test.gif");
GifEncoder encoder = new GifEncoder(image, fileOut);
encoder.encode();
} catch (Exception e) {
;
} finally {
//clean up
if (g != null) g.dispose();
if (frame != null) frame.removeNotify();
if (fileOut != null) {
try { fileOut.close(); }
catch (IOException ioe) { ; }
}
}

28) Do you know where I could get some code that would encode something to the HTML DTD standard? TOC

As a matter of fact...

(NB: This is an implementation of the HTMLEncode function that ASP has)

From: Eric Lunt <elunt@YAHOO.COM>

Somewhere in my net-travels I picked up this version which performs pretty well:

/**
* Returns an HTML rendition of the given <code>String</code>. This was
* written by <a href=mailto:kimbo@biddersedge.com>Kimbo Mundy</a>.
* @param text A <code>String</code> to be used in an HTML page.
* @return A <code>String</code> that quotes any HTML markup
* characters. If no quoting is needed, this will be
* the same as <code>text</code>.
*/
public static String asHTML(String text) {
if (text == null)
return "";
StringBuffer results = null;
char[] orig = null;
int beg = 0, len = text.length();
for (int i = 0; i < len; ++i){
char c = text.charAt(i);
switch (c){
case 0:
case '&':
case '<':
case '>':
case '"':
if (results == null){
orig = text.toCharArray();
results = new StringBuffer(len+10);
}
if (i > beg)
results.append(orig, beg, i-beg);
beg = i + 1;
switch (c){
default: // case 0:
continue;
case '&':
results.append("&amp;");
break;
case '<':
results.append("&lt;");
break;
case '>':
results.append("&gt;");
break;
case '"':
results.append("&quot;");
break;
}
break;
}
}
if (results == null)
return text;
results.append(orig, beg, len-beg);
return results.toString();
}

29) What is page compilation? TOC

See (30)

30) How are servlets and JSP pages related? TOC

JSP pages are focused around HTML (or XML) with Java codes and JSP tags inside them. When a web server that has JSP support is asked for a JSP page, it checks to see if it has already compiled the page into a servlet. Thus, JSP pages become servlets and are transformed into pure Java and then compiled, loaded into the server and executed. Different JSP implementations do this in more or less efficient ways.

31) Any good web sites for up to date activities in the Java/JSP/Servlet world? TOC

The following web sites contain information about JSP:

An IBM Tutorial on JSP: http://www.software.ibm.com/developer/education/java/online-courses.html
An IBM Red Book : http://www.redbooks.ibm.com/SG245423/sg245423.pdf
Other IBM Information: http://www.software.ibm.com/webservers/appserv/doc/v20dcadv/doc/index.html

The following web sites focus on JSP solutions

Servlets Taverne - http://www.interpasnet.com/JSS/
Oi Servlet World - http://i.am/servletforme
Web Development with JSP - http://www.burridge.net/jsp/

32) How do I force a user to log in? TOC

From: Andre Richards <AndreRic@MWEB.CO.ZA>

I did as follows:


On every page which must be authenticated, I check for a user ID in the session object - if it doesn't exit, I do a redirect to a login page, passing the url the user was trying to access as a parameter.

On the login page, if the user successfully logs in, I create a session for him/her, and add the user ID to the session. I then redirect back to the original page the user tried to access. This way, even if the user bookmarks a page, he/she will be asked to login once the session has become invalid.

Some code:
On every page I add the following:

HttpSession session = request.getSession(true);
if (session.getValue("CustomerID") == null) {
response.sendRedirect (response.encodeRedirectUrl
("Login.jsp?Origin=SharePortfolio.jsp"));
}
else {
// the rest of the page ...

In Login.jsp once the user has provided the correct logon credentials:

session.putValue("CustomerID", CustomerID);
response.sendRedirect(response.encodeRedirectUrl(request.getParameter("Origin")));


Another developer has a different approach:

From: Christopher Cobb <ccobb@usgs.gov>

After researching several approaches, I have finally settled on the following approach. I would like to hear how others
are solving this problem. (FAQ maintainers note: This syntax won't work with JSP 1.0)

1. User accesses GuardedPage.jsp via

    http://localhost/path/to/GuardedPage.jsp

2. GuardedPage.jsp includes a login checking page:

<!--#include file="/admin/" file="LoginChecker.jsp" -->

Every page that needs to be login-protected should include this file (which, depending on how your site is set up, may be
every page.)

3. LoginChecker.jsp accesses a bean that does the login checking:

<USEBEAN lifespan="session" name ="loginChecker" type="package.LoginChecker">
<setfromrequest beanproperty = "*">
</USEBEAN>

4. The LoginChecker bean has a property 'loggedIn'. (It also has properies for Username and Password, and a
processRequest() method, which are used later).

LoginChecker.jsp checks the value of the loggedIn property. If it is not true (i.e., the user is not logged in), a login
page is displayed:

<excludeif property ="loginChecker:loggedIn" value = "true">

<FORM action="/servlet/DBAccess/path/to/GuardedPage.jsp" method="post">
Username: <input name="userName" size="15" maxlength="15" >
Password: <input type="password" name="password" size="15" maxlength="15">
<input type="submit" name="loginUser" value="Submit">
</FORM>

</excludeif>

The first time through, this bean will be 'empty' and the loggedIn property will not be set. The login form will therefore
be displayed.

5. There is a little trick in the action clause above. When the user types in his login info and presses submit, the
invoked URL is

    /servlet/DBAccess/path/to/GuardedPage.jsp

The action passes through the servlet DBAccess, then continues on to our original page. This servlet does nothing more
than attach an open database connection to the current session:

    session.putValue("open.connection", connection);

The servlet then picks up the trailing part of the URL with:

    String trailingURL = request.getPathInfo();

It then calls forward() to pass control back to the requested page. In this example, the new page happens to be the same
as the page we came from.

    getServletConfig(
          ).getServletContext(
          ).getRequestDispatcher(response.encodeURL(trailingURL)
          ).forward(request,response);

6. Now we are back to our original page and the logginChecker bean gets invoked again. Because of the:

    <setfromrequest beanproperty = "*">

in the loginChecker USEBEAN tag, and because our username and password field names in the LoginChecker.jsp page match our
bean's property names, the username and password that the user typed in get 'magically' populated in the corresponding
properties of the bean.

7. The LoginChecker bean has a processRequest() method which checks to see if a username and password has been supplied.
If so (and if we are not logged in), it performs a database lookup to log the user in. If the lookup is successful, the
loggedIn property is set to true.

8. We are finally back to our GuardedPage.jsp page. It will probably not want to display itself unless the user is logged
in. The page should therefore only be included if loggedIn is true:

<includeif property="loginChecker:loggedIn" value="true" >

The contents of GuardePage.jsp are displayed only if loggedIn is true.

</includeif>

We're done! GuardedPage.jsp is only displayed if the user is logged in. If the user is not logged in, a login page is
displayed, which if successful, returns the user to the original page.

9. There is one small cleanup which is needed in Step 4. As coded above, a passthrough servlet is used to attach a
database connection to the session. If the user repeatedly fails to login, the servlet prefix will get repeatedly
pre-pended to the URL. Furthermore, the 'current page' is hardcoded into the LoginChecker.jsp page which restricts it's
reusability. A little JavaScript fixes both of these problems. The following JavaScript should be used in place of the
<FORM> tag in Step 4. above.

    <script language="JavaScript">
    <!--
    if (document.location.pathname.indexOf("/servlet/package.DBAccess") == 0)
        document.write(
                '<FORM action="' +
                    document.location.pathname +
                    '"method="post">');
    else
        document.write(
                '<FORM action="/servlet/package.DBAccess' +
                   document.location.pathname +
                   '" method="post">');
    //-->
    </script>

 

33) So how can a newbie get started with JSP?

See the QuickStart section of the JSP Book at http://www.esperanto.org.nz/jspbook

34) How can I ensure that session objects stay in existence when the web server restarts? TOC

There is no requirement that a session object will stay around as far as I can tell, but some web servers will serialize objects if they support the serialization interface.

35) How can I include one JSP inside another JSP? TOC

JRUN, ServletExec and GNUJSP allow you to specify (it was in the 0.91 spec):

<%@ include="./header.jsp" %> - where header.jsp is the file you want to include.

The spec does say that it supports NCSA style includes as in

<!--#include virtual="/pathfromdocdir/" file="copyright.html" -->
<!--#include file="data/table.html" -->

But there is no requirement that they support JSP.

36) Is there some sort of event that happens when a session object gets bound or unbound to the session? TOC

From: "Kirkdorffer, Daniel" <daniel.kirkdorffer@ATTWS.COM>

HttpSessionBindingListener will hear the events When an object is added and/or remove from the session object, or when the session is invalidated, in which case the objects are first removed from the session, whether the session is invalidated manually or automatically (timeout).

37) Is there a way to execute a JSP from the comandline or from my own application? TOC

There is a little tool called JSPExecutor that allows you to do just that. The developers (Hendrik Schreiber <hs@webapp.de> & Peter Rossbach <pr@webapp.de>) aim was not to write a full blown servlet engine, but to provide means to use JSP for generating source code or reports. Therefore most HTTP-specific features (headers, sessions, etc) are not implemented, i.e. no reponseline or header is generated. Nevertheless you can use it to precompile JSP for your website. JSPExecutor is GPLed and available at no charge at:

http://www.webapp.de/jspexecutor.html

38) What should I use, Model 1 or Model 2? TOC

Whichever one works for you. Model 2 can give you more control, especially if you are doing things such as filtering the actual web pages a client receives because of language. Model 1 is generally more simple. A more full description of Model 1 vs Model 2 is at http://www.aptura.com/technology/jspBook_Architectures.html.

39) How do I delete a cookie with JSP? TOC

From: Chris Fesler <cfesler@InstantObjects.com>

A little more experimentation, and I came up with a method to delete cookies. Say that I have a cookie called "foo," that I set a while ago & I
want it to go away. I simply:

<%
Cookie killCookie = new Cookie("foo", null);
killCookie.setPath("/");
killCookie.setMaxAge(0);
response.addCookie(killCookie);
%>

Note that this is -not- how the JSDK documentation indicates cookies are to be deleted, but what the heck -- it seems to work.

 

40) Help! JSP Reference implementation doesn't work! TOC

There is a problem with the startserver.bat file that comes with the Reference implementation when it goes to try and compile JSPs. The problem is that the tools.jar file is missing from the classpath. The symptom occurs as a page like:

Unhandled error! You might want to consider having an error page to report
such errors more gracefully

java.lang.NoClassDefFoundError: sun/tools/javac/Main
        at com.sun.jsp.compiler.Main.compile(Main.java:194)
        at com.sun.jsp.runtime.JspLoader.loadJSP(JspLoader.java:114)
        at
com.sun.jsp.runtime.JspServlet$JspServletWrapper.loadIfNecessary(JspServlet.
java:69)
        at
com.sun.jsp.runtime.JspServlet$JspServletWrapper.service(JspServlet.java:77)
        at
com.sun.jsp.runtime.JspServlet.serviceJspFile(JspServlet.java:125)
        at com.sun.jsp.runtime.JspServlet.service(JspServlet.java:152)
        at javax.servlet.http.HttpServlet.service(HttpServlet.java:840)

To fix it, you need to add the tools.jar file from your JDK 1.2 LIB directory to the classpath that is in the startserver.bat file (or just add it to your environment variables). An alternative (from John Zukowski) is to put the tools.jar file into your jre\lib\ext directory.

41) Are there tips on things to watch out for in JSP? TOC

There are a number of things to beware of I'm sure, I have found one in particular so far:

The Virtual Machine has some intrinsic limitations as well (contributed by Costin Manolache), and these affect your JSP. From Virtual Machine Spec:

Other tips appreciated! Email me at rvowles@esperanto.org.nz

42) How do I get started with JSP on the Macintosh? TOC

From: Niels Peter Strandberg <nps@HEM1.PASSAGEN.SE>

This mail is for all Mac users that want to get started with Java Server Pages on the Mac.

This list is base on the mails I got from Mike Engelhart <mengelhart@earthtrip.com>. Who helped me to get my server started. Thanks Mike!

Java Server Pages is the Java worlds answer to Active Server Pages on NT. Sun has made a free version witch includes a WebServer and an JSP
engine. The package is made in 100% pure Java. So it runs on every Java platform, and it is free.

Before you can cook you own Java Server Pages, You need to build the "JSP machine". And here is how to do it.

  1. You need the latest MRJ from Apple. MRJ2.1 can be found here: http://www.apple.com/java/. After download run the installer and install
    the MRJ.
  2. You also need the latest MRJ SDK 2.1 (Im using 2.0 and that works great), that can be found here: http://developer.apple.com/java/text/download.html#sdk. After download run the installer and install the MRJ SDK.
  3. You also need the "JavaServer WDK EA (JavaServer Web Development Kit 1.0 EA)" from Sun. This can be found here: http://developer.java.sun.com/developer/earlyAccess/jsp/. I downloaded the Win version, but there should be no problem if you download the
    Solaris version. After you have downloaded the Zip, unzip it using ZipIt or StuffIt. You have to be a registered member of developer connection
    to get access to the files, but that it's free. So go ahead an register yourself.
  4. After you have unziped the zip file, place the unziped folder "jswdk-1.0-ea" on the desktop. Now locate the "MRJ SDK 2.1" folder and
    open it. Inside that folder is another folder named "JBindery" and inside that folder an app with the same name.
  5. Now launche the app "jBindery". Click on the"Command" icon and add this to the Class name field: "com.sun.web.shell.Startup". Leave the
    optional parameters blank.
  6. Click on the "Classpath" icon. Click on the "add .zip file..." button and add the following files: "webserver.jar" which is in the root of your "jswdk-1.0-ea" folder. Also add the following files which are in the "lib" folder: "jsp.jar" and "jspengine.jar" and "servlet.jar"
  7. Click on the "add folder..." button and ad the following folder "beans" locate in examples/WEB-INF/jsp/
  8. Now you are ready to save these setting as an click able application. Click on the "Save Settings..." button, and give your "app" a name (ex.
    JSP Server) and make sure the check box "save as App" is checked. Make sure that you save the app in the root of the "jswdk-1.0-ea" folder.
  9. Now you have embedded these setting in an application file. Now locate your "JSP Server" application and double click on it. Wait a few seconds, and your server should be up an running. The app will quit if it cant find a IP number. Go into your TCP/IP control panel and assign a permanent IP number (ex. 127.0.0.1). Then try to run the app again.
  10. The JPS Server will run at port 8080 by default. You can change that by opening the "default.cfg" file in a text editor and change the "server.port" from 8080 to 80, witch is the default port for WebServers.
  11. Now here is where the fun begins. Open your web browser and type in the IP number you assigned to you mac in the TCP/IP control panel. (http://127.0.0.1) or (http://127.0.0.1:8080) if you didn't change the port setting in the "default.cfg" file.
  12. Now, explore the example and when your are ready, cook your own JSP.

43) What Application Servers support JSP? TOC

Originally contributed by Daniel Kirkdorffer, daniel.kirkdorffer@attws.com. See also http://www.interpasnet.com/JSS/textes/jsp2.htm or http://www.flashline.com/components/appservermatrix.jsp

44) What happened to the LOOP and DISPLAY tags from JSP 0.92? TOC

They were left out in JSP 1.0 onwards. There was no explanation given. They may be able to be expressed as tag extensions but I have not investigated the 1.1 API yet to determine how that could be done.

45) I cannot seem to import my classes in the 1.0 reference implementation! TOC

The reference implementation for 1.0 got the name of the import tag wrong. They put "import" in the specification and "imports" into the reference implementation. Thus, when you would have expected to use

<%@ page import="myclasses.*" %>

you need to use

<%@ page imports="myclasses.*" %>

instead.


46) Does JSP have a bean providing File Upload features like ActiveX upload control? TOC

Get a look at the MultipartRequest object from the author of "Java Servlet Programming" (O'Reilly). Home page is http://www.servlets.com/index.html. The zip file for this class and other useful classes is at http://www.servlets.com/resources/com.oreilly.servlet/cos.zip.

48) Can I just abort processing a JSP? TOC

Yes. Because your JSP is just a servlet method, you can just put (whereever necessary) a

<% return; %>