IT评测·应用市场-qidao123.com

标题: JSP 的本质原理解析:"编写的时候是JSP,心里想解读的是 java 源码" [打印本页]

作者: 十念    时间: 2023-4-30 18:58
标题: JSP 的本质原理解析:"编写的时候是JSP,心里想解读的是 java 源码"
JSP 的本质原理解析:"编写的时候是JSP,心里想解读的是 java 源码"


@
目录

每博一文案
  1. 活明白的人,一生只做好了这两件事:
  2. 每个瞬间都充满了选择和承担,就算面前是一座独木桥,也必须选择是前进后退,亦或是留在原地此时此刻你所经历的一切。
  3. 这是过往无数个选择后的结果,哪些小的选择汇聚在了一起,最终成了我们今天的时光。
  4. 其实,活明白的人一生只做好了两件事看,一是选择,二是承担。常听人争论选择和努力哪个更重要。
  5. 其实,努力并不是选择的对比面,而是拥有选择的基本条件。不努力的人往往连选择的资格都没有,努力是为了,
  6. 更好的选择。正如马伯庸说:所谓的选择只是努力所赋予人的一种资格。
  7. 所有的一夜成名,刹那的焰火,实际是过往今年默默努力埋下的伏笔,因此这里说的选择不是投机取巧的小聪明。
  8. 而是积淀后的深思熟虑。常言道:选择不对,努力白费。
  9. 李兰娟院士在为了汕头大学的毕业学生送上给予时,表示:不管是在生活还是事业上,有很多外部变化和环境因素是我们
  10. 所无法选择的。我们可以选择的是在每一个人生路口要做出怎样的选择,以及如何勇敢的前行。
  11. 我们所有的人都在共享一段岁月,却在不同的选择中分道扬镳,因为人生最重要的除了努力还有选择。
  12. 当你被生活的疲惫裹挟着,被环境的艰难牵制着,这时你要么被生活牵着鼻子走,要么接收痛苦与打击,抗住一场场暴风雪,主动迎击一地鸡毛的琐碎,你要做的不是抱怨生活的不公,而是迈出步子,夺下生活的主导权,做出选择了。
  13. 一种选择就是一种代价,不同的选择造就了不同的人生,人打从生下来就面临着很多种未知的可能。
  14. 未来都是一张白纸,任由自己去上色作画。有些人完成地很好,也有人画得一团糟,人生的一万种可能好的,不好的
  15. 都是有认真选择好。
  16. 每一支画笔,在每次选择时都要坚持原则,便是对自己的人生负责。
  17.                                             —————— 《一禅心灵庙语》
复制代码
1. JSP  概述

JSP(全称JavaServer Pages),sun公司主导的一种动态网页技术,JSP在服务端运行,可以响应客户端的请求,根据请求内容动态的生成HTML、XML或其他格式文档的Web网页然后返回请求者。在JSP页面可以嵌入Java代码,JSP文件在运行时会被其编译器转换成更原始的Servlet代码,然后再由Java编译器来编译成能快速执行的二进制机器码。
2.特点:
3.JSP页面组成:
在 HTML 页面文件中加入 Java 程序段和 JSP 标签,即可构成一个 JSP 页文件,JSP 页面由 5 种元素组合而成。
普通的 HTML 标记符。
2. 第一个 JSP 程序

我的第一个JSP程序:
这里给一个小的建议,大家在阅读如下,文章时,可以带着一个这样的问题:JSP 是什么 ? 去阅读文章,有助于后面的内容上的阅读理解。
WEB-INF目录之外创建一个 index.jsp文件,然后这个文件中没有任何内容。注意 了:我们对于这个jsp 文件当中并没有编写任何的内容,一个字符,一个标点都可以,就是一个空白的。如下显示的:

将上面的项目部署之后,启动服务器,打开浏览器,访问以下地址 http://127.0.0.1:8080/servlet14/index.jsp 我们部署的项目的路径:具体显示如下。

重点: 实际上我们访问的以上的这个:index.jsp,底层执行的是:index_jsp.class 这个java程序。我们可以在我们本地电脑上访问到该生成是 index_jsp.class,index_jsp.java的文件,该生成的对应的.class,.java文件所在的路径是在我们启动 Tomcat 服务器当中提示的,一个 CATALINA_BASE路径下的 C:\Users\huo\AppData\Local\JetBrains\IntelliJIdea2022.1\tomcat\4b6bbfbb-d520-498b-b8f2-090a7ad68f62

这个index.jsp会被tomcat翻译生成index_jsp.java文件,然后tomcat服务器又会将 index_jsp.java编译生成index_jsp.class文件。访问index.jsp,实际上执行的是index_jsp.class中的方法。
如下是我们访问 index.jsp 在我本地电脑上生成的 CATALINA_BASE的 路径下的,index_jsp.java,index_jsp.class 的文件。 C:\Users\huo\AppData\Local\JetBrains\IntelliJIdea2022.1\tomcat\4b6bbfbb-d520-498b-b8f2-090a7ad68f62\work\Catalina\localhost\servlet14\org\apache\jsp

如下是我们的一个 index.jsp(空内容) 被翻译为  index_jsp.java 文件的内容如下:
  1. /*
  2. * Generated by the Jasper component of Apache Tomcat
  3. * Version: Apache Tomcat/10.0.12
  4. * Generated at: 2023-04-21 03:20:48 UTC
  5. * Note: The last modified time of this file was set to
  6. *       the last modified time of the source file after
  7. *       generation to assist with modification tracking.
  8. */
  9. package org.apache.jsp;
  10. import jakarta.servlet.*;
  11. import jakarta.servlet.http.*;
  12. import jakarta.servlet.jsp.*;
  13. public final class index_jsp extends org.apache.jasper.runtime.HttpJspBase
  14.     implements org.apache.jasper.runtime.JspSourceDependent,
  15.                  org.apache.jasper.runtime.JspSourceImports {
  16.   private static final jakarta.servlet.jsp.JspFactory _jspxFactory =
  17.           jakarta.servlet.jsp.JspFactory.getDefaultFactory();
  18.   private static java.util.Map<java.lang.String,java.lang.Long> _jspx_dependants;
  19.   private static final java.util.Set<java.lang.String> _jspx_imports_packages;
  20.   private static final java.util.Set<java.lang.String> _jspx_imports_classes;
  21.   static {
  22.     _jspx_imports_packages = new java.util.HashSet<>();
  23.     _jspx_imports_packages.add("jakarta.servlet");
  24.     _jspx_imports_packages.add("jakarta.servlet.http");
  25.     _jspx_imports_packages.add("jakarta.servlet.jsp");
  26.     _jspx_imports_classes = null;
  27.   }
  28.   private volatile jakarta.el.ExpressionFactory _el_expressionfactory;
  29.   private volatile org.apache.tomcat.InstanceManager _jsp_instancemanager;
  30.   public java.util.Map<java.lang.String,java.lang.Long> getDependants() {
  31.     return _jspx_dependants;
  32.   }
  33.   public java.util.Set<java.lang.String> getPackageImports() {
  34.     return _jspx_imports_packages;
  35.   }
  36.   public java.util.Set<java.lang.String> getClassImports() {
  37.     return _jspx_imports_classes;
  38.   }
  39.   public jakarta.el.ExpressionFactory _jsp_getExpressionFactory() {
  40.     if (_el_expressionfactory == null) {
  41.       synchronized (this) {
  42.         if (_el_expressionfactory == null) {
  43.           _el_expressionfactory = _jspxFactory.getJspApplicationContext(getServletConfig().getServletContext()).getExpressionFactory();
  44.         }
  45.       }
  46.     }
  47.     return _el_expressionfactory;
  48.   }
  49.   public org.apache.tomcat.InstanceManager _jsp_getInstanceManager() {
  50.     if (_jsp_instancemanager == null) {
  51.       synchronized (this) {
  52.         if (_jsp_instancemanager == null) {
  53.           _jsp_instancemanager = org.apache.jasper.runtime.InstanceManagerFactory.getInstanceManager(getServletConfig());
  54.         }
  55.       }
  56.     }
  57.     return _jsp_instancemanager;
  58.   }
  59.   public void _jspInit() {
  60.   }
  61.   public void _jspDestroy() {
  62.   }
  63.   public void _jspService(final jakarta.servlet.http.HttpServletRequest request, final jakarta.servlet.http.HttpServletResponse response)
  64.       throws java.io.IOException, jakarta.servlet.ServletException {
  65.     if (!jakarta.servlet.DispatcherType.ERROR.equals(request.getDispatcherType())) {
  66.       final java.lang.String _jspx_method = request.getMethod();
  67.       if ("OPTIONS".equals(_jspx_method)) {
  68.         response.setHeader("Allow","GET, HEAD, POST, OPTIONS");
  69.         return;
  70.       }
  71.       if (!"GET".equals(_jspx_method) && !"POST".equals(_jspx_method) && !"HEAD".equals(_jspx_method)) {
  72.         response.setHeader("Allow","GET, HEAD, POST, OPTIONS");
  73.         response.sendError(HttpServletResponse.SC_METHOD_NOT_ALLOWED, "JSP 只允许 GET、POST 或 HEAD。Jasper 还允许 OPTIONS");
  74.         return;
  75.       }
  76.     }
  77.     final jakarta.servlet.jsp.PageContext pageContext;
  78.     jakarta.servlet.http.HttpSession session = null;
  79.     final jakarta.servlet.ServletContext application;
  80.     final jakarta.servlet.ServletConfig config;
  81.     jakarta.servlet.jsp.JspWriter out = null;
  82.     final java.lang.Object page = this;
  83.     jakarta.servlet.jsp.JspWriter _jspx_out = null;
  84.     jakarta.servlet.jsp.PageContext _jspx_page_context = null;
  85.     try {
  86.       response.setContentType("text/html");
  87.       pageContext = _jspxFactory.getPageContext(this, request, response,
  88.                               null, true, 8192, true);
  89.       _jspx_page_context = pageContext;
  90.       application = pageContext.getServletContext();
  91.       config = pageContext.getServletConfig();
  92.       session = pageContext.getSession();
  93.       out = pageContext.getOut();
  94.       _jspx_out = out;
  95.       out.write(' ');
  96.       out.write(' ');
  97.     } catch (java.lang.Throwable t) {
  98.       if (!(t instanceof jakarta.servlet.jsp.SkipPageException)){
  99.         out = _jspx_out;
  100.         if (out != null && out.getBufferSize() != 0)
  101.           try {
  102.             if (response.isCommitted()) {
  103.               out.flush();
  104.             } else {
  105.               out.clearBuffer();
  106.             }
  107.           } catch (java.io.IOException e) {}
  108.         if (_jspx_page_context != null) _jspx_page_context.handlePageException(t);
  109.         else throw new ServletException(t);
  110.       }
  111.     } finally {
  112.       _jspxFactory.releasePageContext(_jspx_page_context);
  113.     }
  114.   }
  115. }
复制代码
3. JSP 的本质就是 Servlet

从上述我们编写的第一jsp 程序,index.jsp 空内容的,index.jsp访问的时候,会自动翻译生成index_jsp.java,会自动编译生成index_jsp.class,那么index_jsp 这就是一个类。

从图中我们可以看到,该index.jsp 翻译的 index_jsp.java 类是继承了 extends org.apache.jasper.runtime.HttpJspBase 类的,我们查阅其 Tomcat 10 的  HttpJspBase 源码如下:

如下是 HttpJspBase 的源码内容
  1. /*
  2. * Licensed to the Apache Software Foundation (ASF) under one or more
  3. * contributor license agreements.  See the NOTICE file distributed with
  4. * this work for additional information regarding copyright ownership.
  5. * The ASF licenses this file to You under the Apache License, Version 2.0
  6. * (the "License"); you may not use this file except in compliance with
  7. * the License.  You may obtain a copy of the License at
  8. *
  9. *      http://www.apache.org/licenses/LICENSE-2.0
  10. *
  11. * Unless required by applicable law or agreed to in writing, software
  12. * distributed under the License is distributed on an "AS IS" BASIS,
  13. * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  14. * See the License for the specific language governing permissions and
  15. * limitations under the License.
  16. */
  17. package org.apache.jasper.runtime;
  18. import java.io.IOException;
  19. import jakarta.servlet.ServletConfig;
  20. import jakarta.servlet.ServletException;
  21. import jakarta.servlet.http.HttpServlet;
  22. import jakarta.servlet.http.HttpServletRequest;
  23. import jakarta.servlet.http.HttpServletResponse;
  24. import jakarta.servlet.jsp.HttpJspPage;
  25. import org.apache.jasper.Constants;
  26. import org.apache.jasper.compiler.Localizer;
  27. /**
  28. * This is the super class of all JSP-generated servlets.
  29. *
  30. * @author Anil K. Vijendran
  31. */
  32. public abstract class HttpJspBase extends HttpServlet implements HttpJspPage {
  33.     private static final long serialVersionUID = 1L;
  34.     protected HttpJspBase() {
  35.     }
  36.     @Override
  37.     public final void init(ServletConfig config)
  38.         throws ServletException
  39.     {
  40.         super.init(config);
  41.         jspInit();
  42.         _jspInit();
  43.     }
  44.     @Override
  45.     public String getServletInfo() {
  46.         return Localizer.getMessage("jsp.engine.info", Constants.SPEC_VERSION);
  47.     }
  48.     @Override
  49.     public final void destroy() {
  50.         jspDestroy();
  51.         _jspDestroy();
  52.     }
  53.     /**
  54.      * Entry point into service.
  55.      */
  56.     @Override
  57.     public final void service(HttpServletRequest request, HttpServletResponse response)
  58.         throws ServletException, IOException
  59.     {
  60.         _jspService(request, response);
  61.     }
  62.     @Override
  63.     public void jspInit() {
  64.     }
  65.     public void _jspInit() {
  66.     }
  67.     @Override
  68.     public void jspDestroy() {
  69.     }
  70.     protected void _jspDestroy() {
  71.     }
  72.     @Override
  73.     public abstract void _jspService(HttpServletRequest request,
  74.                                      HttpServletResponse response)
  75.         throws ServletException, IOException;
  76. }
复制代码

而 HttpServlet 是 extends 了 GenericServlet 抽象类,而 GenericServlet 抽象类是 实现了 Servlet 接口的。

所以:一个index_jsp类就是一个Servlet类。总结就是:一个 index.jsp 文件会被翻译为一个 index_jsp.java 类,而 该 翻译的 index_jsp.java类是 继承 了 org.apache.jasper.runtime.HttpJspBase 类的,而  org.apache.jasper.runtime.HttpJspBase 类 是继承了 HttpServlet 类的。这下逻辑就清晰了,JSP 就是 Servlet 。
<ul>JSP 的生命周期和Servlet的生命周期完全相同。完全就是一个东西。没有任何区别。
JSP和servlet一样,都是单例的。(假单例,真单例是:其类的构造器是 private 私有化的,而Servlte 的构造器不是 private 私有化的,是公开的。所以为假单例),想要了解更多的,大家可以移步至:
免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!




欢迎光临 IT评测·应用市场-qidao123.com (https://dis.qidao123.com/) Powered by Discuz! X3.4