Maintainer: Richard Vowles, rvowles@esperanto.org.nz (http://www.esperanto.org.nz)
| 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:
- The focus is on HTML. Java and the JSP extensions assist in making the HTML more
functional. Servlets on the other hand allow outputting of HTML but it is a tedious
process.- It is easy to make a change and then let the JSP capability of the Web Server you are
using deal with compiling it into a Servlet and running it.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.1. It is available from http://java.sun.com/products/jsp.
The JSP 1.1 is available from http://java.sun.com/products/jsp/techinfo.html.
The 0.92 spec is available from http://www.brainopolis.com/jsp/jspSpec092.zip
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
Cost
Comments JSP Reference 1.1 free TOMCAT - Now included as part of the J2EE Reference Implementation, but also managed by the Jakarta Project as part of Apache. This implementation has a way to go before being ready for production. GNU JSP 1.0 free, open source, located in CVS at the Giant Java Tree Sun's Java Web Server 2.0 1.0 commercial Sun's own Java Web Server. Being replaced with iPlanet (Alliance) PolyJSP 0.92 free, open source PolyJsp is based on XML/XSL and has been designed to be extensible. Now supports WebL Hasn't been updated for a while. Resin 1.0, 1.1 in beta Unknown Now Open Source. SJSP 1.1 free for personal use Uses compile time introspection, allows you to replace your existing JSP engine in your web server. zJSP 0.91 Last updated, Sept 3, 1998 JRUN 0.92, 1.0 commercial JSP 1.1 support now in beta. Orion 1.1 commercial Orion is a web application server that implements JSP internally. It also has a lot of JSP vs other JSP and vs ASP stats on its pages. Also supports Servlet 2.2 ServletExec 1.1 commercial Supports large number of web servers RocketJSP 1.0 GPL Located in the Giant Java Tree
| 5) What books are available for JSP? | TOC |
There are now a number of books available on JSP from various publishers.
A quick search of Amazon comes up with
- Professional Java Server Programming: with Servlets, JavaServer Pages (JSP), XML, Enterprise JavaBeans (EJB), JNDI, CORBA, Jini and Javaspaces
- Professional Java XML Programming with servlets and JSP
- Pure JSP Java Server Pages
- Web Development with JavaServer Pages
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 and yet another at Brainopolis.
| 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 JRun Studio http://beta.allaire.com/registration/index.cfm?betaprogram=jrunstudio
JRun Studio, currently in Beta, An integrated JSP visual development tool based on Homesite, an award winning HTML editor. JRun Studio supports JSP 1.1 tags, JSP wizzards, support for custom tag libraries including the JRun tag library, and offers page compilation, debugging and remote deployment features.NetObjects ScriptBuilder 3.0 http://www.netobjects.com/products/html/nsb3.html
Win32 product supports JSPAny text editor Borland JBuilder 3.5 http://www.borland.com/jbuilder Java Development tool, supports JSP internally, and allows running and debugging of JSPs DreamWeaver 3 http://www.dreamweaver.com Ignores JSP tags, and allows you to edit JSP files as if they are HTML files given you customise the product slightly (you need to edit a special file) FrontPage 2000 http://www.microsoft.com/frontpage Some reports that Front Page now ignores JSP tags.
| 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."Also available are a set of benchmarks from the people who make the Orion server, located at http://orion.evermind.net/, and also from the people who do Resin (comparing their JSP implementation with Orion)
| 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 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 } // classFrom: 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); %>
| 13) 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, three 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
- Allaire's JRun 3.0 has support for JSP pages using either Java or JavaScript as the server-side scripting language, so you needent learn java to deploy JSP applications. JavaScript is considered to be easier to learn then Java because it's typeless, dynamic language features. JavaScript can flatten the JSP learning curve, empowering a larger group of developers, shortening time-to-market.
| 14) 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>)
| 15) 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:
- Have one server per person when developing.
- 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.
- 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.
| 16) 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.
Tomcat, the "reference" implementation of JSP 1.1 from the Jakarta Project also has an ISAPI plug-in. Tomcat does not (as of 3.1) support multi-homing.
Resin also provides support for multi-homing (very well at that!)
| 17) Are there any newsgroups that discuss JSP? | TOC |
Live Software has a new newsgroup for JSP discussion at news://news.livesoftware.com/livesoftware.jsp
| 18) 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:
- page - NO storage
- session - servletrequest.getSession(true).putValue("myobjectname",myobject);
- application - getServletConfig().getServletContext().setAttribute("myobjectname",myobject);
- request - The storage exists for the lifetime of the request, which may be forwarded between jsp's and servlets.
| 19) 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.
| 20) 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. "
| 21) 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.
| 22) 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());
| 23) 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:
| 24) 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) { ; } } }
| 25) 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("&"); break; case '<': results.append("<"); break; case '>': results.append(">"); break; case '"': results.append("""); break; } break; } } if (results == null) return text; results.append(orig, beg, len-beg); return results.toString(); }
| 26) What is page compilation? | TOC |
See (30)
| 27) 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.
| 28) 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/abstracts/sg245423.html
- Other IBM Information: http://www.software.ibm.com/webservers/appserv/doc/v20dcadv/doc/index.html
- JSP-Resource Information - http://www.jspin.com is quite comprehensive on sites and articles.
- JSP Tags is a site for Taglibs - http://jsptags.com
- Another JSP tags site (for a book) is www.taglibs.com
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/
| 29) 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.jsp2. 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.jspThe 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>
| 30) So how can a newbie get started with JSP? | TOC |
See the QuickStart section of the JSP Book at http://www.esperanto.org.nz/jspbook
| 31) 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.
| 32) 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.
| 33) 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).
| 34) 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:
| 35) 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.brainopolis.com/jsp/book/jspBook_Architectures.html.
| 36) 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.
| 37) 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:
- From John Langley (langley@NEOTEK.MV.COM), don't have directories in your path that are not valid Java identifiers (for example, they start with a number, or are a number). A number of JSP implementations use the directory your JSP is in as part of the package name and if that is in a directory with an invalid identifier then you are out of luck.
- Beware of server side includes not recompiling when you have changed them. Some JSP engines won't check into your JSP or create dependency lists to ensure that the entire content of your JSP will be recompiled if a dependency has changed.
- Many servlet engines don't notice that you change your beans, so that if you change your JSP and change a bean that it uses, although the JSP will reload, the bean will not. This will require you to restart your server.
The Virtual Machine has some intrinsic limitations as well (contributed by Costin Manolache), and these affect your JSP. From Virtual Machine Spec:
- 64k entries in constant pool ( that means the count of strings you can use in out.println(), plus all other constants < 64k )
- 64k as the size of a method ( that mean the service() method can't have unlimited number of instructions )
- constant string limit is 64k (bytes - not characters!) That may explain the 32K ( since Unicode chars are ~ 2 bytes - sometimes).
( it's not the limit of a String - just constant String ).Other tips appreciated! Email me at rvowles@esperanto.org.nz
| 38) How do you 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.
- 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.- 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.
- 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.- 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.- 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.- 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"
- Click on the "add folder..." button and ad the following folder "beans" locate in examples/WEB-INF/jsp/
- 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.- 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.
- The JSP 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.
- 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.
- Now, explore the example and when your are ready, cook your own JSP.
| 39) 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
| 40) 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.
| 41) 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.
| 42) So how do I use EJB from JSP? | TOC |
| 43) 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; %>
| 44) "I'm trying to pass an object between a servlet and a JSP page, but my object is null on the JSP page. What could be wrong?" | TOC |
From: Timothy Owen ReillyHttpSession objects are limited in scope to a particular servlet zone. In my case, I saw this behaviour because my servlet was in one servlet zone, and my jsp engine (GnuJSP) was in another. Try printing out the session id in both your servlet and your JSP page [use: HttpSession.getId() ], if it's different in both, then obviously each side of the equation is using a different session framework, and you could have the same problem as I did.
Running both my servlets and GnuJSP in the same servlet zone solved this problem.
Note: The observed behaviour and solution were under Apache JServ 1.1 and GnuJSP 1.0