JSP
JSPs are converted to servlets before the container runs them. This is a nice trick by Sun because non-programmers can create JSP pages. Although JSP reduces the required skill level, JSP becomes a servlet, with the nice performance and portability benefits. Let's walk through the JSP-to-servlet process.
Listing 3.3 is a trivial JSP file:
Listing 3.3 A Trivial JSP File
<!-- Simple demonstration of how Tomcat converts JSP to a servlet. --> <html> <body> Devyn likes <b>R/C Buggies</b>. </body> </html>
This JSP file was placed in the ...\jakarta-tomcat-4.0.1\webapps\examples\jsp directory. I requested the file with this: http://localhost:8080/examples/jsp/jsp_servlet.jsp. Tomcat converted the JSP code into a servlet source file, compiled it, and then invoked it. The servlet source file is located in ...\jakarta-tomcat-4.0.1\work\localhost\examples\jsp as jsp_0005fservlet$jsp.java. The source is shown in Listing 3.4, the translation of a trivial JSP file (see Listing 3.3):
Listing 3.4 Translation of JSP File into a Servlet
package org.apache.jsp; import javax.servlet.*; import javax.servlet.http.*; import javax.servlet.jsp.*; import org.apache.jasper.runtime.*; public class jsp_0005fservlet$jsp extends HttpJspBase { static { } public jsp_0005fservlet$jsp( ) { } private static boolean _jspx_inited = false; public final void _jspx_init() throws org.apache.jasper.runtime.JspException { } public void _jspService(HttpServletRequest request, HttpServletResponse response) throws java.io.IOException, ServletException { JspFactory _jspxFactory = null; PageContext pageContext = null; HttpSession session = null; ServletContext application = null; ServletConfig config = null; JspWriter out = null; Object page = this; String _value = null; try { if (_jspx_inited == false) { synchronized (this) { if (_jspx_inited == false) { _jspx_init(); _jspx_inited = true; } } } _jspxFactory = JspFactory.getDefaultFactory(); response.setContentType("text/html;charset=" + "ISO-8859-1"); pageContext = _jspxFactory.getPageContext(this, request, response, "", true, 8192, true); application = pageContext.getServletContext(); config = pageContext.getServletConfig(); session = pageContext.getSession(); out = pageContext.getOut(); // HTML // begin [file="/jsp/jsp_servlet.jsp"] out.write("<!--\r\n Simple demonstration"+ " of how Tomcat converts\r\n JSP to a "+ "servlet.\r\n-->\r\n<html>\r\n<body>"+ "\r\nDevyn likes <b>R/C Buggies</b>."+ "\r\n</body>\r\n</html>\r\n"); // end } catch (Throwable t) { if (out != null && out.getBufferSize() != 0) out.clearBuffer(); if (pageContext != null) pageContext.handlePageException(t); } finally { if (_jspxFactory != null) jspxFactory.releasePageContext(pageContext); } } } // servlet code generated from JSP source may vary //from container to container
As you can see, Tomcat does a lot of work when it converts a JSP to a servlet. If you look at the source that is sent to your browser, you will see the original HTML in the JSP file. The plain HTML in a JSP is always passed through. What happens when we throw in a little Java syntax? I revised the JSP so that it contains two lines of Java code, as shown in Listing 3.5.
Listing 3.5 Java Code in a JSP File
<!-- Simple demonstration of how Tomcat converts JSP to a servlet. --> <html> <body> Devyn likes <b>R/C Buggies</b>. <br> <%! int count = 100, factor=5; %> <%=count * factor%> </body> </html>
Tomcat converts the Java embedded in the JSP (see Listing 3.5) to the following, which was at the top of the class:
// begin [file="/jsp/jsp_servlet.jsp";from=(7,3);to=(7,31)] int count = 100, factor=5; // end
It also generates this version of the try block, which differed slightly from the previous servlet source:
try { if (_jspx_inited == false) { synchronized (this) { if (_jspx_inited == false) { _jspx_init(); _jspx_inited = true; } } } _jspxFactory = JspFactory.getDefaultFactory(); response.setContentType("text/html;charset=ISO-8859-1"); pageContext = _jspxFactory.getPageContext(this, request, response, "", true, 8192, true); application = pageContext.getServletContext(); config = pageContext.getServletConfig(); session = pageContext.getSession(); out = pageContext.getOut(); // HTML // begin [file="/jsp/jsp_servlet.jsp"...] out.write("<!--\r\n Simple demonstration of how" + " Tomcat converts\r\n JSP to a servlet.\r\n-->" + "\r\n<html>\r\n<body>\r\n" + "Devyn likes <b>R/C Buggies</b>. <br>\r\n"); // end // HTML // begin [file="/jsp/jsp_servlet.jsp";from=...] out.write("\r\n "); // end // begin [file="/jsp/jsp_servlet.jsp";from=...] out.print(count * factor); // end // HTML // begin [file="/jsp/jsp_servlet.jsp";from=...] out.write("\r\n\r\n</body>\r\n</html>\r\n"); // end }
You can see how Tomcat takes the top level count and factor variables declared at the top of the JSP and generates the declarations as class-level variables in the servlet. So, <%=count * factor%> becomes out.print(count * factor);.
Once the translation is completed, the servlet is compiled and loaded into memory. Every subsequent request for this JSP will trigger Tomcat to compare the modification date of the loaded servlet with the date of the JSP. If the JSP changes, Tomcat will translate and recompile it.