JSP是一种建立在Servlet规范提供的功能之上的动态网页技术,和ASP类似,它们都是在通常的网页文件中嵌入脚本代码,用于产生动态内容,不过JSP文件中嵌入的是Java代码和JSP标记。
JSP文件在用户第一次请求时,会被编译成Servlet,然后由这个Servlet处理用户的请求,所以JSP也可以看成是运行时的Servlet。既然JSP也是Servlet,那么我们为什么还要使用JSP呢?或者说JSP和Servlet的区别是什么呢?
? Servlet是Java对CGI的回应。它们在服务器上执行和解释浏览器的请求,承担客户端和其他应用程序之间的中间层的角色。Servlet主要是把动态的内容混合到静态的内容中以产生HTML。
? JSP页面在HTML元素中嵌入Java脚本代码和JSP标记,使得文件长度变短,格式更加清晰。另一方面,JSP把静态和动态的内容分离开来,实现了内容和表示的分离。
? 使用JSP,不需要单独配置每一个文件,只要扩展名是.jsp,JSP容器(也是Servlet容器)就会自动识别,将其转换为Servlet为客户端服务。术语Web容器和JSP容器是同义的。
我们先来看一个简单的JSP文件,如例12-1所示。
例12-1 hello.jsp
<head><title>Hello</title></head>
</html>
<body>
<%
out.println("Hello World!");
%>
</body>
这个JSP页面向客户端输出“Hello World!”。我们把这个页面复制到%CATALINA_HOME%/webapps /ROOT目录下,启动Tomcat,打开浏览器,在地址栏中输入http://localhost:8080/hello.jsp,看到“Hello World!”的输出后,读者可以转到%CATALINA_HOME%/work/Catalina/localhost目录,在这个目录下,有一些读者熟悉的目录,这些目录都是以前面章节的Web应用程序的上下文路径命名的,其中“_”目录对应的是ROOT目录。在_/org/apache/jsp目录下,可以看到两个文件:“hello_jsp.java”和“hello_jsp.class”,这两个文件就是在我们访问hello.jsp文件时,由JSP容器生成的,整个过程如图12-1所示。
JSP容器管理JSP页面生命周期的两个阶段:转换阶段(translation phase)和执行阶段(execution phase)。当有一个对JSP页面的客户请求到来时,JSP容器检验JSP页面的语法是否正确,将JSP页面转换为Servlet源文件,然后调用javac工具类编译Servlet源文件生成字节码文件,这一阶段是转换阶段。接下来,Servlet容器加载转换后的Servlet类,实例化一个对象处理客户端的请求,在请求处理完成后,响应对象被JSP容器接收,容器将HTML格式的响应信息发送到客户端,这一阶段是执行阶段。
从整个过程中我们可以知道,当第一次加载JSP页面时,因为要将JSP文件转换为Servlet类,所以响应速度较慢。当再次请求时,JSP容器就会直接执行第一次请求时产生的Servlet,而不会再重新转换JSP文件,所以其执行速度和原始的Servlet执行速度几乎就相同了。在JSP执行期间,JSP容器会检查JSP文件,看是否有更新或修改。如果有更新或修改,JSP容器会再次编译JSP或Servlet;如果没有更新或修改,就直接执行前面产生的Servlet,这也是JSP相对于Servlet的好处之一。
下面我们看一下JSP容器在后台针对hello.jsp生成的Servlet源文件。虽然JSP页面转换为Servlet是在后台由JSP容器自动进行的,但通过阅读JSP容器生成的源代码来了解JSP背后运行的机制,将有助于我们更好地理解JSP页面的运行,编写更加健壮、安全的JSP页面。
hello_jsp.java的完整代码如例12-2所示。
例12-2 hello_jsp.java
1.package org.apache.jsp;
2.
3.import javax.servlet.*;
4.import javax.servlet.http.*;
5.import javax.servlet.jsp.*;
6.
7.public final class hello_jsp extends org.apache.jasper.runtime.HttpJspBase
8. implements org.apache.jasper.runtime.JspSourceDependent {
9.
10. private static java.util.Vector _jspx_dependants;
11.
12. public java.util.List getDependants() {
13. return _jspx_dependants;
14. }
15.
16. public void_jspService(HttpServletRequest request, HttpServletResponse response)
17. throws java.io.IOException, ServletException {
18.
19. JspFactory _jspxFactory = null;
20. PageContext pageContext = null;
21. HttpSession session = null;
22. ServletContext application = null;
23. ServletConfig config = null;
24. JspWriter out = null;
25. Object page = this;
26. JspWriter _jspx_out = null;
27. PageContext _jspx_page_context = null;
28.
29.
30. try {
31. _jspxFactory = JspFactory.getDefaultFactory();
32. response.setContentType("text/html");
33. pageContext = _jspxFactory.getPageContext(this, request, response,
34. null, true, 8192, true);
35. _jspx_page_context = pageContext;
36. application = pageContext.getServletContext();
37. config = pageContext.getServletConfig();
38. session = pageContext.getSession();
39. out = pageContext.getOut();
40. _jspx_out = out;
41.
42. out.write("<html>/r/n");
43. out.write(" <head><title>Hello</title></head>/r/n");
44. out.write("</html>/r/n");
45. out.write("<body>/r/n");
46. out.write(" ");
47.
48. out.println("Hello World!");
49.
50. out.write("/r/n");
51. out.write("</body>/r/n");
52. out.write("</html>");
53. } catch (Throwable t) {
54. if (!(t instanceof SkipPageException)){
55. out = _jspx_out;
56. if (out != null && out.getBufferSize() != 0)
57. out.clearBuffer();
58. if (_jspx_page_context != null) _jspx_page_context.handlePageException(t);
59. }
60. } finally {
61. if (_jspxFactory != null) _jspxFactory.releasePageContext(_jspx_page_context);
62. }
63. }
代码的第5行,导入javax.servlet.jsp包中所有的类,与JSP相关的类定义在这个包中。在Tomcat的文档中,包含了JSP API的文档,该文档的位置是:%CATALINA_HOME%/webapps/tomcat-docs/ jspapi/index.html。
在JSP2.0规范中定义,JSP页面转换后的Servlet类必须实现javax.servlet.jsp.JspPage接口(与 Servlet类似,Servlet类必须实现javax.servlet.Servlet接口),该接口继承自javax.servlet.Servlet接口。除了继承的方法外,JspPage接口还定义了下面两个方法:
? public void jspInit()
这个方法在JSP页面初始化时被调用,它类似于Servlet中的init()方法。页面编写者可以在JSP的声明元素中覆盖这个方法,以提供任何的初始化工作。
? public void jspDestroy()
在JSP页面将要被销毁时调用这个方法。它类似于Servlet中的destroy()方法。页面编写者可以在JSP的声明元素中覆盖这个方法,以提供任何的JSP清除工作。
因为绝大多数情况下,JSP页面都是使用HTTP协议,所以JSP页面转换后的Servlet类实际上必须实现javax.servlet.jsp.HttpJspPage接口,该接口继承自JspPage接口。除了继承的方法外,HttpJspPage接口只定义了一个方法:
? public void _jspService(javax.servlet.http.HttpServletRequest request, javax.servlet.http.HttpServlet Response response) throws javax.servlet.ServletException, java.io.IOException
这个方法对应于JSP页面的主体(body)部分,它类似于Servlet中的service()方法。这个方法由JSP容器自动定义,页面编写者不应当提供该方法的实现。代码的第16~63行,就是JSP容器自动生成的_jspService()方法。
代码的第7行,hello_jsp类从org.apache.jasper.runtime.HttpJspBase类派生,HttpJspBase类是Tomcat提供的实现了HttpJspPage接口的类。HttpJspBase类的部分代码如下。
package org.apache.jasper.runtime;
import …;
public abstract class HttpJspBase extends HttpServlet implements HttpJspPage
{
…
static
{
if( JspFactory.getDefaultFactory() == null )
{
JspFactoryImpl factory = new JspFactoryImpl();
…
JspFactory.setDefaultFactory(factory);
}
}
public final void init(ServletConfig config) throws ServletException
{
super.init(config);
jspInit();
…
}
public String getServletInfo()
{
return Localizer.getMessage("jsp.engine.info");
}
public final void destroy()
{
jspDestroy();
…
}
public final void service(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException
{
_jspService(request, response);
}
public void jspInit(){}
public void jspDestroy(){}
public abstract void _jspService(HttpServletRequest request,
HttpServletResponse response)
throws ServletException, IOException;
}
读者看HttpJspBase类是否感觉非常熟悉,实际上,这就是一个实现了HttpJspPage接口的Servlet类,在Servlet类的init()方法中调用jspInit()方法,在Servlet类的destory()方法中调用jspDestroy()方法,在Servlet类的service ()方法中调用_jspService ()方法。从Tomcat提供的HttpJspBase类可以看出,JSP页面运行的底层仍然是Servlet技术。
在例12-2的第20~25行,定义了一些对象变量,第33~39行,分别对这些对象进行了初始化,这些代码都是由JSP容器自动产生的,也就是说,在JSP页面中,可以直接使用这些服务器端对象(详见12.4节)。
代码的第42~52行,打印输出HTML页面,这段代码对应的是例12-1 hello.jsp文件中的代码。
我们先来看一个简单的JSP文件,如例12-1所示。
例12-1 hello.jsp
<head><title>Hello</title></head>
</html>
<body>
<%
out.println("Hello World!");
%>
</body>
这个JSP页面向客户端输出“Hello World!”。我们把这个页面复制到%CATALINA_HOME%/webapps /ROOT目录下,启动Tomcat,打开浏览器,在地址栏中输入http://localhost:8080/hello.jsp,看到“Hello World!”的输出后,读者可以转到%CATALINA_HOME%/work/Catalina/localhost目录,在这个目录下,有一些读者熟悉的目录,这些目录都是以前面章节的Web应用程序的上下文路径命名的,其中“_”目录对应的是ROOT目录。在_/org/apache/jsp目录下,可以看到两个文件:“hello_jsp.java”和“hello_jsp.class”,这两个文件就是在我们访问hello.jsp文件时,由JSP容器生成的,整个过程如图12-1所示。
JSP容器管理JSP页面生命周期的两个阶段:转换阶段(translation phase)和执行阶段(execution phase)。当有一个对JSP页面的客户请求到来时,JSP容器检验JSP页面的语法是否正确,将JSP页面转换为Servlet源文件,然后调用javac工具类编译Servlet源文件生成字节码文件,这一阶段是转换阶段。接下来,Servlet容器加载转换后的Servlet类,实例化一个对象处理客户端的请求,在请求处理完成后,响应对象被JSP容器接收,容器将HTML格式的响应信息发送到客户端,这一阶段是执行阶段。
从整个过程中我们可以知道,当第一次加载JSP页面时,因为要将JSP文件转换为Servlet类,所以响应速度较慢。当再次请求时,JSP容器就会直接执行第一次请求时产生的Servlet,而不会再重新转换JSP文件,所以其执行速度和原始的Servlet执行速度几乎就相同了。在JSP执行期间,JSP容器会检查JSP文件,看是否有更新或修改。如果有更新或修改,JSP容器会再次编译JSP或Servlet;如果没有更新或修改,就直接执行前面产生的Servlet,这也是JSP相对于Servlet的好处之一。
下面我们看一下JSP容器在后台针对hello.jsp生成的Servlet源文件。虽然JSP页面转换为Servlet是在后台由JSP容器自动进行的,但通过阅读JSP容器生成的源代码来了解JSP背后运行的机制,将有助于我们更好地理解JSP页面的运行,编写更加健壮、安全的JSP页面。
hello_jsp.java的完整代码如例12-2所示。
例12-2 hello_jsp.java
1.package org.apache.jsp;
2.
3.import javax.servlet.*;
4.import javax.servlet.http.*;
5.import javax.servlet.jsp.*;
6.
7.public final class hello_jsp extends org.apache.jasper.runtime.HttpJspBase
8. implements org.apache.jasper.runtime.JspSourceDependent {
9.
10. private static java.util.Vector _jspx_dependants;
11.
12. public java.util.List getDependants() {
13. return _jspx_dependants;
14. }
15.
16. public void_jspService(HttpServletRequest request, HttpServletResponse response)
17. throws java.io.IOException, ServletException {
18.
19. JspFactory _jspxFactory = null;
20. PageContext pageContext = null;
21. HttpSession session = null;
22. ServletContext application = null;
23. ServletConfig config = null;
24. JspWriter out = null;
25. Object page = this;
26. JspWriter _jspx_out = null;
27. PageContext _jspx_page_context = null;
28.
29.
30. try {
31. _jspxFactory = JspFactory.getDefaultFactory();
32. response.setContentType("text/html");
33. pageContext = _jspxFactory.getPageContext(this, request, response,
34. null, true, 8192, true);
35. _jspx_page_context = pageContext;
36. application = pageContext.getServletContext();
37. config = pageContext.getServletConfig();
38. session = pageContext.getSession();
39. out = pageContext.getOut();
40. _jspx_out = out;
41.
42. out.write("<html>/r/n");
43. out.write(" <head><title>Hello</title></head>/r/n");
44. out.write("</html>/r/n");
45. out.write("<body>/r/n");
46. out.write(" ");
47.
48. out.println("Hello World!");
49.
50. out.write("/r/n");
51. out.write("</body>/r/n");
52. out.write("</html>");
53. } catch (Throwable t) {
54. if (!(t instanceof SkipPageException)){
55. out = _jspx_out;
56. if (out != null && out.getBufferSize() != 0)
57. out.clearBuffer();
58. if (_jspx_page_context != null) _jspx_page_context.handlePageException(t);
59. }
60. } finally {
61. if (_jspxFactory != null) _jspxFactory.releasePageContext(_jspx_page_context);
62. }
63. }
代码的第5行,导入javax.servlet.jsp包中所有的类,与JSP相关的类定义在这个包中。在Tomcat的文档中,包含了JSP API的文档,该文档的位置是:%CATALINA_HOME%/webapps/tomcat-docs/ jspapi/index.html。
在JSP2.0规范中定义,JSP页面转换后的Servlet类必须实现javax.servlet.jsp.JspPage接口(与 Servlet类似,Servlet类必须实现javax.servlet.Servlet接口),该接口继承自javax.servlet.Servlet接口。除了继承的方法外,JspPage接口还定义了下面两个方法:
? public void jspInit()
这个方法在JSP页面初始化时被调用,它类似于Servlet中的init()方法。页面编写者可以在JSP的声明元素中覆盖这个方法,以提供任何的初始化工作。
? public void jspDestroy()
在JSP页面将要被销毁时调用这个方法。它类似于Servlet中的destroy()方法。页面编写者可以在JSP的声明元素中覆盖这个方法,以提供任何的JSP清除工作。
因为绝大多数情况下,JSP页面都是使用HTTP协议,所以JSP页面转换后的Servlet类实际上必须实现javax.servlet.jsp.HttpJspPage接口,该接口继承自JspPage接口。除了继承的方法外,HttpJspPage接口只定义了一个方法:
? public void _jspService(javax.servlet.http.HttpServletRequest request, javax.servlet.http.HttpServlet Response response) throws javax.servlet.ServletException, java.io.IOException
这个方法对应于JSP页面的主体(body)部分,它类似于Servlet中的service()方法。这个方法由JSP容器自动定义,页面编写者不应当提供该方法的实现。代码的第16~63行,就是JSP容器自动生成的_jspService()方法。
代码的第7行,hello_jsp类从org.apache.jasper.runtime.HttpJspBase类派生,HttpJspBase类是Tomcat提供的实现了HttpJspPage接口的类。HttpJspBase类的部分代码如下。
package org.apache.jasper.runtime;
import …;
public abstract class HttpJspBase extends HttpServlet implements HttpJspPage
{
…
static
{
if( JspFactory.getDefaultFactory() == null )
{
JspFactoryImpl factory = new JspFactoryImpl();
…
JspFactory.setDefaultFactory(factory);
}
}
public final void init(ServletConfig config) throws ServletException
{
super.init(config);
jspInit();
…
}
public String getServletInfo()
{
return Localizer.getMessage("jsp.engine.info");
}
public final void destroy()
{
jspDestroy();
…
}
public final void service(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException
{
_jspService(request, response);
}
public void jspInit(){}
public void jspDestroy(){}
public abstract void _jspService(HttpServletRequest request,
HttpServletResponse response)
throws ServletException, IOException;
}
读者看HttpJspBase类是否感觉非常熟悉,实际上,这就是一个实现了HttpJspPage接口的Servlet类,在Servlet类的init()方法中调用jspInit()方法,在Servlet类的destory()方法中调用jspDestroy()方法,在Servlet类的service ()方法中调用_jspService ()方法。从Tomcat提供的HttpJspBase类可以看出,JSP页面运行的底层仍然是Servlet技术。
在例12-2的第20~25行,定义了一些对象变量,第33~39行,分别对这些对象进行了初始化,这些代码都是由JSP容器自动产生的,也就是说,在JSP页面中,可以直接使用这些服务器端对象(详见12.4节)。
代码的第42~52行,打印输出HTML页面,这段代码对应的是例12-1 hello.jsp文件中的代码。
分享到:
相关推荐
具体描述了jsp语法,并对其进行了讲解,让大家对JAVA语法进行了深入的了解
常用JSP语法以及数据库连接 有2个网页导航的脚本 以及jsp连接sql数据库和一些jsp常用语法
jsp 语法大全详细解说,我看过了,觉得挺好的希望对您有用
JSP语法基础.pdf一个JSP 页面由元素和模板数据组成。元素是必须由JSP 容器处理的部分,而模板数据是JSP 容器不处理的部分,例如,JSP 页面中的HTML 内容,这些内容会直接发送到客户端。在JSP2.0 规范中,元素有三种...
jsp语法-------------
JSP语法 JSP语法 JSP语法 JSP语法 JSP语法 JSP语法 JSP语法
个人学习总结,jsp基本理论知识,jdk配置,tomcat配置,jsp语法,myelipse使用
JSP语法大全及举例说明.doc
本资源描述了jsp语法及工作原理和基本规范
JSP基础语法,掌握JSP基本语法 掌握JSP基本指令 <jsp:include pate=“uri”/> “uri”%> <jsp:forward page=“uri”/> 掌握JSP九个内置对象
第二章 JSP语法与内置对象.ppt
jsp语法练习,应对期末考试啊! 选择题 1. 下面那个方法能够读取给定HttpServletRequest request对象中的所有Cookie? A. request.getCookies() B. request.getAttributes() C. request.getSession ().getCookies() D...
JSP语法简明入门教程,喜欢懂得就下来看看
jsp语法手册 jsp语法手册
<JSP语法详解> e book
JSP基础语法知识JSP语法(中华电脑书库_整理制作).rar
JSP语法手册 CHM格式 自己学习收集的 拿出来共享
Servlet与JSP语法.doc Servlet与JSP语法.doc
WEB程序设计-JSP(第3章 JSP语法).pdf WEB程序设计-JSP(第1章 JSP概述).pdf WEB程序设计-JSP(第2章 JSP开发基础).pdf WEB程序设计-JSP(第4章 JSP内置对象).pdf WEB程序设计-JSP(第6章 Servlet技术).pdf WEB程序...
jsp语法详解,介绍jsp使用,java环境下的开发,jsp页面