原创

jsp 执行原理

JSP(全称JavaServer Pages)是由Sun Microsystems公司主导创建的一种动态网页技术标准。
JSP部署于网络服务器上,可以响应客户端发送的请求,并根据请求内容动态地生成HTML、XML或其他格式文档的Web网页,
然后返回给请求者。JSP技术以Java语言作为脚本语言,为用户的HTTP请求提供服务,
并能与服务器上的其它Java程序共同处理复杂的业务需求。

JSP将Java代码和特定变动内容嵌入到静态的页面中,实现以静态页面为模板,
动态生成其中的部分内容。JSP引入了被称为“JSP动作”的XML标签,用来调用内建功能。另外
,可以创建JSP标签库,然后像使用标准HTML或XML标签一样使用它们。标签库能增强功能和服务器性能
,而且不受跨平台问题的限制。JSP文件在运行时会被其编译器转换成更原始的Servlet代码。
JSP编译器可以把JSP文件编译成用Java代码写的Servlet,
然后再由Java编译器来编译成能快速执行的二进制机器码,也可以直接编译成二进制码。

运行原理
1.当jsp页面被用户访问请求时,web容器会将把该访问请求交给JSP引擎去处理。
Tomcat中的jsp引擎就是一个Servlet程序,它负责解释和执行JSP页面

2.每个jsp页面在第一次被访问时,jsp引擎先将它翻译成一个Servlet源程序,
接着再把这个Servlet源程序编译成Servlet的class类文件,然后再由web容器像调用
普通Servlet程序一样的方式来装载和解释执行这个由JSP页面翻译成的Servlet程序

3.Tomcat把为jsp页面创建的Servlet源文件和class类文件放置在"apache-tomcat-版本\work\Catalina\localhost\项目名称"目录中,
Tomcat将jsp页面翻译成的Servlet的包名为org.apache.jsp

示例

原代码 index.jsp

<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<%@ page isELIgnored="false" %>
<html>
<head>
    <title>index</title>
</head>
<body>
    Hello Word!
</body>
</html>
被jsp引擎转换后的代码 index_jsp.java

package org.apache.jsp;

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 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 {

final java.lang.String _jspx_method = request.getMethod();
if (!"GET".equals(_jspx_method) && !"POST".equals(_jspx_method) && !"HEAD".equals(_jspx_method) && !javax.servlet.DispatcherType.ERROR.equals(request.getDispatcherType())) {
  response.sendError(HttpServletResponse.SC_METHOD_NOT_ALLOWED, "JSPs only permit GET POST or HEAD");
  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("\n");
  out.write("\n");
  out.write("\n");
  out.write("<html>\n");
  out.write("<head>\n");
  out.write("    <title>index</title>\n");
  out.write("</head>\n");
  out.write("<body>\n");
  out.write("    Hello Word!\n");
  out.write("</body>\n");
  out.write("</html>\n");
} 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);
    }
 }
}

执行过程
jsp的执行过程主要分为以下几点:

1.客户端发出请求
2.Web容器将jsp转译成Servlet源代码
3.Web容器将产生的源代码编译成class文件
4.Web容器加载编译后的代码并执行
5.把执行结果响应至客户端

总结
JSP执行过程:

1.首先,客户端发出request请求,请求访问jsp网页
2.接着,jsp引擎将要访问的.jsp文件转译成Servlet的源代码.java文件
3.然后,将产生的Servlet的源代码.java文件经过编译,生成.class文件,并加载到内存执行
4.最后把结果响应给客户端

执行JSP网页文件时,需要经过两个时期:转译时期(TranslationTime)和请求时期(RequestTime)

转译时期:jsp转译成Servlet类(.class文件)
请求时期:Servlet类(.class文件)执行后,响应结果至客户端

转译期间主要做了两件事情:

1.将jsp网页转译为Servlet源代码(.java),此段称为转译时期(Translation time)
2.将Servlet源代码(.java)编译成Servlet类(.class),此阶段称为编译时期(Compilation time)

其实,jsp就是一个Servlet
开发者手册
  • 你若安好便是晴天
  • 2020-09-28 10:34:56.713

评论区