JSP在运行时的处理

JSP的实质

JSP实际上是一个精心设计的Servlet

在运行时,JSP代码将有JSP编译器进行转换,它将解析出JSP代码的所有特性,并将其转换为Java代码。
由JSP创建得到的Java类都会实现Servlet


tomcat中,JSP默认是不会在Tomcat启动时进行加载编译的,当我们访问时,则会在tomcat根目录\work\Catalina\localhost中的文件夹中出现刚刚编译好的JSP文件的class文件和Java文件

public final class index_jsp extends org.apache.jasper.runtime.HttpJspBase
    implements org.apache.jasper.runtime.JspSourceDependent,
                 org.apache.jasper.runtime.JspSourceImports {
..............................
}

可以看到由JSP生成的类继承了org.apache.jasper.runtime.HttpJspBase,而该类又继承了HttpServlet;
HttpJspBase提供了一些可用Tomcat编译过的JSP所使用的功能,在执行JSP时,最后将执行Servlet的service方法,而service方法又会执行方法_jspService
查看由JSP生成的Java文件中的_jspService方法:

  public void _jspService(final javax.servlet.http.HttpServletRequest request, final javax.servlet.http.HttpServletResponse response)
      throws java.io.IOException, javax.servlet.ServletException {

    final java.lang.String _jspx_method = request.getMethod();
    if (!"GET".equals(_jspx_method) && !"POST".equals(_jspx_method) && !"HEAD".equals(_jspx_method) && !javax.servlet.DispatcherType.ERROR.equals(request.getDispatcherType())) {
      response.sendError(HttpServletResponse.SC_METHOD_NOT_ALLOWED, "JSPs only permit GET POST or HEAD");
      return;
    }

    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=UTF-8");
      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("\n");
      out.write("\n");
      out.write("\n");
      out.write(" \n");
      out.write(" Hello World Application\n");
      out.write(" \n");
      out.write(" \n");
      out.write(" Hello, World!\n");
      out.write(" \n");
      out.write("\n");
    } catch (java.lang.Throwable t) {
      if (!(t instanceof javax.servlet.jsp.SkipPageException)){
        out = _jspx_out;
        if (out != null && out.getBufferSize() != 0)
          try {
            if (response.isCommitted()) {
              out.flush();
            } else {
              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);
    }
  }

在入口处可以看到JSP只支持GET方法和POST方法
接下来将HTML写入输出流中。

不同的容器中创建出的Java类也是不同的

JSP的生命周期

JSP作为Servlet,也有自己的生命周期,在某些容器中(Tomcat),JSP会在第一次请求到达时被即时转换并编译。
当然,很多web容器提供了在部署项目时预编译所有JSP的功能,不过会降低部署速度。

空白的JSP文件

<%@ page contentType="text/html;charset=UTF-8" language="java" %>

没有包含该头部的JSP页面,依旧正常编译
因为JSP默认的内容类型(contentType)为text/html,默认的字符编码(charset)为ISO-8859-1.

你可能感兴趣的:(JavaWeb高级编程读书笔记)