I often ask if there is any difference between JSP and Servlet, what is the connection between the two? In fact, the performance of servlet technology is very early, which is developed for the application of Java server. Everyone knows that applet is a applet, servlet is a server-side applet. However, after Microsoft's ASP technology appears, the output statement of a row of rows when using the servlet, is very awkward, and this is the case for complex layout or display pages. JSP is to meet this need to be developed on servlet technology. It can be seen that there is an intrinsic blood relationship between JSP and Servlet. When learning JSP, if you can seize this connection, you can understand the operational mechanism of JSP and achieve the effect of halving.
This article will pass the inside of JSP operation by analyzing an JSP operation process, and elaborate from a new perspective.
HelloWorld.jsp
We take Tomcat 4.1.17 servers as an example to see how the easiest helloworld.jsp runs.
Code List 1: HelloWorld.jsp
HelloWorld.jsp <% string message = "Hello World!";%> <% = Message%>
This file is very simple, only defines a string variable and outputs. Put this file in the Tomcat's WebApps / root / directory, start Tomcat, access http: // localhost: 8080 / helloworld.jsp, the output in the browser is "HelloWorld!"
Let us see what Tomcat has done. Go to Tomcat / Work / Standalone / localhost / _ directory, you can find the following helloworld_jsp.java, this file is the source file generated when Tomcat parsing HelloWorld.jsp:
Code List 2: HelloWorld_Jsp.Java
Package org.apache.jsp;
Import javax.servlet. *; import javax.servlet.http. *; import javax.servlet.jsp. *; import org.Apache.jasper.Runtime. *;
public class HelloWorld_jsp extends HttpJspBase {...... public void _jspService (HttpServletRequest request, HttpServletResponse response) throws java.io.IOException, ServletException {JspFactory _jspxFactory = null; javax.servlet.jsp.PageContext pageContext = null; HttpSession session = NULL; servletcontext application = null; servletconfig config = null; jspwriter out = null; object page = this; jspwriter _jspx_out = null;
try {_jspxFactory = JspFactory.getDefaultFactory (); response.setContentType ( "text / html; charset = ISO-8859-1"); pageContext = _jspxFactory.getPageContext (this, request, response, null, true, 8192, true); application = pageContext.getServletContext (); config = pageContext.getServletConfig (); session = pageContext.getSession (); out = pageContext.getOut (); _jspx_out = out; String message = "Hello World!"; out.print (message );} Catch (throwable t) {out = _jspx_out; if (out! = Null && out.getBuffersize ()! = 0) out.clearbuffer (); if (pageContext! = Null) PageContext.HandlePageException (t);} Finally {if (_jspxfactory! = null) _JspxFactory.releasePageContext (pageContext);}}}
As can be seen from the above, helloWorld.jsp first parsed to a Java class helloworld_jsp.java, which inherits in the org.apache.jasper.Runtime.httpjspBase base class, HTTPJSPBASE implements the httpservlet interface. It can be seen that JSP first compiled into a servlet before running, which is the key to understanding JSP technology.
We also know that there are several objects in the JSP page, such as PageContext, Application, Config, Page, Session, Out, etc. You may be strange, why you can use these built-in objects directly in the code snippet in the JSP. Observe _JspService () method, in fact, these built-in objects are defined here. Initialize these built-in objects before analyzing the code snippet in the JSP file.
First, call the JSPFactory's getDefaultFactory () method to obtain a reference to a JSPFactory object of the container implementation (refer to Tomcat 4.1.17). JSPFactory is an abstract class defined in the javax.servlet.jsp package, which defines two static methods set / getDefaultFactory (). The SET method is placed by the JSP container (Tomcat). When the page servlet (ie HelloWorld_JSP class) is placed, it can directly call the JSPFactory.getDefaultFactory () method to get the implementation class of this JSP factory. Tomcat is called org.apache.jasper.Runtime.jspFactoryImpl class.
Then, call this JSPFactoryImpl's getPageContext () method, populate a PageContext, and assign the built-in variable PageConext. Other built-in objects are obtained via this pageContext. The specific process see the code above, and details will not be described here. The page servlet's environment is complete, and the page begins to parse the page. The HelloWorld.JSP page only defines a string variable and then outputs it directly. The parsed code is as follows: Code List 3: JSP page analysis code snippet
String message = "Hello World!"; Out.Print (Message);
Customized tag analysis process
In a large web application, JSP custom labels are usually used to encapsulate page display logic. An analysis of the parsing process of the custom label is very helpful to our in-depth understanding of the operational mechanism of customized labels. Below we run as an example with the homepage of Struts-Example apps attached in Struts1.1.
INDEX.JSP containing custom labels
The download address of Struts1.1 is http://jakarta.apache.org/struts/index.html. Put the downloaded package, you can find Struts-Example.war under the WebApps directory. Copy the WAR package to the Tomcat's WebApps directory, Tomcat will automatically install this package. Access the Struts-Example App to HTTP: // localhost: 8080 / Struts-Example in the browser, the home page of the app is displayed (see Figure 1).
Figure 1 Home
Code List 4: INDEX.JSP
<% @ Page ContentType = "Text / HTML; Charset = UTF-8" Language = "Java"%> <% @ Taglib URI = "/ Web-INF / STRUTS-Bean.TLD" prefix = "bean"%> < % @ Taglib Uri = "/ Web-INF / STRUTS-HTML.TLD" prefix = "HTML"%> <% @ Taglib URI = "/ Web-inf / struts-logic.tld" prefix = "logic"%> < HTML: html locale = "true">
We only analyze as an example only as an example of
It can be seen that the container has replaced the
Analytical process
So, how does the JSP container complete parsing? View Index_jsp.java files after the work directory jakarta-tomcat-4.1.17 / work / standardalone / localhost / struts-example:
Code List 5: INDEX_JSP.JAVA
Package org.apache.jsp;
Import javax.servlet. *; import javax.servlet.http. *; import javax.servlet.jsp. *; import org.apache.jasper.runtime. *; public class index_jsp extends httpjspbase {// For all custom tag definitions a reference processor pool of private org.apache.jasper.runtime.TagHandlerPool; _jspx_tagPool_bean_message_key; ...... // page class constructor public index_jsp () {_jspx_tagPool_bean_message_key = new org.apache.jasper.runtime.TagHandlerPool (); ......}
public void _jspService (HttpServletRequest request, HttpServletResponse response) throws java.io.IOException, ServletException {...... _jspxFactory = JspFactory.getDefaultFactory (); response.setContentType ( "text / html; charset = UTF-8"); pageContext = _jspxFactory. getPageContext (this, request, response, null, true, 8192, true); application = pageContext.getServletContext (); config = pageContext.getServletConfig (); session = pageContext.getSession (); out = pageContext.getOut (); _jspx_out = Out; ... if (_jspx_meth_html_html_0) Return; ...} // Release all custom labels when processing exit PUBLIC VOID _JSPDESTROY () {_jspx_tagpool_bean_message_key.release (); ......}}
The generated index_jsp.java inherits in org.apache. Jasper.Runtime.httpjspbase. Research this document provides us to understand the operational mechanism of custom labels.
As can be seen from the above, Tomcat first defines each custom label and instantizes a TagHandlerPool object for each custom tag when parsing a JSP page. The processing method of the page covers the _ jspservice () method of the parent class, _jspservice method first initializes the environment and assigns a built-in object. Since the index.jsp page is wrapped in a
Bean: Analysis of Message Tags
Code List 7: _jspx_meth_bean_message_0 () method pieces
// message processing method of custom tags private boolean _jspx_meth_bean_message_0 (javax.servlet.jsp.tagext.Tag _jspx_th_html_html_0, javax.servlet.jsp.PageContext pageContext) throws Throwable {JspWriter out = pageContext.getOut (); / * --- - bean: message ---- * / org.apache.struts.taglib.bean.MessageTag _jspx_th_bean_message_0 = (org.apache.struts.taglib.bean.MessageTag) _jspx_tagPool_bean_message_key.get (org.apache.struts.taglib.bean. MessageTag.class); _jspx_th_bean_message_0.setPageContext (pageContext); _jspx_th_bean_message_0.setParent (_jspx_th_html_html_0); _jspx_th_bean_message_0.setKey ( "index.title"); int _jspx_eval_bean_message_0 = _jspx_th_bean_message_0.doStartTag (); if (_jspx_th_bean_message_0.doEndTag () == javax. Servlet.jsp.tagext.tag.skip_page) Return true; _jspx_tagpool_bean_message_key.reuse (_jspx_th_bean_message_0); Return False;} Also, for HTML: Bean also needs to get a label class from the pool, then set the environment. Not detailed here. We only focus on the special processing section of the MessageTag custom label class. The development of custom labels is not within the scope of this article. A bean: Message label is defined in Index.jsp, and sets an attribute:
Tag class object instance
In order to improve the operational efficiency, Tomcat is done to all custom labels, and the poolization work is done by org.apache.jasper. Runtime.taghandlerpool class. There are two main methods in the TagHandlerPool class, the code is as follows:
Code List 8: TagHandlerpool.java
public class TagHandlerPool {private static final int MAX_POOL_SIZE = 5; private Tag [] handlers; public synchronized Tag get (Class handlerClass) throws JspException {......} public synchronized void reuse (Tag handler) {......}} TagHandlerPool achieved simply The pool of the label class, where max_pool_size is the initial size of the pool, and Handlers is an array of TAGs and instances of the label class. Get (class handlerclass) gets an instance of a specified tag class. If there is no instance in the pool, a new instance is new. Reuse (Tag Handler) puts the Handler object back in the pool.
At this point, we have the operation of JSP in the container. Although the resolution of each JSP container will differ, but the principles are similar. For written JSP applications, we do not need to interfere with the running process in the container, but if you are familiar with the overall running mechanism, you can have a deeper understanding of JSP / servlet technology.