JSP的運行原理


  昨天花了很多時間弄清了JSP的運行原理,總的來說,JSP就是封裝好了的Servlet。不信的話請往下看:

  首先你得弄清楚為什么后綴名為jsp的文件就能運行,原因很簡單,因為Tomcat已經配置好了,配置文件是Tomcat的conf目錄下的web.xml,打開該文件找到如下代碼:

1     <servlet-mapping>
2         <servlet-name>jsp</servlet-name>
3         <url-pattern>*.jsp</url-pattern>
4     </servlet-mapping>
5     <servlet-mapping>
6         <servlet-name>jsp</servlet-name>
7         <url-pattern>*.jspx</url-pattern>
8     </servlet-mapping>

這里就是Tomcat配置好的,由上面的URL可以知道,后綴名無論是jsp還是jspx都可以運行,甚至還可以自己更改,比如把*.jspx改成*.aaa,在Tomcat下的aaa文件就能被運行。這是問什么呢?<url-pattern>*.jsp</url-pattern>這一句就是配置URL的,只要URL中輸入的是jsp文件,就會通過<servlet-name>jsp</servlet-name>,找到名為jsp的servlet,web.xml中還有這么一段代碼:

 1 <servlet>
 2         <servlet-name>jsp</servlet-name>
 3         <servlet-class>org.apache.jasper.servlet.JspServlet</servlet-class>
 4         <init-param>
 5             <param-name>fork</param-name>
 6             <param-value>false</param-value>
 7         </init-param>
 8         <init-param>
 9             <param-name>xpoweredBy</param-name>
10             <param-value>false</param-value>
11         </init-param>
12         <load-on-startup>3</load-on-startup>
13 </servlet>

然后由servlet名找到servlet-class,即org.apache.jasper.servlet.JspServlet,JspServlet就是一個Servlet,它繼承了HttpServlet,所以jsp文件能夠被運行。JspServlet類可以到Tomcat源文件里面去找,這里不再詳講。

  然后再講一講JSP的運行過程,當jsp文件第一次被運行時它會被編譯成一個java文件,然后再將這個java文件編譯成class文件(這些文件放在tomcat的work目錄下)。要注意的是一個jsp文件只能被編譯一次,也就是第一次運行的時候被編譯,以后只要這個Jsp文件沒有修改就不會再編譯了。比如說在tomcat里面新建了一個demo.jsp,當這個jsp被運行的時候就會被編譯成demo_jsp.java和demo_jsp.class。demo_jsp這個類繼承了HttpJspBase,HttpJspBase也是一個servlet,它繼承了HttpServlet,它的代碼如下:

 1 package org.apache.jasper.runtime;
 2 
 3 import java.io.IOException;
 4 
 5 import javax.servlet.ServletConfig;
 6 import javax.servlet.ServletException;
 7 import javax.servlet.http.HttpServlet;
 8 import javax.servlet.http.HttpServletRequest;
 9 import javax.servlet.http.HttpServletResponse;
10 import javax.servlet.jsp.HttpJspPage;
11 import javax.servlet.jsp.JspFactory;
12 
13 import org.apache.jasper.compiler.Localizer;
14 
15 /**
16  * This is the super class of all JSP-generated servlets.
17  *
18  * @author Anil K. Vijendran
19  */
20 public abstract class HttpJspBase 
21     extends HttpServlet 
22     implements HttpJspPage 
23         
24     
25 {
26     
27     protected HttpJspBase() {
28     }
29 
30     public final void init(ServletConfig config) 
31     throws ServletException 
32     {
33         super.init(config);
34     jspInit();
35         _jspInit();
36     }
37     
38     public String getServletInfo() {
39     return Localizer.getMessage("jsp.engine.info");
40     }
41 
42     public final void destroy() {
43     jspDestroy();
44     _jspDestroy();
45     }
46 
47     /**
48      * Entry point into service.
49      */
50     public final void service(HttpServletRequest request, HttpServletResponse response) 
51     throws ServletException, IOException 
52     {
53         _jspService(request, response);
54     }
55     
56     public void jspInit() {
57     }
58 
59     public void _jspInit() {
60     }
61 
62     public void jspDestroy() {
63     }
64 
65     protected void _jspDestroy() {
66     }
67 
68     public abstract void _jspService(HttpServletRequest request, 
69                      HttpServletResponse response) 
70     throws ServletException, IOException;
71 }

HttpJspBase這個類重寫了HttpServlet的service方法,而沒有重寫doGet()或者doPost()(通過URL運行的默認是GET方式提交),因為首先調用的是service方法,而這個方法里面又調用了_jspService()方法,HttpJspBase類中_jspService()方法是抽象方法,但是demo1_jsp這個類重寫了這個方法,所以就調用了demo1_jsp類中的_jspService()方法。以上就足以證明,JSP就是servlet了。

  JSP中可以直接寫HTML標簽,又可以直接嵌入JAVA程序,java程序段寫在<% %>或者<%! %>里面,但是寫在<% %>和寫在<%! %>里又有什么不同呢?<%! %>里面是定義變量或者函數用的,寫在這里面的會定義成demo1_jsp類中的成員變量或成員函數。而寫在<% %>里面的則在_jspService()方法里直接輸出了。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM