`
Aether
  • 浏览: 13915 次
  • 性别: Icon_minigender_1
  • 来自: 深圳
最近访客 更多访客>>
社区版块
存档分类
最新评论

JSP拾遗(二)——从jsp到servlet

    博客分类:
  • Java
阅读更多

     无代码无真相。这里我们来看看,一个简单的jsp页面,在被服务器解释执行时,到底发生了怎么样的转换。

     在你的tomcat根目录下的webapps目录下,新建一个test目录。在新建的test目录里面,创建一个WEB-INF目录。将tomcat根目录下的conf目录里的web.xml目录拷贝到/webapps/test/WEB-INF目录下,这里的web.xml的可以把<web-app>标签里面的内容全部删除,因为conf里面已经声明过了。然后在/webapps/test目录下新建一个txt文档,并把名称改为MyJsp.jsp,注意后缀名是.jsp

完成上面操作后的目录结构如下:

wbapps - test -

             -MyJsp.jsp

                    -WEB-INF -

                                       - web.xml

      启动tomcat,在地址栏中输入http://127.0.0.1:8080/test/MyJsp.jsp。浏览器里一片空白,这是自然的,因为我们的MyJsp.jsp文件本身就什么内容也没有。

      在tomcatwork目录中找到test目录,它的位置是/work/Catalina/localhos/下面,然后依次顺着目录找下去,在/work/Catalina/localhos/org/apache/jsp目录下面,你会发现一个MyJsp_jsp.java文件。这个文件就是MyJsp.jsp文件被翻译成的java文件。它并不是在jsp文件名后面加了Servlet,而是直接把"."变成"_"作为类名。

    打开MyJsp_jsp.java文件:

   

package org.apache.jsp;

import javax.servlet.*;
import javax.servlet.http.*;
import javax.servlet.jsp.*;

public final class MyJsp_jsp extends org.apache.jasper.runtime.HttpJspBase
    implements org.apache.jasper.runtime.JspSourceDependent {

  private static java.util.List _jspx_dependants;

  public Object 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");
      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;

    } 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文件,也照样会生成这么长的一段代码的。没有看到servlet的字样?翻翻tomcatapi,你就会发现,MyJsp_jsp的父类HttpJspBase已经实现了javax.servlet.Servlet接口的。

下面我们在MyJsp.jsp文件中加入以下HTML代码:

<html>
<body>
	This is my first JSP!
</body>
</html>

 

 

 

刷新一下浏览器,我们发现,MyJsp_jsp.java中, _jspService()方法中,增加了以下代码:

out.write("<html>\r\n");
out.write("<body>\r\n");
out.write("\tThis is my first JSP!\r\n");
out.write("</body>\r\n");
out.write("</html>");

 

 

 

      原来,所有的HTML代码都要用out.write()方法输出出来的啊。所以可以想象,如果使用纯粹的Servlet编写一个复杂的web页面,将是一件多么麻烦的事情。

 

下面,我们来实验将jsp里面插入代码段的情况。教材里面说jsp里面的java代码段有两种形式,一种是<%!  %>包围,一种是<%  %>包围。(当然取值符<%=  %>里面的表达式里也可以有相当长java代码段,这个我们暂时不予考虑)

<%!  %>一般用来表示全局变量的声明,以及方法的声明,而<%  %>则是普通的可执行程序段。什么意思呢?用代码来说话!

 

MyJsp.jsp文件里面加入以下代码:

 

<%!   
        double PI = 3.14159;

         int  plus(int a, int b){
         return a+b;
}
%>
<%
         String hello = "Hello World!";
%>

 

 

再次刷新浏览器,查看MyJsp_jsp.java代码:

 

package org.apache.jsp;

import javax.servlet.*;
import javax.servlet.http.*;
import javax.servlet.jsp.*;

public final class MyJsp_jsp extends org.apache.jasper.runtime.HttpJspBase
    implements org.apache.jasper.runtime.JspSourceDependent {

   
	double PI = 3.14159; //<%! %>里面的变量成为成员变量
	
	int  plus(int a, int b){//<%! %>里面的方法成为成员方法 
	return a+b;
	}
	
  private static java.util.List _jspx_dependants;

  public Object 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");
      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;

      String hello = "Hello World!";  //<%%>里面的代码段

      out.write("\r\n");
      out.write("\r\n");                     //HTML代码段
      out.write("<html>\r\n");
      out.write("<body>\r\n");
      out.write("\tThis is my first JSP!\r\n");
      out.write("</body>\r\n");
      out.write("</html>");
    } 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);
    }
  }
}

 

 

我们发现,<%!  %>里面声明的变量成为了MyJsp_jsp的成员变量,里面声明的方法成为了MyJsp_jsp类的成员方法,而<%  %>的代码则被填充到了_jspService()方法中。

 

 注意<%  %>中的代码在_jspService()方法中的填充位置。这里的代码是被填充在一大堆对象的初始化之后,因此, _jspService()方法中的这一大堆对象就可以在<% %>里面直接拿来使用,这些对象就是所谓JSP的内置对象,除了_jspFactory对象没什么用处外,这里有八个内置对象,按照声明顺序依次是:requestresponsepageContextsessionapplicationconfigoutpage。这些内置对象除了可以直接在你的<% %>代码段中使用外,还会在你试图声明和它们同名的对象时,优雅地给你报出一个错误。(废话)

 

 

分享到:
评论

相关推荐

Global site tag (gtag.js) - Google Analytics