Utilisez Eclipse pour visualiser le processus de compilation JSP pour générer un servlet et analyser le principe de la compilation JSP


Préface

Je crois que tout le monde sait que lorsqu'une page JSP est demandée, elle sera compilée par Tomcat dans un servlet (Servlet est un programme côté serveur écrit en langage Java), puis compilée par un compilateur Java dans un fichier bytecode intermédiaire se terminant par. Enfin, il est compilé dans un fichier de code machine binaire qui peut être reconnu par la machine. Nous démontrons un petit cas en utilisant Eclipse pour vous aider à trouver et analyser les fichiers de code Java du Servlet généré après la compilation tout en comprenant les principes de la compilation JSP.

Insérez la description de l'image ici


1. Principe du processus de compilation de fichiers JSP

Les pages JSP seront compilées en Servlet par Tomcat (Servlet est un programme côté serveur écrit en langage Java) à la demande , puis compilées dans un fichier bytecode intermédiaire se terminant par .class par le compilateur Java, et finalement compilées dans une machine Le reconnaissable fichier de code machine binaire , le processus global est illustré dans la figure ci-dessous:
Insérez la description de l'image ici

Deuxièmement, créez et exécutez la page JSP à tester

Nous créons d'abord un projet Web dynamique JavaWebDemo_2020, et créons une page JSP Demo01.jsp, et l' exécutons une fois sous le serveur Tomcat . Notre code de test est le suivant:

<%@ 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>

Les résultats de l'opération sont les suivants:

Insérez la description de l'image ici

Troisièmement, recherchez l'emplacement de sortie du fichier compilé JSP

Maintenant, notre projet a été exécuté une fois sur le serveur.Selon ce qui précède, la page JSP a terminé le processus de compilation et a été sortie, alors comment pouvons-nous trouver le fichier de sortie?

3.1, ouvrez la configuration d'exécution de projet dynamique

Cliquez sur Exécuter en tant que → Exécuter les configurations ... sous le projet actuel pour accéder à la page de configuration d'exécution, comme illustré dans la figure ci-dessous:

Insérez la description de l'image ici
Cliquez sur le serveur que vous utilisez actuellement, le mien est: Tomcat v9.0 Server at localhost, nous cliquons ensuite sur Arguments, comme indiqué ci-dessous:

Insérez la description de l'image ici

3.2. Afficher l'emplacement de sortie du fichier compilé JSP

Vérifiez l'emplacement de sortie du fichier compilé en fonction des informations sur les paramètres de la machine virtuelle Tomcat. La première donnée Dcatalina.base est le répertoire de sortie après la compilation du fichier JSP . Par exemple, mon répertoire de sortie est: D: \ bailu \ eclipse-jee -2019-09- R-win32-x86_64 \ eclipse \ eclipse-workspace.metadata.plugins \ org.eclipse.wst.server.core \ tmp0, comme indiqué dans la figure ci-dessous:

Insérez la description de l'image ici

3.3. Afficher le fichier de sortie de la compilation JSP

Nous copions le répertoire de sortie du fichier compilé, ouvrons le chemin dans "Poste de travail" et la structure de répertoires suivante apparaît:

Insérez la description de l'image ici
Selon les connaissances de base de JSP sur le répertoire de service Web, nous pouvons indiquer clairement que le fichier de sortie compilé se trouve dans le dossier de travail . Ouvrez le dossier du bas du dossier, et nous pouvons voir le dossier de sortie du projet actuel JavaWebDemo_2020 que nous vient de s'exécuter dans eclipse. Comme indiqué ci-dessous:

Insérez la description de l'image ici
Si nous regardons le dossier du projet niveau par niveau, nous pouvons voir les fichiers de sortie compilés de la page Demo01.jsp que nous venons d'exécuter. L'un est le fichier .java généré par la première compilation de JSP, et l'autre est le milieu de la .class généré après la compilation du fichier java. Fichier Bytecode , comme illustré dans la figure ci-dessous:

Insérez la description de l'image ici

Quatrièmement, la démonstration du servlet de sortie de compilation JSP

Il est temps d'assister au miracle!
Insérez la description de l'image ici

Nous utilisons l'EDI pour ouvrir le fichier .java généré par la compilation de la page JSP (le fichier .java est beaucoup plus lisible que le fichier .class), ligne par ligne par rapport à notre page JSP ci-dessus, est-ce la même chose ? Cela peut expliquer directement que le fichier java est généré après la compilation de la page JSP . Le code spécifique est le suivant:

/*
 * 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);
    }
  }
}

Je ne veux pas regarder le code entier pour voir la partie clé de moi ici , comme le montre la figure suivante:
Insérez la description de l'image ici
Remarque : Nous pouvons voir que Java out.write();génère des balises JSP via des méthodes et traite d'autres éléments.

  1. C'est la raison pour laquelle JSP est apparu en premier lieu.Utiliser JSP économise beaucoup de code que Java.
  2. Dans le même temps, il est prouvé que le premier généré après la compilation du fichier JSP est le servlet.
  3. En d'autres termes, JSP est essentiellement un servlet, et finalement du code Java.

Cinq, le processus d'accès aux fichiers JSP

À ce stade, nous avons appris que le servlet sera généré en premier lorsque le fichier JSP est enregistré, chargé et compilé pour la première fois , et que le processus de compilation suivant sera exécuté. Par conséquent, en supprimant la cause de la mise en cache du navigateur, vous vous sentirez lent lorsque vous visiterez une page JSP pour la première fois, et les visites ultérieures seront plus rapides.

Que ce soit la première fois que vous accédez au fichier JSP, le processus est illustré dans la figure suivante:

Insérez la description de l'image ici
Mais s'il vous plaît noter : Si votre fichier JSP a été modifié, cliquer à nouveau sur Enregistrer recompilera la version et le processus de compilation sera réintroduit.


Pour résumer

Cet article vous présente le processus de compilation après la publication de la page JSP, des fichiers JSP au Sevlet (fichiers Java) aux fichiers .class et enfin au code machine binaire. Il analyse pourquoi l'essence de JSP est Servlet, afin que vous puissiez prendre Approfondir le mode MVC Comprendre et approfondir la maîtrise du niveau de JSP dans l'architecture. Je suggère également à chacun de développer une bonne habitude: regardez le code source! Le code source est tout!

Insérez la description de l'image ici


Merci pour votre soutien Je suis Bailu, un programmeur qui travaille sans relâche. J'espère que cet article pourra aider tout le monde et souhaiter la bienvenue à tous les trois connexions en un clic! Si vous avez des questions, des suggestions ou des suppléments, vous pouvez laisser un message en bas de l'article pour aider plus de personnes!
Plus d'informations Recherche WeChat Compte public 【Cercle de code WDeerCode

Je suppose que tu aimes

Origine blog.csdn.net/qq_22695001/article/details/109333723
conseillé
Classement