How JSP Works


This article is a series of JSP Tutorial. In this article, we will learn how JSP works with a simple example.

JavaServer page (JSP) is a template for a Web page that uses Java code to generate an HTML document dynamically. JSPs are run in a server-side component known as a JSP container, which translates them into equivalent Java servlets. For this reason, servlets and JSP pages are intimately related.

How JSP Works

A JSP page exists in three forms:
  • JSP source code - This is the form the developer actually writes. It exists in a text file with an extension of .jsp, and consists of a mix of HTML template code, Java language statements, and JSP directives and actions that describe how to generate a Web page to service a particular request.
  • Java source code - The JSP container translates the JSP source code into the source code for an equivalent Java servlet as needed. This source code is typically saved in a work area and is often helpful for debugging.
  • Compiled Java class - Like any other Java class, the generated servlet code is compiled into bytecodes in a .class file, ready to be loaded and executed.

How the container process JSP page?

The JSP container manages each of these forms of the JSP page automatically, based on the timestamps of each file. In response to an HTTP request, the container checks to see if the .jsp source file has been modified since the .java source was last compiled. If so, the container retranslates the JSP source into Java source and recompiles it.
The above diagram illustrates the process used by the JSP container. When a request for a JSP page is made, the container first determines the name of the class corresponding to the .jsp file. If the class doesn’t exist or if it’s older than the .jsp file (meaning the JSP source has changed since it was last compiled), then the container creates Java source code for an equivalent servlet and compiles it. If an instance of the servlet isn’t already running, the container loads the servlet class and creates an instance. Finally, the container dispatches a thread to handle the current HTTP request in the loaded instance.

Demonstrating How JSP Works with Basic Example

To illustrate how JSP works, let’s look at the example converting kilometers per liter to miles per gallon JSP example.

converter.jsp

<%@ page language="java" contentType="text/html; charset=ISO-8859-1"
 pageEncoding="ISO-8859-1"%>

<%@ page session="false"%>
<%@ page import="java.io.*,java.text.*,java.util.*"%>

<!DOCTYPE html>
<html>
<head>
<meta charset="ISO-8859-1">
<title>>Fuel Efficiency Conversion Chart</title>
<%!private static final DecimalFormat FMT = new DecimalFormat("#0.00");%>
</head>
<body>
 <%-- Prints a conversion table of miles per gallon to kilometers per liter --%>
<BODY>
 <H3>Fuel Efficiency Conversion Chart</H3>
 <TABLE BORDER=1>
  <TR>
   <TH>Kilometers per Liter</TH>
   <TH>Miles per Gallon</TH>
  </TR>
  <%
   for (double kpl = 5; kpl <= 20; kpl += 1.0) {
    double mpg = kpl * 2.352146;
  %>
  <TR>
   <TD><%=FMT.format(kpl)%></TD>
   <TD><%=FMT.format(mpg)%></TD>
  </TR>
  <%
   }
  %>
 </TABLE>
</body>
</html>
Let's invoke this JSP page from a Web browser, you see the table on a browser:

converter_jsp.java

To make the JSP-to-servlet relationship clearer, look at the .java source code generated by the JSP container. This code will differ greatly, depending on which container is used and the implementation approach it takes. This code was generated by tomcat 8.5.
/*
 * Generated by the Jasper component of Apache Tomcat
 * Version: Apache Tomcat/8.5.31
 * Generated at: 2019-01-05 09:45:14 UTC
 * Note: The last modified time of this file was set to
 *       the last modified time of the source file after
 *       generation to assist with modification tracking.
 */
package org.apache.jsp;

import javax.servlet.*;
import javax.servlet.http.*;
import javax.servlet.jsp.*;
import java.io.*;
import java.text.*;
import java.util.*;

public final class converter_jsp extends org.apache.jasper.runtime.HttpJspBase
implements org.apache.jasper.runtime.JspSourceDependent,
    org.apache.jasper.runtime.JspSourceImports {

        private static final DecimalFormat FMT = new DecimalFormat("#0.00");
        private static final javax.servlet.jsp.JspFactory _jspxFactory =
            javax.servlet.jsp.JspFactory.getDefaultFactory();

        private static java.util.Map < java.lang.String, java.lang.Long > _jspx_dependants;

        private static final java.util.Set < java.lang.String > _jspx_imports_packages;

        private static final java.util.Set < java.lang.String > _jspx_imports_classes;

        static {
            _jspx_imports_packages = new java.util.HashSet < > ();
            _jspx_imports_packages.add("javax.servlet");
            _jspx_imports_packages.add("java.text");
            _jspx_imports_packages.add("java.util");
            _jspx_imports_packages.add("javax.servlet.http");
            _jspx_imports_packages.add("java.io");
            _jspx_imports_packages.add("javax.servlet.jsp");
            _jspx_imports_classes = null;
        }

        private volatile javax.el.ExpressionFactory _el_expressionfactory;
        private volatile org.apache.tomcat.InstanceManager _jsp_instancemanager;

        public java.util.Map < java.lang.String, java.lang.Long > getDependants() {
            return _jspx_dependants;
        }

        public java.util.Set < java.lang.String > getPackageImports() {
            return _jspx_imports_packages;
        }

        public java.util.Set < java.lang.String > getClassImports() {
            return _jspx_imports_classes;
        }

        public javax.el.ExpressionFactory _jsp_getExpressionFactory() {
            if (_el_expressionfactory == null) {
                synchronized(this) {
                    if (_el_expressionfactory == null) {
                        _el_expressionfactory = _jspxFactory.getJspApplicationContext(getServletConfig().getServletContext()).getExpressionFactory();
                    }
                }
            }
            return _el_expressionfactory;
        }

        public org.apache.tomcat.InstanceManager _jsp_getInstanceManager() {
            if (_jsp_instancemanager == null) {
                synchronized(this) {
                    if (_jsp_instancemanager == null) {
                        _jsp_instancemanager = org.apache.jasper.runtime.InstanceManagerFactory.getInstanceManager(getServletConfig());
                    }
                }
            }
            return _jsp_instancemanager;
        }

        public void _jspInit() {}

        public void _jspDestroy() {}

        public void _jspService(final javax.servlet.http.HttpServletRequest request, final javax.servlet.http.HttpServletResponse response)
        throws java.io.IOException, javax.servlet.ServletException {

            final java.lang.String _jspx_method = request.getMethod();
            if (!"GET".equals(_jspx_method) && !"POST".equals(_jspx_method) && !"HEAD".equals(_jspx_method) && !javax.servlet.DispatcherType.ERROR.equals(request.getDispatcherType())) {
                response.sendError(HttpServletResponse.SC_METHOD_NOT_ALLOWED, "JSPs only permit GET POST or HEAD");
                return;
            }

            final javax.servlet.jsp.PageContext pageContext;
            final javax.servlet.ServletContext application;
            final javax.servlet.ServletConfig config;
            javax.servlet.jsp.JspWriter out = null;
            final java.lang.Object page = this;
            javax.servlet.jsp.JspWriter _jspx_out = null;
            javax.servlet.jsp.PageContext _jspx_page_context = null;


            try {
                response.setContentType("text/html; charset=ISO-8859-1");
                pageContext = _jspxFactory.getPageContext(this, request, response,
                    null, false, 8192, true);
                _jspx_page_context = pageContext;
                application = pageContext.getServletContext();
                config = pageContext.getServletConfig();
                out = pageContext.getOut();
                _jspx_out = out;

                out.write("\r\n");
                out.write("\r\n");
                out.write("\r\n");
                out.write("\r\n");
                out.write("\r\n");
                out.write("<!DOCTYPE html>\r\n");
                out.write("<html>\r\n");
                out.write("<head>\r\n");
                out.write("<meta charset=\"ISO-8859-1\">\r\n");
                out.write("<title>>Fuel Efficiency Conversion Chart</title>\r\n");
                out.write("\r\n");
                out.write("</head>\r\n");
                out.write("<body>\r\n");
                out.write("\t");
                out.write("\r\n");
                out.write("<BODY>\r\n");
                out.write("\t<H3>Fuel Efficiency Conversion Chart</H3>\r\n");
                out.write("\t<TABLE BORDER=1>\r\n");
                out.write("\t\t<TR>\r\n");
                out.write("\t\t\t<TH>Kilometers per Liter</TH>\r\n");
                out.write("\t\t\t<TH>Miles per Gallon</TH>\r\n");
                out.write("\t\t</TR>\r\n");
                out.write("\t\t");

                for (double kpl = 5; kpl <= 20; kpl += 1.0) {
                    double mpg = kpl * 2.352146;

                    out.write("\r\n");
                    out.write("\t\t<TR>\r\n");
                    out.write("\t\t\t<TD>");
                    out.print(FMT.format(kpl));
                    out.write("</TD>\r\n");
                    out.write("\t\t\t<TD>");
                    out.print(FMT.format(mpg));
                    out.write("</TD>\r\n");
                    out.write("\t\t</TR>\r\n");
                    out.write("\t\t");

                }

                out.write("\r\n");
                out.write("\t</TABLE>\r\n");
                out.write("</body>\r\n");
                out.write("</html>");
            } catch (java.lang.Throwable t) {
                if (!(t instanceof javax.servlet.jsp.SkipPageException)) {
                    out = _jspx_out;
                    if (out != null && out.getBufferSize() != 0)
                        try {
                            if (response.isCommitted()) {
                                out.flush();
                            } else {
                                out.clearBuffer();
                            }
                        } catch (java.io.IOException e) {}
                    if (_jspx_page_context != null) _jspx_page_context.handlePageException(t);
                    else throw new ServletException(t);
                }
            } finally {
                _jspxFactory.releasePageContext(_jspx_page_context);
            }
        }
    }
Now the question is where does Eclipse store generate servlet files for Tomcat?

Comments