• 为什么JSP的内置对象不需要声明


    本文将通过对一个JSP运行过程的剖析,深入JSP运行的内幕,并从全新的视角阐述一些JSP中的技术要点。

    HelloWorld.jsp

    我们以Tomcat 4.1.17服务器为例,来看看最简单的HelloWorld.jsp是怎么运行的。

    代码清单1:HelloWorld.jsp

    HelloWorld.jsp 
    <% 
    String message = "Hello World!"; 
    %> 
    <%=message%>

    这个文件非常简单,仅仅定义了一个String的变量,并且输出。把这个文件放到Tomcat的webappsROOT目录下,启动Tomcat,在浏览器中访问 http://localhost:8080/HelloWorld.jsp ,浏览器中的输出为“HelloWorld!”

      让我们来看看Tomcat都做了什么。转到Tomcat的workStandalonelocalhost\_目录下,可以找到如下的HelloWorld_jsp.java,这个文件就是Tomcat解析HelloWorld.jsp时生成的源文件:

      代码清单2:HelloWorld_jsp.java

    package org.apache.jsp;

    import javax.servlet.*; 
    import javax.servlet.http.*; 
    import javax.servlet.jsp.*; 
    import org.apache.jasper.runtime.*;

    public class HelloWorld_jsp extends HttpJspBase { 
    ...... 
    public void _jspService(HttpServletRequest request, 
    HttpServletResponse response)throws java.io.IOException, ServletException 

    JspFactory _jspxFactory = null; 
    javax.servlet.jsp.PageContext pageContext = null; 
    HttpSession session = null; 
    ServletContext application = null; 
    ServletConfig config = null; 
    JspWriter out = null; 
    Object page = this; 
    JspWriter _jspx_out = null;

    try { 
    _jspxFactory = JspFactory.getDefaultFactory(); 
    response.setContentType("text/html;charset=ISO-8859-1"); 
    pageContext = _jspxFactory.getPageContext(this, request, response,null, true, 8192, true); 
    application = pageContext.getServletContext(); 
    config = pageContext.getServletConfig(); 
    session = pageContext.getSession(); 
    out = pageContext.getOut(); 
    _jspx_out = out;

    String message = "Hello World!"; 
    out.print(message); 
    } catch (Throwable t) { 
    out = _jspx_out; 
    if (out != null && out.getBufferSize() != 0) 
    out.clearBuffer(); 
    if (pageContext != null) pageContext.handlePageException(t); 
    } finally { 
    if (_jspxFactory != null) _jspxFactory.releasePageContext(pageContext); 


    }

    从上面可以看出,HelloWorld.jsp在运行时首先解析成一个Java类HelloWorld_jsp.java,该类继承于org.apache.jasper.runtime.HttpJspBase基类,HttpJspBase实现了HttpServlet接口。可见,JSP在运行前首先将编译为一个Servlet,这就是理解JSP技术的关键。

      我们还知道JSP页面中内置了几个对象,如pageContext、application、config、page、session、out等,你可能会奇怪,为什么在JSP中的代码片断中可以直接使用这些内置对象。观察_jspService()方法,实际上这几个内置对象就是在这里定义的。在对JSP文件中的代码片断进行解析之前,先对这几个内置对象进行初始化。

      首先,调用JspFactory的getDefaultFactory()方法获取容器实现(本文中指Tomcat 4.1.17)的一个JspFactory对象的引用。JspFactory是javax.servlet.jsp包中定义的一个抽象类,其中定义了两个静态方法set/getDefaultFactory()。set方法由JSP容器(Tomcat)实例化该页面Servlet(即HelloWorld_jsp类)的时候置入,所以可以直接调用JspFactory.getDefaultFactory()方法得到这个JSP工厂的实现类。Tomcat是调用org.apache.jasper.runtime.JspFactoryImpl类。

      然后,调用这个JspFactoryImpl的getPageContext()方法,填充一个PageContext返回,并赋给内置变量pageConext。其它内置对象都经由该pageContext得到。具体过程见上面的代码,这里不再赘述。该页面Servlet的环境设置完毕,开始对页面进行解析。HelloWorld.jsp页面仅仅定义了一个String变量,然后直接输出。解析后的代码如下:

      代码清单3:JSP页面解析后的代码片断

    String message = "Hello World!"; 
    out.print(message);

    另:

    JSP声明标记<%!       %>翻译成Servlet中类的成员变量或者成员函数

    JSP表达式标记<%=  message   %>也会插入_jspService()方法中,(意味着<%=  message   %>中也能使用内置对象,应该是吧)被翻译成out.print(message);

  • 相关阅读:
    数据库
    poj上关于回文的题目
    最长上升子序列
    [CodeForces]914D Bash and a Tough Math Puzzle
    [HAOI2011]problem a
    Arc123 D
    [Cnoi2020]线性生物
    [USACO17FEB]Why Did the Cow Cross the Road III P
    ABC 210
    CF1111D Destroy the Colony
  • 原文地址:https://www.cnblogs.com/gaoxiangde/p/4379857.html
Copyright © 2020-2023  润新知