0
点赞
收藏
分享

微信扫一扫

JSP 原理


一、JSP原理介绍

 

jsp是运行在web服务端的JAVA展现技术,JSP的实质是一个servlet,也就是一个java文件,在运行的时候也要被JVM编译和装载

 


 二、Jsp运行原理

 

在一个JSP文件第一次被请求时,JSP引擎把该JSP文件转换成为一个Servlet。而这个引擎本身也是一个Servlet。JSP的运行过程如下所示:
(1)JSP引擎先把该JSP文件转换成一个Java源文件(Servlet),在转换时如果发现JSP文件有任何语法错误,转换过程将中断,并向服务端和客户端输出出错信息。
(2)如果转换成功,JSP引擎用javac把该Java源文件编译成相应的class文件。
(3)创建一个该Servlet(JSP页面的转换结果)的实例,该Servlet的jspInit()方法被执行,jspInit()方法在Servlet的生命周期中只被执行一次。
(4)jspService()方法被调用来处理客户端的请求。对每一个请求,JSP引擎创建一个新的线程来处理该请求。如果有多个客户端同时请求该JSP文件,则JSP引擎会创建多个线程。每个客户端请求对应一个线程。以多线程方式执行可以大大降低对系统的资源需求,提高系统的并发量及响应时间。但不过也应该注意多线程的编程限制,由于该Servlet始终驻于内存,所以响应是非常快的。
(5)如果.jsp文件被修改了,服务器将根据设置决定是否对该文件重新编译,如果需要重新编译,则将编译结果取代内存中的Servlet,并继续上述处理过程。
(6)虽然JSP效率很高,但在第一次调用时由于需要转换和编译而有一些轻微的延 迟。此外,在任何时候如果由于系统资源不足的原因,JSP引擎将以某种不确定的方式将Servlet从内存中移去。当这种情况发生时jspDestroy()方法首先被调用。
(7)然后Servlet实例便被标记加入“垃圾收集”处理。可在jspInit()中进行一些初始化工作,如建立与数据库的连接,或建立网络连接,从配置文件中取一些参数等,在jspDestory()中释放相应的资源。

 

三、jsp原理图

 

 

其步骤如下:
    1.jsp引擎将jsp文件翻译为Servlet源程序;
    2.之后又将Servlet源程序编译为.class类文件;
其中:
     1.Jsp引擎是通常一个Servlet程序,Tomcat中的jsp引擎就是org.apache.jasper.servlet.JspServlet;
     2.在Tomcat中编译的源文件和.class文件放在”[TOMCAT_HOME]\work\Catalina\[主机名,如localhost]\应用程序名称” 目录下;
     3.默认情况下,第一次访问某jsp文件时,才对该jsp文件进行翻译、编译,所以较慢。不过在以后的访问中将不会在出现该情况,因为已经被编译过了,呵呵。

 

 

四、jsp相关类

 

4.1 jsp相关uml图

 

 

   其中,org.apache.jsp.index_jsp是tomcat将index.jsp转化为servlet源代码后的结果

JSP 原理_apache

。其代码可以在如下目录中看到(当然,你要首先访问index.jsp才会翻译,编译)

 

 

4.2 具体类源代码

 

 

4.2.1 JspPage源代码

 

 


Java代码 

package
  
import
  
public abstract interface JspPage extends
{  
public abstract void
  
public abstract void
}

 

4.2.2 HttpJspPage源代码

 

 


Java代码 

package
  
import
import
import
import
  
public abstract interface HttpJspPage extends
{  
public abstract void
throws
}

 

4.2.2 HttpJspBase 源代码

 

    和HttpJspPage名称虽然很香精 ,但已经位于不同的包中了。下面的源代码是我从tomcat6中的jasper.jar拉出来的。

 

 


Java代码 

package
  
import
import
import
import
import
import
import
import
  
public abstract class HttpJspBase extends
implements
{  
public final void
throws
  {  
super.init(config);  
    jspInit();  
    _jspInit();  
  }  
  
public
return Localizer.getMessage("jsp.engine.info");  
  }  
  
public final void
    jspDestroy();  
    _jspDestroy();  
  }  
  
public final void
throws
  {  
    _jspService(request, response);  
  }  
  
public void
  {  
  }  
  
public void
  {  
  }  
  
public void
  {  
  }  
  
protected void
  {  
  }  
  
public abstract void
throws
}

 

4.2.2 JspSourceDependent源代码

 

 

Java代码 


package
  
public abstract interface
{  
public abstract
}

4.2.2  org.apache.jsp.index_jsp 源代码

 

       上面提到过org.apache.jsp.index_jsp是tomcat将index.jsp转化为servlet的源代码。

 

 

 


Java代码 

package
  
import
import
import
import
  
public final class index_jsp extends
implements
  
private static final
  
private static
  
private
private
  
public
return
  }  
  
public void
    _el_expressionfactory = _jspxFactory.getJspApplicationContext(getServletConfig().getServletContext()).getExpressionFactory();  
class.getName());  
  }  
  
public void
  }  
  
public void
throws
  
null;  
null;  
null;  
null;  
null;  
this;  
null;  
null;  
  
  
try
"text/html;charset=GB18030");  
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;  
  
'\r');  
'\n');  
  
String path = request.getContextPath();  
String basePath = request.getScheme()+"://"+request.getServerName()+":"+request.getServerPort()+path+"/";  
  
"\r\n");  
"\r\n");  
"<!DOCTYPE HTML PUBLIC \"-//W3C//DTD HTML 4.01 Transitional//EN\">\r\n");  
"<html>\r\n");  
"  <head>\r\n");  
"    <base href=\"");  
      out.print(basePath);  
"\">\r\n");  
"    \r\n");  
"    <title>My JSP 'index.jsp' starting page</title>\r\n");  
"\t<meta http-equiv=\"pragma\" content=\"no-cache\">\r\n");  
"\t<meta http-equiv=\"cache-control\" content=\"no-cache\">\r\n");  
"\t<meta http-equiv=\"expires\" content=\"0\">    \r\n");  
"\t<meta http-equiv=\"keywords\" content=\"keyword1,keyword2,keyword3\">\r\n");  
"\t<meta http-equiv=\"description\" content=\"This is my page\">\r\n");  
"\t<!--\r\n");  
"\t<link rel=\"stylesheet\" type=\"text/css\" href=\"styles.css\">\r\n");  
"\t-->\r\n");  
"  </head>\r\n");  
"  \r\n");  
"  <body>\r\n");  
"    This is my JSP page. <br>\r\n");  
"  </body>\r\n");  
"</html>\r\n");  
catch
if (!(t instanceof
        out = _jspx_out;  
if (out != null && out.getBufferSize() != 0)  
try { out.clearBuffer(); } catch
if (_jspx_page_context != null) _jspx_page_context.handlePageException(t);  
      }  
finally
      _jspxFactory.releasePageContext(_jspx_page_context);  
    }  
  }  
}

 

其对应的index.jsp为

 

 


Html代码 

<%@ page language="java" import="java.util.*" pageEncoding="GB18030"%>
<%  
String path = request.getContextPath();  
String basePath = request.getScheme()+"://"+request.getServerName()+":"+request.getServerPort()+path+"/";  
%>
  
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<head>
<base href="<%=basePath%>">
      
<title>My JSP 'index.jsp' starting page</title>
<meta http-equiv="pragma" content="no-cache">
<meta http-equiv="cache-control" content="no-cache">
<meta http-equiv="expires" content="0">
<meta http-equiv="keywords" content="keyword1,keyword2,keyword3">
<meta http-equiv="description" content="This is my page">
<!--
    <link rel="stylesheet" type="text/css" href="styles.css">
    -->
</head>
    
<body>
<br>
</body>
</html>

4.2.3 九大隐藏对象

 

    从jsp转换的源码中,很容易的就可以发现了传说中的9大jsp内置隐藏对象中的8个。如下:

 

 


Java代码 

PageContext pageContext = null;  
HttpSession session = null;  
ServletContext application = null;  
ServletConfig config = null;  
JspWriter out = null;  
Object page = this;  
JspWriter _jspx_out = null;  
PageContext _jspx_page_context = null;

 

    至于第9个,只有page指令被设置为:

 

 


Html代码 


<%@ page isErrorPage="true" %>

    才会出现:

 

 


Java代码 


Throwable exception = org.apache.jasper.runtime.JspRuntimeLibrary.getThrowable(request);

 

举报

相关推荐

0 条评论