详解JSP——从源码分析

何为JSP

Java Server Pages:java服务器端页面 和Servlet一样 用于动态web技术

特点:

跟在写HTML一样

区别:

HTML只给用户提供静态的数据
JSP页面中可以嵌入Java代码 为用户提供动态数据

JSP原理分析:

jsp执行流程
服务器内部:
tomcat内部有个work目录
详解JSP——从源码分析
IDEA使用tomcat会在IDEA的tomcat中生成一个work目录
详解JSP——从源码分析
看了这两处地方 我们可以发现 我们所写的jsp页面最终变成了java程序
浏览器向服务器发送请求 ,不管访问什么资源 ,其实都是在访问Servlet
JSP最终也会转换成一个Java类

打开此文件

详解JSP——从源码分析

1:验证JSP本身就是一个Servlet类

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

发现extends org.apache.jasper.runtime.HttpJspBase
然而HttpJspBase 又继承了HttpServlet
所以这个类本身就是Servlet

最终还是变成以前那种手动输出页面的方式实现
详解JSP——从源码分析

2:查看该Java类的代码 就是Servlet接口中三个代表生命周期的方法


  public void _jspInit() {
  		//初始化方法
  }

  public void _jspDestroy() {
  		//销毁方法
  }

  public void _jspService(HttpServletRequest request,HttpServletResponse response){
	  //调用JSP的Service
  }

3:查看该_jspService方法中的代码

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

    if (!javax.servlet.DispatcherType.ERROR.equals(request.getDispatcherType())) {
      final java.lang.String _jspx_method = request.getMethod();
      if ("OPTIONS".equals(_jspx_method)) {
        response.setHeader("Allow","GET, HEAD, POST, OPTIONS");
        return;
      }
      if (!"GET".equals(_jspx_method) && !"POST".equals(_jspx_method) && !"HEAD".equals(_jspx_method)) {
        response.setHeader("Allow","GET, HEAD, POST, OPTIONS");
        response.sendError(HttpServletResponse.SC_METHOD_NOT_ALLOWED, "JSP 只允许 GET、POST 或 HEAD。Jasper 还允许 OPTIONS");
        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");
      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("<html>\n");
      out.write("<body>\n");
      out.write("<h2>Hello World!</h2>\n");
      out.write("</body>\n");
      out.write("</html>\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);
    }
  }

3_1:判断请求类型(执行 get | post )

if (!javax.servlet.DispatcherType.ERROR.equals(request.getDispatcherType())) {
      final java.lang.String _jspx_method = request.getMethod();
      if ("OPTIONS".equals(_jspx_method)) {
        response.setHeader("Allow","GET, HEAD, POST, OPTIONS");
        return;
      }
      if (!"GET".equals(_jspx_method) && !"POST".equals(_jspx_method) && !"HEAD".equals(_jspx_method)) {
        response.setHeader("Allow","GET, HEAD, POST, OPTIONS");
        response.sendError(HttpServletResponse.SC_METHOD_NOT_ALLOWED, "JSP 只允许 GET、POST 或 HEAD。Jasper 还允许 OPTIONS");
        return;
      }
    }

3_2:内置对象

 final javax.servlet.jsp.PageContext pageContext;	//页面上下文
    javax.servlet.http.HttpSession session = null;	//session
    final javax.servlet.ServletContext application;	//applicationContext 就是ServletContext改名而已
    final javax.servlet.ServletConfig config;		//config
    javax.servlet.jsp.JspWriter out = null;			//out
    final java.lang.Object page = this;				//page代表当前页
    HttpServletRequest request						//请求
    HttpServletResponse response					//响应

3_3:输出页面前的代码用途

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;

以上这些对象 我们可以在JSP页面中直接使用

执行流程图解:

详解JSP——从源码分析

下面我们来编写一个简单的JSP Demo看一下

<%@ page pageEncoding="utf-8" %>
<html>
<body>
<h2>哈喽 潮汕奴仔</h2>
<%
    String name ="潮汕奴仔";
%>
欢迎:<%= name %>
</body>
</html>

在<% 代码 %>的代码就是Java代码

运行显示

详解JSP——从源码分析
运行的时候如果你没关闭原来的最终文件 他会提示
详解JSP——从源码分析

接下来查看最终的Java文件
详解JSP——从源码分析
详解JSP——从源码分析
对比之下 整个Java文件中只有输出页面的这部分代码发生变化

结论:

在JSP页面中,只要是Java代码就会原封不动的输出
如果是HTML代码 ,就会被转换为 out.print() 的格式输出

上一篇:JSP_01


下一篇:JSP