Use Eclipse to view the process of JSP compilation to generate Servlet and analyze the principle of JSP compilation


Preface

I believe everyone knows that when a JSP page is requested, it will be compiled by Tomcat into a Servlet (Servlet is a server-side program written in Java language), and then compiled by a Java compiler into an intermediate bytecode file ending in .class. Finally, it is compiled into a binary machine code file that can be recognized by the machine. We demonstrate a small case by using Eclipse to help you find and analyze the Java code files of the Servlet generated after compilation while understanding the principles of JSP compilation.

Insert picture description here


1. Principle of JSP file compilation process

JSP pages will be compiled into Servlet by Tomcat (Servlet is a server-side program written in Java language) when requested , and then compiled into an intermediate bytecode file ending in .class by the Java compiler, and finally compiled into a machine The recognizable binary machine code file , the overall process is shown in the figure below:
Insert picture description here

Two, create and run the JSP page to be tested

We first create a dynamic Web project JavaWebDemo_2020, and create a JSP page Demo01.jsp, and run it once under the Tomcat server . Our test code is as follows:

<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%>
<!DOCTYPE html>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>Insert title here</title>
</head>
<body>
	<h1>Hello,bailu!</h1>
</body>
</html>

The results of the operation are as follows:

Insert picture description here

Three, find the output location of the JSP compiled file

Now our project has been run once on the server. According to the above one, the JSP page has completed the compilation process and has been output, then how can we find the output file?

3.1, open the dynamic project run configuration

Click Run As→Run Configurations... under the current project to enter the run configuration page, as shown in the figure below:

Insert picture description here
Click on the server you are currently using, mine is: Tomcat v9.0 Server at localhost, we then click on Arguments, as shown below:

Insert picture description here

3.2. View the output location of the JSP compiled file

Check the output location of the compiled file according to the Tomcat virtual machine parameter information. The first data Dcatalina.base is the output directory after the JSP file is compiled . For example, my output directory is: D:\bailu\eclipse-jee-2019-09- R-win32-x86_64\eclipse\eclipse-workspace.metadata.plugins\org.eclipse.wst.server.core\tmp0, as shown in the figure below:

Insert picture description here

3.3. View JSP compilation output file

We copy the output directory of the compiled file, open the path in "My Computer", and the following directory structure appears:

Insert picture description here
According to the basic knowledge of JSP about the Web service directory, we can make it clear that the compiled output file is in the work folder . Open the bottom folder of the folder, and we can see the output folder of the current project JavaWebDemo_2020 that we just ran in eclipse. As shown below:

Insert picture description here
When we look down the project folder level by level, we can see the compiled output files of the Demo01.jsp page we just ran. One is the .java file generated by the first compilation of JSP, and the other is the middle of the .class generated after the java file is compiled. Bytecode file , as shown in the figure below:

Insert picture description here

Fourth, the demonstration of JSP compilation output Servlet

It's time to witness the miracle!
Insert picture description here

We use the IDE to open the .java file generated by the JSP page compilation (the .java file is much more readable than the .class file), line by line compared with our JSP page above, is it the same ? This can directly explain that the java file is generated after the JSP page is compiled . The specific code is as follows:

/*
 * Generated by the Jasper component of Apache Tomcat
 * Version: Apache Tomcat/9.0.35
 * Generated at: 2020-10-28 07:21: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.jsp;

import javax.servlet.*;
import javax.servlet.http.*;
import javax.servlet.jsp.*;

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

  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("javax.servlet.http");
    _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 {
    
    

    if (!javax.servlet.DispatcherType.ERROR.equals(request.getDispatcherType())) {
    
    
      final java.lang.String _jspx_method = request.getMethod();
      if ("OPTIONS".equals(_jspx_method)) {
    
    
        response.setHeader("Allow","GET, HEAD, POST, OPTIONS");
        return;
      }
      if (!"GET".equals(_jspx_method) && !"POST".equals(_jspx_method) && !"HEAD".equals(_jspx_method)) {
    
    
        response.setHeader("Allow","GET, HEAD, POST, OPTIONS");
        response.sendError(HttpServletResponse.SC_METHOD_NOT_ALLOWED, "JSP 只允许 GET、POST 或 HEAD。Jasper 还允许 OPTIONS");
        return;
      }
    }

    final javax.servlet.jsp.PageContext pageContext;
    javax.servlet.http.HttpSession session = null;
    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=UTF-8");
      pageContext = _jspxFactory.getPageContext(this, request, response,
      			null, true, 8192, true);
      _jspx_page_context = pageContext;
      application = pageContext.getServletContext();
      config = pageContext.getServletConfig();
      session = pageContext.getSession();
      out = pageContext.getOut();
      _jspx_out = out;

      out.write("\r\n");
      out.write("<!DOCTYPE html>\r\n");
      out.write("<html>\r\n");
      out.write("<head>\r\n");
      out.write("<meta http-equiv=\"Content-Type\" content=\"text/html; charset=UTF-8\">\r\n");
      out.write("<title>Insert title here</title>\r\n");
      out.write("</head>\r\n");
      out.write("<body>\r\n");
      out.write("\t<h1>Hello,bailu!</h1>\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);
    }
  }
}

I don't want to look at the entire code to see the key part of me here , as shown in the following figure:
Insert picture description here
Note : We can see that Java out.write();outputs JSP tags through methods and processes other elements.

  1. This is the reason why JSP appeared in the first place. Using JSP saves a lot of code than Java.
  2. At the same time, it is proved that the first generated after the JSP file is compiled is the Servlet.
  3. In other words, JSP is essentially Servlet, and ultimately Java code.

Five, the process of accessing JSP files

At this point, we have learned that the servlet will be generated first when the JSP file is saved, loaded and compiled for the first time , and the subsequent compilation process will be performed. Therefore, removing the cause of browser caching, you will feel slow when you first visit a JSP page, and later visits will be faster.

Whether it is the first time to access the JSP file, the process is shown in the following figure:

Insert picture description here
But please note : If your JSP file has been modified, clicking Save again will recompile the release, and the compilation process will be re-entered.


to sum up

This article introduces you to the compilation process after the JSP page is released, from JSP files to Sevlet (Java files) to .class files and finally to binary machine code. It analyzes why the essence of JSP is Servlet, so that you can take the MVC model further. Understand and deepen the mastery of the level of JSP in the architecture. I also suggest that everyone develop a good habit: look at the source code! Source code is everything!

Insert picture description here


Thank you for your support. I am Bailu, a program ape who works tirelessly. I hope this post can help everyone, and welcome everyone's one-click three-connection! If you have any questions, suggestions or supplements, you can leave a message at the bottom of the post to help more people!
More information WeChat search public accountWDeerCode code circle

Guess you like

Origin blog.csdn.net/qq_22695001/article/details/109333723