JSP讲解

83 阅读3分钟

本文已参与[新人创作礼]活动,一起开启掘金创作之路。

哈喽,大家好!我是Why,一名在读学生,目前刚刚开始进入自己的编程学习生涯。虽然学习起步较晚,但我坚信做了才有0或1的可能。学了一段时间以后也是选择在掘金上分享自己的日常笔记,也希望能够在众多道友的大家庭中打成一片。 本文主要讲解JSP,如果大家读后觉得有用的话,还请大家多多支持博主:欢迎 ❤️点赞👍、收藏⭐、留言💬 ✨✨✨个人主页:JinHuan

JSP与Servlet的分工与联系

 1、JSP与Servlet的分工
     Servlet
         负责处理业务并得到处理结果--------------------------------------厨师负责做菜,做好交给传菜员
     JSP
         不负责处理业务,主要负责将Servlet的处理结果写入到响应体中--------传菜员负责传菜给响应体
 ​
 2、Servlet与JSP之间的关系
         Servlet工作完毕后,通过Tomcat调用Jsp
         request.getRequestDispatcher("/目标JSP文件").forward(request,response);
 ​
 3、Servlet与Jsp二者之间如何实现数据共享?
     Servlet将【处理结果】放到【请求作用域对象】中
          request.setAttributes("处理结果");
 ​
     Jsp在运行的时候从【请求作用域对象】得到处理结果并把它放到【响应体】中
         request.getRequestDispatcher("/目标JSP文件").forward(request,response);
 ​

JSP文件运行原理

HTTP服务器调用JSP文件步骤
 'servlet规范中说到'
     '只有servlet接口的实现类,才能被浏览器调用,但是JSP文件是怎么调用的呢?'
  
 1、Http服务器将JSP文件内容编辑为一个'Servlet接口实现类(.java)'
 2、Http服务器将Servlet接口实现类【编译】为一个class文件(.class)
 3、Http服务器负责创建这个class文件的实例对象————即Servlet实例对象
 4、HTTP服务器通过该Servlet实例对象调用'_jspServices方法',将jsp文件内容写入到响应体中
Http服务器【编辑】和【编译】JSP文件的位置
 在
 C:\Users\尽欢.IntelliJIdea2018.3\system\tomcat\Unnamed_JSP教程\work\Catalina\localhost\myWeb\org\apache\jsp
 这个文件夹中
实例
 <%--
   Created by IntelliJ IDEA.
   User: 尽欢
   Date: 2021/11/18
   Time: 17:08
   To change this template use File | Settings | File Templates.
 --%>
 <%@ page contentType="text/html;charset=UTF-8" language="java" %>
 <%--
 第一部分
     纯文本
 --%>
 Hello world
 <br>
 <%--
 第二部分
     含有java命令
 --%>
 <%
     int num1 =  10;
     int num2 =  20;
 %>
 num1 + num2的值是:<%=num1+num2%><br>
 ​
 <%--
 第三部分
     拆分的java语句(检验是否一个JSP文件中所有的<%%>中的语句是一个整体
 --%>
 <%
     for(int i = 0;i < 10;i++){
 %>
 <br>
 <font size="12">i的值是<%=i%></font><br>
 <%
     }
 %>
编译后的代码
 /*
  * Generated by the Jasper component of Apache Tomcat
  * Version: Apache Tomcat/9.0.30
  * Generated at: 2021-11-18 09:20:19 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 check_jsp extends org.apache.jasper.runtime.HttpJspBase
     //这个java类check_jsp继承了org.apache.jasper.runtime.HttpJspBase
     //而org.apache.jasper.runtime.HttpJspBase的父类实现了Servlet接口,所以是一个货真价实的Servlet接口实现类
     implements org.apache.jasper.runtime.JspSourceDependent,
                  org.apache.jasper.runtime.JspSourceImports {
 ​
   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;
 ​
   private static final java.util.Set<java.lang.String> _jspx_imports_packages;
 ​
   private static final java.util.Set<java.lang.String> _jspx_imports_classes;
 ​
   static {
     _jspx_imports_packages = new java.util.HashSet<>();
     _jspx_imports_packages.add("javax.servlet");
     _jspx_imports_packages.add("javax.servlet.http");
     _jspx_imports_packages.add("javax.servlet.jsp");
     _jspx_imports_classes = null;
   }
 ​
   private volatile javax.el.ExpressionFactory _el_expressionfactory;
   private volatile org.apache.tomcat.InstanceManager _jsp_instancemanager;
 ​
   public java.util.Map<java.lang.String,java.lang.Long> getDependants() {
     return _jspx_dependants;
   }
 ​
   public java.util.Set<java.lang.String> getPackageImports() {
     return _jspx_imports_packages;
   }
 ​
   public java.util.Set<java.lang.String> getClassImports() {
     return _jspx_imports_classes;
   }
 ​
   public javax.el.ExpressionFactory _jsp_getExpressionFactory() {
     if (_el_expressionfactory == null) {
       synchronized (this) {
         if (_el_expressionfactory == null) {
           _el_expressionfactory = _jspxFactory.getJspApplicationContext(getServletConfig().getServletContext()).getExpressionFactory();
         }
       }
     }
     return _el_expressionfactory;
   }
 ​
   public org.apache.tomcat.InstanceManager _jsp_getInstanceManager() {
     if (_jsp_instancemanager == null) {
       synchronized (this) {
         if (_jsp_instancemanager == null) {
           _jsp_instancemanager = org.apache.jasper.runtime.InstanceManagerFactory.getInstanceManager(getServletConfig());
         }
       }
     }
     return _jsp_instancemanager;
   }
 ​
   public void _jspInit() {
   }
 ​
   public void _jspDestroy() {
   }
 /*
 重点
     _jspServices方法
 */
   public void _jspService(final javax.servlet.http.HttpServletRequest request, final javax.servlet.http.HttpServletResponse response)
       //这个方法中的参数,就是Servlet在调用JSP文件的时候传进来的response和request
       //request.getRequestDispatcher("/目标JSP文件").forward(request,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;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("\r\n");
       out.write("\r\n");
       out.write("\r\n");
       out.write("Hello world\r\n");
       out.write("<br>\r\n");
       out.write('\r');
       out.write('\n');
 //java代码
     int num1 =  10;
     int num2 =  20;
 ​
       out.write("\r\n");
       out.write("num1 + num2的值是:");
       out.print(num1+num2);
       out.write("<br>\r\n");
       out.write("\r\n");
       out.write('\r');
       out.write('\n');
 //检验完整性,都是通过out.write()和out.print()来写的
     for(int i = 0;i < 10;i++){
 ​
       out.write("\r\n");
       out.write("<br>\r\n");
       out.write("<font size="12">i的值是");
       out.print(i);
       out.write("</font><br>\r\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);
     }
   }
 }