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

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

①HelloWorld.jsp

<%@ page contentType="text/html; charset=gb2312" language="java" %>

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">

<HTML>

    <HEAD>

    <TITLE>HelloWorld</TITLE>

    </HEAD>

<BODY>

<%

    out.println("HelloWorld");

%>

</BODY>

</HTML>

②HelloWorld_jsp.java

package org.apache.jsp;

 

import javax.servlet.*;

import javax.servlet.http.*;

import javax.servlet.jsp.*;

 

public final class HelloWorld_jsp extends org.apache.jasper.runtime.HttpJspBase

    implements org.apache.jasper.runtime.JspSourceDependent {

 

  private static final javax.servlet.jsp.JspFactory _jspxFactory =

          javax.servlet.jsp.JspFactory.getDefaultFactory();

 

  private static java.util.Map<java.lang.String,java.lang.Long> _jspx_dependants;

 

  public java.util.Map<java.lang.String,java.lang.Long> getDependants() {

    return _jspx_dependants;

  }

 

  public void _jspInit() {

  }

 

  public void _jspDestroy() {

  }

 

  public void _jspService(final javax.servlet.http.HttpServletRequest request, final javax.servlet.http.HttpServletResponse response)

        throws java.io.IOException, javax.servlet.ServletException {

 

    final javax.servlet.jsp.PageContext pageContext;

    javax.servlet.http.HttpSession session = null;

    final javax.servlet.ServletContext application;

    final javax.servlet.ServletConfig config;

    javax.servlet.jsp.JspWriter out = null;

    final java.lang.Object page = this;

    javax.servlet.jsp.JspWriter _jspx_out = null;

    javax.servlet.jsp.PageContext _jspx_page_context = null;

 

    try {

      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("<!DOCTYPE HTML PUBLIC \"-//W3C//DTD HTML 4.0 Transitional//EN\">\r\n");

      out.write("<HTML>\r\n");

      out.write("    <HEAD>\r\n");

      out.write("    <TITLE>HelloWorld</TITLE>\r\n");

      out.write("    </HEAD>\r\n");

      out.write("<BODY>\r\n");

      out.println("HelloWorld");

      out.write("\r\n");

      out.write("</BODY>\r\n");

      out.write("</HTML>\r\n");

    } catch (java.lang.Throwable t) {

      if (!(t instanceof javax.servlet.jsp.SkipPageException)){

        out = _jspx_out;

        if (out != null && out.getBufferSize() != 0)

          try { out.clearBuffer(); } catch (java.io.IOException e) {}

        if (_jspx_page_context != null) _jspx_page_context.handlePageException(t);

        else throw new ServletException(t);

      }

    } finally {

      _jspxFactory.releasePageContext(_jspx_page_context);

    }

  }

}

经过前面介绍的语法解析及使用访问者模式对HelloWorld.jsp文件编译成相应的HelloWorld_jsp.java文件可以看到Servlet类名是由jsp文件名_jsp拼成。再往下看HelloWorld_jsp.java文件的详细内容类包名默认为org.apache.jsp默认有三个导入“import javax.servlet.*;import javax.servlet.http.*;import javax.servlet.jsp.*;”。

接下去是真正的类主体jsp生成的java类都必须继承org.apache.jasper.runtime.HttpJspBase这个类的结构图如下继承了HttpServlet是为了将HttpServlet的所有功能都继承下来另外又实现HttpJspPage接口定义了一个JSP类的Servlet的核心处理方法_jspService除此之外还有_jspInit和_jspDestroy用于在jsp初始化和销毁时执行这些方法其实都是由Servlet的service、init、destroy方法间接去调用所以jsp生成servlet主要就是实现这三个方法。

 

除了继承HttpJspBase外还需实现org.apache.jasper.runtime.JspSourceDependent接口这个接口只有一个返回Map<String,Long>类型的getDependants()方法Map的键值分别为资源名和最后修改时间这个实现主要是为了记录某些依赖资源是否过时依赖资源可能是page指令导入的也可能是标签文件引用等。在生成servlet时如果jsp页面做了上述依赖的话则会在servlet类中添加一个static块static块会将资源及最后修改时间添加到Map中。

在jsp类servlet处理过程中会依赖很多资源比如我要操作会话的话就需要此次访问的HttpSession对象比如我要操作Context容器级别的对象就要ServletContext对象再比如我要获取servlet配置信息就要ServletConfig对象最后还需要一个输出对象用于在处理过程中将内容输出。这些对象都在核心方法_jspService中使用作为servlet类要获取这些对象其实非常简单因为这些本身就属于servlet属性有相关方法直接获取。但这里因为JSP有自己的标准所以必须按照它的标准去实现。

具体的JSP标准是怎样的首先为了方便JSP的实现提供一个统一的工厂类JspFactory用于获取不同的资源其次由于按照标准规定不能直接使用servlet上下文所以需要定义一个PageContext类封装servlet上下文最后同样按照标准需要定义一个输出类JspWriter封装servlet的输出。所以可以看到PageContext对象通过JspFactory获取其他ServletContext对象、ServletConfig对象、HttpSession对象及JspWriter则通过PageContext对象获取。通过这些对象再加上前面章节语法解析得到的语法树对象再利用访问者模式对语法树遍历就可以生成核心处理方法_jspService了。

上面只是介绍了最简单的一个jsp页面转变成servlet的过程旨在说明jsp到servlet转化的原理实际上需要处理很多jsp指令标签。

点击订购作者《Tomcat内核设计剖析》

时间: 2024-10-01 16:37:25

JSP编译成Servlet(三)JSP编译后的Servlet的相关文章

图形界面编译工具Koala将SASS文件编译成CSS文件

文章简介:本文主要通过创建一个SASS项目为实例,带领大家如何使用Koala这样的图形界面编译工具来将你的SASS项目,将SASS文件编译成CSS文件. <SASS界面编译工具--Codekit的使用>一文中图解了"CodeKit"图形工具编译SASS项目.由于CodeKit是一款付费工具,而且只能在Mac中使用,因此国内众多SASS爱好者,或者初学者也就无法体验CodeKit工具编译SASS项目.幸运的是,有一款国产图形工具Koala和CodeKit功能极其类似,支持多个

JNI: C++编译成dll问题

问题描述 JNI: C++编译成dll问题 C++编译成dll,然后JNI调用其中的方法.但是在.cpp文件生成.dll文件过程中,报错.我在C++的源文件.cpp中用到了如cv.h之类的头文件.这是什么问题 解决方案 这些是编译jni调用的dll必须的头文件,一般安装了jdk后都会有 解决方案二: 要看你的编译错误信息,可能是依赖的头文件没配置对路径. 解决方案三: .cpp文件生成.dll文件过程中,报错. 那是编译错误.和jni没关系.检查你的代码,包括引用的头和库.

把js文件编译成dll供页面调用的方法_实用技巧

1. 在解决方案中添加一个项目:JSControl 2. 在这个项目添加一个js文件(JScript1.js) 脚本的内容: function showAlert(){ alert('Today is a good dary'); } 3. 改变JScript1.js的属性,Build Action为Embedded Resource(嵌入的资源) 4. 在JSControl项目的AssemblyInfo.cs文件中添加一行:(注意JSControl.JScript1.js,JSControl是

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

我们知道java虚拟机只认识class文件,要在虚拟机上运行就必须要遵守class文件格式,所以JSP编译成servlet后还需要进一步编译成class文件,但从JSP文件到java文件再到class文件的过程需要考虑的事情比较多,其中一个比较重要的就是调试问题,由于语法不一样,jsp某行执行的逻辑怎样与java文件对应起来,这样在JVM执行过程发生异常或错误才能找到JSP对应的行,提供一个友好的调试信息.类似的,jsp文件名编译后的java文件名同样也要有映射关系.     总的来说,为了解决

JSP编译成Servlet(一)语法树的生成——语法解析

一般来说,语句按一定规则进行推导后会形成一个语法树,这种树状结构有利于对语句结构层次的描述.同样Jasper对JSP语法解析后也会生成一棵树,这棵树各个节点包含了不同的信息,但对于JSP来说解析后的语法树比较简单,只有一个父节点和n个子节点.例如node1是表示形如<!-- 字符串 -->的注释节点,节点里面包含了一个表示注释字符串的属性:而node2则可能是表示形如<%= a+b %>的表达式节点,节点里面包含一个表示表达式的属性,同样地其他节点可能表示JSP的其他语法,有了这棵

如何使用ant调用WebSphere的编译器将jsp编译成jar包?

问题描述 我们现有的项目是运行在tomcat5下,jsp是通过使用tomcat提供的org.apache.jasper.JspC编译工具将JSP页面的预编译.把所有JSP编译后得到的.class打包成一个xxx.jar包,放在我们应用的lib中.然后在web.xml中分别设置为servlet,再映射到某个xxx.jsp的URL上.build.xml文件如下:<projectname="WebappPrecompilation"default="all"base

把JSP预编译成class文件进行JSP文件的保护

js|编译 在Weblogic中发布Web Application工程时,为了保护JSP文件避免未经授权的访问和窥视,可以用weblogic.jspc把JSP文件precompile成为servlet文件,放到WEB-INF/classes目录下.基于Servlet的声明,WEB-INF不作为Web应用的公共文档树的一部分.因而,WEB-INF目录下的资源不是为客户直接服务的,这样就可以一定程度上保证JSP的安全. 具体的实现步骤如下(Weblogic for linux): 1.用weblog

快速建立Servlet和JSP的运行、调试和编译环境

js|servlet|编译 相信很多刚开始学习Servlet和JSP的朋友都有一个困扰,就是如何快速方便的建立一个Servlet和JSP的运行.调试和编译环境.本人现在正在国外攻读MIT(Master of Information Technology),现在选修的这一科是WBIS(Web Based Information Systems),其包含了许多种技术,如Java,Perl,CGI,Servlet,ASP,Java Script,JSP,OO,UML等等.下面的这篇文章是学校所提供的相

快速建立Servlet和JSP的运行、调试和编译环境_JSP编程

相信很多刚开始学习Servlet和JSP的朋友都有一个困扰,就是如何快速方便的建立一个Servlet和JSP的运行.调试和编译环境.本人现在正在国外攻读MIT(Master of Information Technology),现在选修的这一科是WBIS(Web Based Information Systems),其包含了许多种技术,如Java,Perl,CGI,Servlet,ASP,Java Script,JSP,OO,UML等等.下面的这篇文章是学校所提供的相关软件的下载地址.安装方法以