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详细过程【转】的更多相关文章

  1. JSP转译成Servlet详细过程

    很多人都会认为JSP的执行性能会和Servlet相差很多,其实执行性能上的差别只在第一次的执行.因为JSP在执行第一次后,会被编译成 Servlet的类文件,即.class,当再重复调用执行时,就直接 ...

  2. jsp页面编译成Servlet类文件

    package org.apache.jsp; import javax.servlet.*; import javax.servlet.http.*; import javax.servlet.js ...

  3. JSP编译成Servlet(三)JSP编译后的Servlet

    JSP编译后的Servlet类会是怎样的呢?他们之间有着什么样的映射关系?在探讨JSP与Servlet之间的关系时先看一个简单的HelloWorld.jsp编译成HelloWorld.java后会是什 ...

  4. JSP源码、改写Servlet为JSP、查看转译成为Servlet的文件、JSP字符编码设置

    概述 在Servlet中编写HTML太麻烦了,应该使用JSP.JSP中可以直接编写HTML,使用指示.声明.脚本(scriptlet)等元素来堆砌各种功能,但JSP最后还是会被容器转译为Servlet ...

  5. JSP九大内置对象详细介绍

    内置对象的特点: 1.由JSP规范提供,不用编写者实例化. 2.通过Web容器实现和管理 3. 所有JSP页面均可使用 4.只有在脚本元素的表达式或代码段中才可使用(<%=使用内置对象%> ...

  6. jsp页面转发到servlet

    一个简单的例子来了解一下jsp页面转发到servlet的过程,环境 eclipse.tomcat 1.工程目录结构如下 2.各部分代码如下 1>index.jsp <%@ page lan ...

  7. JSP编译成Servlet(四)JSP与Java行关系映射

    我们知道java虚拟机只认识class文件,要在虚拟机上运行就必须要遵守class文件格式,所以JSP编译成servlet后还需要进一步编译成class文件,但从JSP文件到java文件再到class ...

  8. IDEA搭建SSMM框架(详细过程)

    IDEA搭建SSMM框架(详细过程) 相关环境 Intellij IDEA Ultimate Tomcat JDK MySql 5.6(win32/win64) Maven (可使用Intellij ...

  9. Tomcat配置(三):tomcat处理连接的详细过程

    */ .hljs { display: block; overflow-x: auto; padding: 0.5em; color: #333; background: #f8f8f8; } .hl ...

随机推荐

  1. 08_Android中的SimpleAdapter的使用

     1 目的界面 2.编写Android清单文件 <?xml version="1.0" encoding="utf-8"?> <manif ...

  2. clisp, scheme 和 clojure 初学习

    clisp, scheme和clojure 初学习 1 clojure "clojure绝对会成为你的编程工具箱里的终极武器" "其他语言可能只是工具,但 Clojure ...

  3. UseCase事件流描述规范

    文/fasiondog 整理需求用例的编写规范,分享部分UseCase事件流描述规范.其中,准则5~10.12来自<编写有效用例>([美] Alistair Cockburn 著)一书,其 ...

  4. nginx 配置open_cache_file 静态文件的缓存

    open_file_cache max=65535 inactive=30s 最多缓存多少个文件,缓存多少时间open_file_cache_min_uses 1 在30S中没有使用到这个配置的次数的 ...

  5. android 优化之布局优化

    布局优化的思路很简单,尽量减少布局文件的层级,看过系统源码的都知道,Android view绘制都是逐层绘制的,所以布局的层级少了,decodeview的时候绘制工作自然就少了. 那么如何进行布局的优 ...

  6. C#之结尾篇

    在Top10语言中,C#是最优美的语言,没有之一,在Top10语言中,C#所可用的标准库及可获得其他库是最强大的之一,这个必须带上之一,因为有java在,在Top语言中,C#语言是性能最高的语言之一, ...

  7. jQuery 瀑布流插件: Wookmark

    原文链接: jQuery Wookmark 在线示例: jQuery Wookmark Demo Wookmark官网: http://www.wookmark.com/jquery-plugin 翻 ...

  8. ros_indigo使用keyboard键盘控制虚拟或实际机器人

    首先,上参考网址: http://wiki.ros.org/Robots/TIAGo http://wiki.ros.org/teleop_twist_keyboard 第一个,使用TIAGo的gaz ...

  9. Linux - info

    基本上,info与man的用途其实差不多,都是用来查询命令的用法或者是文件的格式.但是与man page一口气输出一堆信息不同的是,info page则是将文件数据拆成一个一个的段落,每个段落用自己的 ...

  10. 苹果新的编程语言 Swift 语言进阶(八)--属性

    属性是特定类.结构或枚举的相关值,属性根据作用域不同分为实例属性与类型属性,还可以根据是否存储分为存储属性和计算属性. 1.1 实例属性 为一个类.结构或枚举定义的属性默认属于实例属性,即该属性属于为 ...