JSP-原理详细分析+源码查看

本文深入探讨了JSP(JavaServer Pages)的工作原理及执行流程,解释了JSP如何在首次访问时转换为Servlet,并详细展示了从JSP源文件到生成的Java代码的全过程。通过对比两个JSP页面的转换实例,揭示了JSP本质为特殊Servlet的特点。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

JSP

JSP:Java Server Page,Java服务器端页面,和Servlet一样,用于动态web技术。

JSP页面的展示就是HTML和Java代码组成的页面。

JSP中可以直接写Java代码,既能满足页面的显示,还能在里面写处理业务逻辑的Java代码。看似是一个优点,但也是它的缺点,这样的jsp文件,其中的代码非常的杂乱,对于后期管理维护就比较困难。

JSP原理

JSP执行过程

当某个JSP页面第一次被访问时,它就会进行如下步骤:
在这里插入图片描述

准备两个JSP页面如下:

index.jsp

<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
    <title>首页</title>
</head>
<body>
    这是首页

    <%
        //向控制台打印数据
        System.out.println("hello jsp!-index");
    %>

    <hr>

    <%
        out.print("index.jsp页面");
    %>

</body>
</html>

href.jsp

<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
    <title>首页</title>
</head>
<body>
    这是首页

    <%
        int a = 1;
        int b = 10;

        //向控制台打印数据
        System.out.println("hello jsp!——href"+(a+b));
    %>

    <hr>

    <%
        out.print("href.jsp页面");
    %>

    <table border="1px">
        <thead>
        <tr>
            <th>#</th>
            <th>First</th>
            <th>Last</th>
            <th>Handle</th>
        </tr>
        </thead>
        <tbody>
        <tr>
            <th>1</th>
            <td>Mark</td>
            <td>Otto</td>
            <td>@mdo</td>
        </tr>
        <tr>
            <th>2</th>
            <td>Jacob</td>
            <td>Thornton</td>
            <td>@fat</td>
        </tr>
        <tr>
            <th>3</th>
            <td>Larry</td>
            <td>the Bird</td>
            <td>@twitter</td>
        </tr>
        </tbody>
    </table>

</body>
</html>

在IDEA中运行,我们打开电脑用户目录,找到当前用户目录,然后:
在这里插入图片描述
我们可以发现这下面都是IDEA运行Tomcat的工作空间,我们在这里面可以看到我们的web项目,点击进入我们的对应项目,然后再打开如下:
在这里插入图片描述
由于博主设置了Tomcat启动完成自动打开浏览器访问首页,所以已经生成了对应的java和class文件,我们也可以发现还没生成href.jsp的对应文件,当我们访问一下href.jsp页面,该路径下就会生成对应的文件。
在这里插入图片描述
我们打开两个java文件对比:

index.java

/*
 * Generated by the Jasper component of Apache Tomcat
 * Version: Apache Tomcat/9.0.16
 * Generated at: 2020-02-28 12:09:37 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.
 */

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

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

  private static final JspFactory _jspxFactory =
          JspFactory.getDefaultFactory();

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

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

  private static final java.util.Set<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<String, Long> getDependants() {
    return _jspx_dependants;
  }

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

  public java.util.Set<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 HttpServletRequest request, final HttpServletResponse response)
      throws java.io.IOException, ServletException {

    if (!DispatcherType.ERROR.equals(request.getDispatcherType())) {
      final 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 PageContext pageContext;
    HttpSession session = null;
    final ServletContext application;
    final ServletConfig config;
    JspWriter out = null;
    final Object page = this;
    JspWriter _jspx_out = null;
    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("<html>\r\n");
      out.write("<head>\r\n");
      out.write("    <title>首页</title>\r\n");
      out.write("</head>\r\n");
      out.write("<body>\r\n");
      out.write("    这是首页\r\n");
      out.write("\r\n");
      out.write("    ");

        //向控制台打印数据
        System.out.println("hello jsp!-index");
    
      out.write("\r\n");
      out.write("\r\n");
      out.write("    <hr>\r\n");
      out.write("\r\n");
      out.write("    ");

        out.print("index.jsp");
    
      out.write("\r\n");
      out.write("\r\n");
      out.write("</body>\r\n");
      out.write("</html>\r\n");
    } catch (Throwable t) {
      if (!(t instanceof 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);
    }
  }
}

href.java

/*
 * Generated by the Jasper component of Apache Tomcat
 * Version: Apache Tomcat/9.0.16
 * Generated at: 2020-02-28 12:10:08 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.
 */

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

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

  private static final JspFactory _jspxFactory =
          JspFactory.getDefaultFactory();

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

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

  private static final java.util.Set<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<String, Long> getDependants() {
    return _jspx_dependants;
  }

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

  public java.util.Set<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 HttpServletRequest request, final HttpServletResponse response)
      throws java.io.IOException, ServletException {

    if (!DispatcherType.ERROR.equals(request.getDispatcherType())) {
      final 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 PageContext pageContext;
    HttpSession session = null;
    final ServletContext application;
    final ServletConfig config;
    JspWriter out = null;
    final Object page = this;
    JspWriter _jspx_out = null;
    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("<html>\r\n");
      out.write("<head>\r\n");
      out.write("    <title>首页</title>\r\n");
      out.write("</head>\r\n");
      out.write("<body>\r\n");
      out.write("    这是首页\r\n");
      out.write("\r\n");
      out.write("    ");

        int a = 1;
        int b = 10;

        //向控制台打印数据
        System.out.println("hello jsp!-href"+(a+b));
    
      out.write("\r\n");
      out.write("\r\n");
      out.write("    <hr>\r\n");
      out.write("\r\n");
      out.write("    ");

        out.print("href.jsp");
    
      out.write("\r\n");
      out.write("\r\n");
      out.write("    <table border=\"1px\">\r\n");
      out.write("        <thead>\r\n");
      out.write("        <tr>\r\n");
      out.write("            <th>#</th>\r\n");
      out.write("            <th>First</th>\r\n");
      out.write("            <th>Last</th>\r\n");
      out.write("            <th>Handle</th>\r\n");
      out.write("        </tr>\r\n");
      out.write("        </thead>\r\n");
      out.write("        <tbody>\r\n");
      out.write("        <tr>\r\n");
      out.write("            <th>1</th>\r\n");
      out.write("            <td>Mark</td>\r\n");
      out.write("            <td>Otto</td>\r\n");
      out.write("            <td>@mdo</td>\r\n");
      out.write("        </tr>\r\n");
      out.write("        <tr>\r\n");
      out.write("            <th>2</th>\r\n");
      out.write("            <td>Jacob</td>\r\n");
      out.write("            <td>Thornton</td>\r\n");
      out.write("            <td>@fat</td>\r\n");
      out.write("        </tr>\r\n");
      out.write("        <tr>\r\n");
      out.write("            <th>3</th>\r\n");
      out.write("            <td>Larry</td>\r\n");
      out.write("            <td>the Bird</td>\r\n");
      out.write("            <td>@twitter</td>\r\n");
      out.write("        </tr>\r\n");
      out.write("        </tbody>\r\n");
      out.write("    </table>\r\n");
      out.write("\r\n");
      out.write("</body>\r\n");
      out.write("</html>\r\n");
    } catch (Throwable t) {
      if (!(t instanceof 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);
    }
  }
}

我们发现两个java文件中仅仅有以下不一致:
在这里插入图片描述
我们发现它们都继承了一个HttpJspBase类,透过API发现它实质上还是一个Servlet,它设置了响应回去的数据时一个html,将jsp中的页面代码全部以字符流的形式写回了,嵌入的java代码直接按顺序放在了里面。
在这里插入图片描述
这就是jsp的本质,它就是一个特殊的Servlet。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值