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

HelloWorld.jsp

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

代码清单1:HelloWorld.jsp

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

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

  让我们来看看Tomcat都做了什么。转到Tomcat的\work\Standalone\localhost\_目录下,可以找到如下的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);

为什么JSP的内置对象不需要声明的更多相关文章

  1. jsp的内置对象

    JSP内置对象即无需声明就可以直接使用的对象实例,在实际的开发过程中,比较常用的JSP对象有request,response,session,out和application等,笔者在本文章中将简单介绍 ...

  2. JSP的内置对象以及作用域。

    最近在面试,一些基础的问题总是会被问到,虽然是基础,但是有些东西在工作中用的少,所以就有些记不清了,在面试的时候更因为紧张很容易造成原先知道的知识也会突然忘了的情况发生.所以在重新组织一下jsp的内置 ...

  3. JSP的内置对象(上)

    1.JSP内置对象的概念:JSP的内置对象时Web容器所创建的一组对象,不使用new关键字就可以使用的内置对象 2.JSP九大内置对象内置对象:out ,request ,response ,sess ...

  4. JSP&EL 内置对象

    JSP&EL 内置对象 转载▼   具体的JSP和El中的内置对象见下表,由于我写在了excel中,也不知道怎么把excel发出来,就截了图. 相关问题: Q1: JSP:EL中 pageCo ...

  5. struts访问jsp api内置对象的集中方式

    1 default-action-ref元素改元素用来配置默认的action,如果struts找不到对应的action,就会调用这个默认的action 2 dmi处理方式是通过请求action中的一个 ...

  6. JSP的执行原理、JSP的内置对象、四大作用域解析、MVC模式理解>从零开始学JAVA系列

    目录 JSP的执行原理.JSP的内置对象.四大作用域解析.MVC模式理解 JSP的执行原理 这里拿一个小例子来解析JSP是如何被访问到的 首先将该项目部署到tomcat,并且通过tomcat启动 通过 ...

  7. 什么是jsp?jsp的内置对象有哪些?

    这里是修真院前端小课堂,每篇分享文从 [背景介绍][知识剖析][常见问题][解决方案][编码实战][扩展思考][更多讨论][参考文献] 八个方面深度解析前端知识/技能,本篇分享的是: [什么是jsp? ...

  8. 菜鸟日记之JSP二 内置对象的理解

    ·最近学习JSP了,对编程和网络又有了一些理解.无论是现实中人与人的交流,还是网络世界的接触,都是在相互表达自己的意思让别人知道,并理解对方的信息.然后我们知道的事情不断的变多,会又交杂出新的内容,不 ...

  9. JSP (tomcat 内置对象)

    1.内置对象:    request: 方法:getParameter("txtName"):获取和页面上的name属性对象的value值       返回String       ...

随机推荐

  1. php新版本废弃 preg_replace /e 修饰符

    php新版本废弃 preg_replace /e 修饰符 分类: PHP -- : 3531人阅读 评论() 收藏 举报 php正则 最近服务器php版本升级到了 5.6 发现出了很多警告 [php] ...

  2. linux学习笔记32---命令ping和telnet

    Linux系统的ping命令是常用的网络命令,它通常用来测试与目标主机的连通性,我们经常会说“ping一下某机器,看是不是开着”.不能打开网页时会说“你先ping网关地址192.168.1.1试试”. ...

  3. (译)Getting Started——1.2.3 Defining the Interaction(定义交互)

    IOS应用编程是基于事件驱动的编程.也就是说,应用的流程由事件来决定:事件包括系统事件和用户操作.界面上用户执行的操作会触发事件.这些事件导致应用的逻辑被执行,数据被操作.应用对用户动作的响应反映在界 ...

  4. python from import 自定义模块

    from douban250.items import Douban250Item python import 自定义模块 (1)主程序与模块程序在同一目录下: 如下面程序结构: `-- src    ...

  5. centos6.5安装apache2

    参考 http://my.oschina.net/u/593517/blog/340289 http://blog.csdn.net/hkmaike/article/details/9732177

  6. 【Debian】install

    n年前的报废台式机实在不能忍受xp的速度,果断装Linux近期家里的小本装了Ubuntu14.04 ,实在不习惯最新的图形界面.装个debian试试吧. 1.专门弄一个空白分区2.官网下载debian ...

  7. hdu 4067(最小费用最大流)

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=4067 思路:很神奇的建图,参考大牛的: 如果人为添加t->s的边,那么图中所有顶点要满足的条件都 ...

  8. poj 3249(bfs+dp或者记忆化搜索)

    题目链接:http://poj.org/problem?id=3249 思路:dp[i]表示到点i的最大收益,初始化为-inf,然后从入度为0点开始bfs就可以了,一开始一直TLE,然后优化了好久才4 ...

  9. RedMine Email notifications configure for MS Exchange

    Boss需要用到RedMine(project management) open source. 由于不熟悉MS的SMTP服务,BOSS说他配好了,然后配置到Email notification时候, ...

  10. dubbo框架的介绍,应用

    http://www.cnblogs.com/Javame/p/3632473.html