JSP和Servlet的关系

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/fighting_sxw/article/details/80333158

一、JSP和Servlet的关系
当访问一个JSP页面的时候,tomcat(获取其他web容器)会将JSP转化成一个Servlet,JSP其实就是一个Servlet

以Tomcat为例:
在eclipse中新建一个hello.jsp页面,然后发布到Tomcat中:
hello.jsp

<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>Insert title here</title>
</head>
<body>
    <h1>hello JSP!!!</h1>
</body>
</html>

然后访问这个页面,此时在Tomcat/work/Catalina/localhost/WebDemo/org/apache/jsp目录下得到了两个文件:
这里写图片描述

打开hello_jsp.java:

/*
 * Generated by the Jasper component of Apache Tomcat
 * Version: Apache Tomcat/7.0.77
 * Generated at: 2018-05-16 09:02:07 UTC
 * Note: The last modified time of this file was set to
 *       the last modified time of the source file after
 *       generation to assist with modification tracking.
 */
package org.apache.jsp;

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

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

//...省略部分代码...

  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=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("<!DOCTYPE html PUBLIC \"-//W3C//DTD HTML 4.01 Transitional//EN\" \"http://www.w3.org/TR/html4/loose.dtd\">\n");
      out.write("<html>\n");
      out.write("<head>\n");
      out.write("<meta http-equiv=\"Content-Type\" content=\"text/html; charset=UTF-8\">\n");
      out.write("<title>Insert title here</title>\n");
      out.write("</head>\n");
      out.write("<body>\n");
      out.write("    <h1>hello JSP!!!</h1>\n");
      out.write("</body>\n");
      out.write("</html>");
    } 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);
    }
  }
}

也就是说hello.jsp 被Tomcat转化成了一个名字叫hello_jsp的类,hello_jsp继承HttpJspBase。

 * Licensed to the Apache Software Foundation (ASF) under one or more

package org.apache.jasper.runtime;

import java.io.IOException;

import javax.servlet.ServletConfig;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.jsp.HttpJspPage;

import org.apache.jasper.compiler.Localizer;

/**
 * This is the super class of all JSP-generated servlets.
 *
 * @author Anil K. Vijendran
 */
public abstract class HttpJspBase extends HttpServlet implements HttpJspPage {

    private static final long serialVersionUID = 1L;

    protected HttpJspBase() {
    }

    @Override
    public final void init(ServletConfig config) 
        throws ServletException 
    {
        super.init(config);
        jspInit();
        _jspInit();
    }

    @Override
    public String getServletInfo() {
        return Localizer.getMessage("jsp.engine.info");
    }

    @Override
    public final void destroy() {
        jspDestroy();
        _jspDestroy();
    }

    /**
     * Entry point into service.
     */
    @Override
    public final void service(HttpServletRequest request, HttpServletResponse response) 
        throws ServletException, IOException 
    {
        _jspService(request, response);
    }

    @Override
    public void jspInit() {
    }

    public void _jspInit() {
    }

    @Override
    public void jspDestroy() {
    }

    protected void _jspDestroy() {
    }

    @Override
    public abstract void _jspService(HttpServletRequest request, 
                                     HttpServletResponse response) 
        throws ServletException, IOException;
}

HttpJspBase继承的是HttpServlet,最终还是演变成了通过Servlet与客户端进行交互,调用的还是Servlet中的方法,HttpJspBase可以理解为对HttpServlet的一种装饰。

从上述代码中可以看出hello.jsp中的<h1>hello JSP!!!</h1>,最终是在hello_jsp的_jspService方法中,通过out.write(" <h1>hello JSP!!!</h1>\n")向页面输入,也就是说,页面中的HTML代码都是这样输出到页面的。

二、jsp脚本

jsp脚本有下面三种形式:

  • <%java代码%>:最终是在service方法中执行这些代码
  • <%=java变量或者表达式>:向页面输出变量的内容或者表达式的结果,最终是在service方法内部,调用out.print(),向页面输出的。
  • <%!java代码%>:最终会被转化为servlet的成员内容。

hello.jsp

<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>Insert title here</title>
</head>
<body>
    <h1>hello JSP!!!</h1>
    <%
        String Loki="We hava an army!!!";
        System.out.println("Loki:"+Loki);
        Stark();
    %>

    <%="Loki:"+Loki+"<br/>"+"Stark:"+stark%>

    <%!
       String stark="We have an Hulk!!!";
       public void Stark(){
           System.out.println("Stark:"+stark);
       }
    %>
</body>
</html>

转化为hello_jsp:

/*
 * Generated by the Jasper component of Apache Tomcat
 * Version: Apache Tomcat/7.0.77
 * Generated at: 2018-05-16 09:43:29 UTC
 * Note: The last modified time of this file was set to
 *       the last modified time of the source file after
 *       generation to assist with modification tracking.
 */
package org.apache.jsp;

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

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

       /* 对应于<%!java代码%>*/
       String stark="We have an Hulk!!!";
       public void Stark(){
           System.out.println("Stark:"+stark);
       }
    //。。。省略部分代码。。。

  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=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("<!DOCTYPE html PUBLIC \"-//W3C//DTD HTML 4.01 Transitional//EN\" \"http://www.w3.org/TR/html4/loose.dtd\">\n");
      out.write("<html>\n");
      out.write("<head>\n");
      out.write("<meta http-equiv=\"Content-Type\" content=\"text/html; charset=UTF-8\">\n");
      out.write("<title>Insert title here</title>\n");
      out.write("</head>\n");
      out.write("<body>\n");

      /* 对应于h1标签*/
      out.write("    <h1>hello JSP!!!</h1>\n");
      out.write("    ");

        /* 对应于<%java代码%>*/
        String Loki="We hava an army!!!";
        System.out.println("Loki:"+Loki);
        Stark();

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

      /* 对应于<%=java变量%>*/
      out.print("Loki:"+Loki+"<br/>"+"Stark:"+stark);
      out.write("\n");
      out.write("    \n");
      out.write("    ");
      out.write("\n");
      out.write("</body>\n");
      out.write("</html>");
    } 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);
    }
  }
}

可以看出,在hello.jsp页面使用JSP脚本写的Java代码,最终都会转化到hello_jsp中的java代码。

所以:JSP就是Servlet!!!

阅读更多
想对作者说点什么?

博主推荐

换一批

没有更多推荐了,返回首页