JSP转译成Servlet详细过程【转】
JSP是Servlet的扩展,在没有JSP之前,就已经出现了Servlet技术。Servlet是利用输出流动态生成HTML页面,包括每一个HTML标签和每个在HTML页面中出现的内容。
由于包括大量的HTML标签、大量的静态文本及格式等,导致Servlet的开发效率极为低下。所有的表现逻辑,包括布局、色彩及图像等,都必须耦合在Java代码中,这的确让人不胜其烦。JSP的出现弥补了这种不足,JSP通过在标准的HTML页面中插入Java代码,其静态的部分无须Java程序控制,只有那些需要从数据库读取并根据程序动态生成信息时,才使用Java脚本控制。
从表面上看,JSP页面已经不再需要Java类,似乎完全脱离了Java面向对象的特征。事实上,JSP是Servlet的一种特殊形式,每个JSP页面就是一个Servlet实例——JSP页面由系统编译成Servlet,Servlet再负责响应用户请求。JSP其实也是Servlet的一种简化,使用JSP时,其实还是使用Servlet,因为Web应用中的每个JSP页面都会由Servlet容器生成对应的Servlet。对于Tomcat而言,JSP页面生成的Servlet放在work路径对应的Web应用下。
看下面一个简单的JSP页面:
<!-- 表明此为一个JSP页面 -->
<%@ page contentType="text/html; charset=gb2312" language="java" %>
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
<HTML>
<HEAD>
<TITLE>第一个JSP页面</TITLE>
</HEAD>
<BODY>
<!-- 下面是Java脚本 Scriptlet-->
<%for(int i = 0 ; i < 10; i++)
{
out.println(i);
%>
<br>
<%}%>
</BODY>
</HTML>
当启动Tomcat之后,可以在Tomcat的Catalinalocalhostjsptestorgapachejsp目录下找到如下文件(假如Web应用名为jsptest,上面JSP页的名为test1.jsp):test1_jsp.java和test1_jsp.class。这两个文件都是Tomcat生成的,Tomcat根据JSP页面生成对应Servlet的Java文件及class文件。
下面是test1_jsp.java文件的源代码,这是一个特殊的Java类,是一个Servlet类:
//JSP页面经过Tomcat编译后默认的包(不同的servlet容器提供商生成的servlet文件是不同的)
package org.apache.jsp;
import javax.servlet.*;
import javax.servlet.http.*;
import javax.servlet.jsp.*;
//继承HttpJspBase类,该类其实是个HttpServlet的子类(jasper是tomcat的jsp engine)
public final class test1_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
{ //built-in objects(variavles) are created here.
//获得页面输出流
JspFactory _jspxFactory = null;
PageContext pageContext = null;
HttpSession session = null;
ServletContext application = null;
ServletConfig config = null;
//获得页面输出流
JspWriter out = null; //not PrintWriter. JspWriter is buffered defautly.
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("rn");
//下面输出HTML标签
out.write("<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0
Transitional//EN">rn");
out.write("<HTML>rn");
out.write("<HEAD>rn");
out.write("<TITLE>first Jsp</TITLE>rn");
out.write("</HEAD>rn");
out.write("<BODY>rn");
//页面中的循环,在此处循环输出
for(int i = 0 ; i < 10; i++)
{
out.println(i);
out.write("rn");
out.write("<br>rn");
}
out.write("rn");
out.write("</BODY>rn");
out.write("</HTML>rn");
out.write("rn");
}
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.handle
PageException(t);
}
}
finally
{
if (_jspxFactory != null) _jspxFactory.releasePageContext(_jspx_
page_context);
}
}
}
根据图2.1的执行效果,再次对比test1.jsp和test1_jsp.java文件,可得到一个结论:该JSP页面中的每个字符都由test1_jsp.java文件的输出流生成。
根据上面的JSP页面工作原理图,可以得到如下四个结论:
— JSP文件必须在JSP服务器内运行。
— JSP文件必须生成Servlet才能执行。
— 每个JSP页面的第一个访问者速度很慢,因为必须等待JSP编译成Servlet。
— JSP页面的访问者无须安装任何客户端,甚至不需要可以运行Java的运行环境,因为JSP页面输送到客户端的是标准HTML页面。
JSP和Servlet会有如下转换:
- JSP页面的静态内容、JSP脚本都会转换成Servlet的xxxService()方法,类似于自行创建Servlet时service()方法。
- JSP声明部分,转换成Servlet的成员部分。所有JSP声明部分可以使用private,protected,public,static等修饰符,其他地方则不行。
- JSP的输出表达式(<%= ..%>部分),输出表达式会转换成Servlet的xxxService()方法里的输出语句。
- 九个内置对象要么是xxxService()方法的形参,要么是该方法的局部变量,所以九个内置对象只能在JSP脚本和输出表达式中使用。// 不能在jsp Declaration中使用
JSP转译成Servlet详细过程【转】的更多相关文章
- JSP转译成Servlet详细过程
很多人都会认为JSP的执行性能会和Servlet相差很多,其实执行性能上的差别只在第一次的执行.因为JSP在执行第一次后,会被编译成 Servlet的类文件,即.class,当再重复调用执行时,就直接 ...
- jsp页面编译成Servlet类文件
package org.apache.jsp; import javax.servlet.*; import javax.servlet.http.*; import javax.servlet.js ...
- JSP编译成Servlet(三)JSP编译后的Servlet
JSP编译后的Servlet类会是怎样的呢?他们之间有着什么样的映射关系?在探讨JSP与Servlet之间的关系时先看一个简单的HelloWorld.jsp编译成HelloWorld.java后会是什 ...
- JSP源码、改写Servlet为JSP、查看转译成为Servlet的文件、JSP字符编码设置
概述 在Servlet中编写HTML太麻烦了,应该使用JSP.JSP中可以直接编写HTML,使用指示.声明.脚本(scriptlet)等元素来堆砌各种功能,但JSP最后还是会被容器转译为Servlet ...
- JSP九大内置对象详细介绍
内置对象的特点: 1.由JSP规范提供,不用编写者实例化. 2.通过Web容器实现和管理 3. 所有JSP页面均可使用 4.只有在脚本元素的表达式或代码段中才可使用(<%=使用内置对象%> ...
- jsp页面转发到servlet
一个简单的例子来了解一下jsp页面转发到servlet的过程,环境 eclipse.tomcat 1.工程目录结构如下 2.各部分代码如下 1>index.jsp <%@ page lan ...
- JSP编译成Servlet(四)JSP与Java行关系映射
我们知道java虚拟机只认识class文件,要在虚拟机上运行就必须要遵守class文件格式,所以JSP编译成servlet后还需要进一步编译成class文件,但从JSP文件到java文件再到class ...
- IDEA搭建SSMM框架(详细过程)
IDEA搭建SSMM框架(详细过程) 相关环境 Intellij IDEA Ultimate Tomcat JDK MySql 5.6(win32/win64) Maven (可使用Intellij ...
- Tomcat配置(三):tomcat处理连接的详细过程
*/ .hljs { display: block; overflow-x: auto; padding: 0.5em; color: #333; background: #f8f8f8; } .hl ...
随机推荐
- Chipmunk Rigid Bodies:cpBody
Chipmunk刚体支持3种不同的类型: Dynamic(动态),Static(静态)以及Kinematic(混合态)刚体.它们拥有不同的行为和性能特征. 动态刚体是默认的刚体类型.它们可以对碰撞做出 ...
- 【一天一道LeetCode】#70. Climbing Stairs
一天一道LeetCode 本系列文章已全部上传至我的github,地址:ZeeCoder's Github 欢迎大家关注我的新浪微博,我的新浪微博 欢迎转载,转载请注明出处 (一)题目 You are ...
- Python基础 语法特别注意笔记(和Java相比)
Python变量和数据类型 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 ...
- python调用数据库并查询
http://blog.csdn.net/pipisorry/article/details/48024795 python调用数据库命令 conn = sqlite3.connect(". ...
- 高德地图SDK使用经验
下文说的是高德地图 Android SDK版本,详细版本如下: 2D地图:v2.3.1 定位:v1.3.0 导航:v1.1.1 发现的问题如下,其中一些疑是地图BUG,一些是需要你自己小心的地方: 1 ...
- Java集合之WeakHashMap
纸上得来终觉浅,绝知此事要躬行 --陆游 问渠那得清如许,为有源头活水来 --朱熹 WeakHashMap继承于AbstractMap,同时实现了Map接口. 和HashMap一样,Weak ...
- LeetCode之“字符串”:最长回文子串
题目要求: 给出一个字符串(假设长度最长为1000),求出它的最长回文子串,你可以假定只有一个满足条件的最长回文串.例如,给出字符串 "abcdzdcab",它的最长回文子串为 & ...
- Oracle EBS 预警系统管理(可用于配置工作流发审批邮件)
本章主要讲述配置和设置Oracle EBS预警系统管理, 它比较方便和及时发用户或系统对数据库操作情况.下面讲一操作步聚: 1.预警系统管理-->系统-->选项 名称"Unix ...
- C语言笔试经典--求分数数列的和
题目: 求数组的和 2 3/2 5/3 8/5 13/8 21/13 ... 求前20项的和 //求分数数列的和 #include<stdio.h> // ...
- javascript属性访问表达式
属性访问表达式运算得到一个对象属性或一个数组元素的值.js为属性访问定义了2中语法: expression.identifier expression["expression"] ...