JSP的运行原理如下图所示:
下面看看JSP文件在各个阶段的内容。
源文件:
success.jsp
<%@ page contentType="text/html;charset=gb2312"%>
<html>
<head>
<title>登录成功</title>
</head>
<body>
<h2>${sessionScope.userid}您好,欢迎登录网上书店!</h2>
</body>
</html>
与
Servlet
的运行原理不同的是,
JSP
需要先转换成
Java
文件
。
success.jsp
文件被转换成的
Java
文件的内容如下(位于
Tomcat
安装目录下的
work/Catalina/localhost/ch2/org/apache/jsp
文件夹中,
ch2
是我的应用的名字):
package org.apache.jsp;
import javax.servlet.*;
import javax.servlet.http.*;
import javax.servlet.jsp.*;
public final class success_jsp
extends org.apache.jasper.runtime.HttpJspBase
implements org.apache.jasper.runtime.JspSourceDependent {
private static java.util.Vector _jspx_dependants;
public java.util.List getDependants() {
return _jspx_dependants;
}
public void _jspService(HttpServletRequest request, HttpServletResponse response)
throws java.io.IOException, ServletException {
JspFactory _jspxFactory = null;
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;
try {
_jspxFactory = JspFactory.getDefaultFactory();
response.setContentType("text/html;charset=gb2312");
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("/r/n");
out.write("<html>/r/n");
out.write(" <head>/r/n");
out.write(" <title>
登录成功
</title>/r/n");
out.write(" </head>/r/n");
out.write(" <body>/r/n");
out.write(" <h2>");
out.write((java.lang.String) org.apache.jasper.runtime.PageContextImpl.proprietaryEvaluate("${sessionScope.userid}", java.lang.String.class, (PageContext)_jspx_page_context, null, false));
out.write("
您好
,
欢迎登录网上书店
!
</h2>/r/n");
out.write(" </body>/r/n");
out.write("</html>/r/n");
} catch (Throwable t) {
if (!(t instanceof SkipPageException)){
out = _jspx_out;
if (out != null && out.getBufferSize() != 0)
out.clearBuffer();
if (_jspx_page_context != null)
_jspx_page_context.handlePageException(t);
}
} finally {
if (_jspxFactory != null)
_jspxFactory.releasePageContext(_jspx_page_context);
}
}
}
从
JSP
被转换成的
Java
文件可以看出如下几点:
1) JSP
文件中的内容基本都被包含在了
_jspService
方法中,实际上页面执行的过程就是这个方法执行的过程;
2)
页面中显示给用户的
HTML
信息都被转换成了
out.println("XXXX")
的形式;
3)
在
_jspService
方法中有两个参数
request
和
response
,
4) 在方法中生成了如下几个对象:
PageContext pageContext = null;
HttpSession session = null;
ServletContext application = null;
ServletConfig config = null;
JspWriter out = null;
Object page = this;
这就是传说中的内置对象(预定义对象)。
返回给客户端的代码(通过在客户端浏览器可以查看源文件):
<html>
<head>
<title>登录成功</title>
</head>
<body>
<h2>zhangsan您好,欢迎登录网上书店!</h2>
</body>
</html>
在此文件中看不到任何
JSP
的代码,而是纯
HTML
代码。与源文件不同的地方:
n
源文件中的
page
指令没有了
n
源文件中的
${sessionScope.userid}没有了,而使用zhangsan代替了原来的表达式。
浏览器把这段HTML代码解析成界面显示给用户。
这就是从你编写的JSP文件到客户端看到的结果的转换过程。