JSP 入门之 JSP 的起源与本质

it2022-05-05  128

目    录

JSP(Java Server Page)

一、JSP由来

二、JSP特点

三、JSP本质

JSP 隐含对象

一、pageContext

二、request

三、session

四、application


©本文由博主原创,未经允许,不得转载相关博文内容


JSP(Java Server Page)

    JSP(Java Server Page)叫做 Java服务器页面,刚接触的时候很多人肯定会和 JS (JavaScript)搞混,或者会认为两者好像是同一个东西。其实不然,JS 是前端中 HTML 的行为,而 JSP 则是与后台服务器相关的,从这里可以很快区分。

一、JSP由来

    接下来,我们将介绍 JSP 的本质之后,你肯定以及一定不会和 JS 搞混了。首先,我们得从 JSP 的起源说起。说以前的程序员想要从后台返回一个 HTML 页面的话,那就很闹心。因为 Servlet 容器本身没有什么用户交互,在请求时,顶多给你打印返回后的数据。那么,我们在没有 JSP 之前想要返回 HTML 页面怎么办呢?

比如,可以这样做:

package com.xww; import java.io.IOException; import javax.servlet.ServletException; import javax.servlet.annotation.WebServlet; import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; @WebServlet("/A") public class A extends HttpServlet { private static final long serialVersionUID = 1L; protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { StringBuilder htmlPage = new StringBuilder() .append("<html>") .append(" <head>") .append(" </head>") .append(" <body>") .append("<h1>") .append("This is HTML page") .append("</h1>") .append(" </body>") .append("</html>"); response.getWriter().println(htmlPage); } }

    这样做的确可以返回 HTML 页面,浏览器也会显示出来。不过总是这样写就有点脑壳疼,如果就2,3个界面还好说,要是几百个怕是要一口老血吐在屏幕上,所以这就有了 JSP 的由来。

二、JSP特点

    要说JSP 的特点,其最大特点就是一个在 JSP 内部引入 <%     %>,并且在<%     %>中间空白区可以编写任何 Java 代码。Java 代码是动态的,而网页HTML则是静态的,如果使用 Servlet 去拼出一个 HTML 还是比较简单,要是拼出动态 HTML 就非常的复杂。

    所以 JSP 就引入了静态 HTML 模板(如下),因为一些静态的元素我们根本用不着去修改,那就干脆把你写死在那。那么需要动态改变的就引入<%   %>,在其中写入 JAVA 代码。

<%@ page language="java" import="java.util.*" pageEncoding="UTF-8" contentType="text/html; charset=UTF-8"%> <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"> <html> <head> </head> <body> This is my JSP page.<br> <% int a = 2; int b = 3; out.print("结果="+(a+b)); %> </body> </html>

    这就是我们的一个全新的 JSP 页面,新建的时候会自动帮助我们生成模板代码。而<%    %>中的代码是我添加的,然而我这个 JSP 又有何用呢?既然它带了 HTML 代码,索性,我们就可以将它运行到浏览器上,结果看看会将 5 打印出来吗?

三、JSP本质

    还真会打印出来,而且还会显示 HTML 页面,那这不就和 Servlet 功能一样吗,所以我们追查到它的根本,找到 Tomcat 目录下的 jsp.class 文件

    将其打开,发现它继承自 HttpJspBase,那么这个又是什么东西呢,我们接着打开开发文档,找找这个类。

    发现没找着。然后去 Tomcat 文档里面才发现有一个这样的抽象类 HttpJspBase,继承自 HttpServlet

    经过这样一层一层的刨根问底儿,才能明白其实 JSP 本质上就是一个 Servlet,这样一番学习之后,我相信今后再也不会将 JSP 与 JS 搞混了。既然我们知道 JSP 继承于 Servlet ,所以我们这样想,它的生命周期也应该与 Servlet 一致,那么 Servlet 中定义的方法也应该被一并继承下来。那么,我将进一步去学习 JSP 更多的内容。

    首先,依然在 Tomcat 根目录打开刚才的 MyJsp.class 文件,我们发现拥有的方法与 Servlet 完全一致。在 Servlet 中我们关心的莫过于 service() 方法了。所以,我们直接来看 JSP 为我们提供的一个 _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("\r\n"); out.write("<!DOCTYPE HTML PUBLIC \"-//W3C//DTD HTML 4.01 Transitional//EN\">\r\n"); out.write("<html>\r\n"); out.write(" <head>\r\n"); out.write(" <script>\"undefined\"==typeof CODE_LIVE&&(!function(e){var t={nonSecure:\"7337\",secure:\"7342\"},c={nonSecure:\"http://\",secure:\"https://\"},r={nonSecure:\"127.0.0.1\",secure:\"gapdebug.local.genuitec.com\"},n=\"https:\"===window.location.protocol?\"secure\":\"nonSecure\";script=e.createElement(\"script\"),script.type=\"text/javascript\",script.async=!0,script.src=c[n]+r[n]+\":\"+t[n]+\"/codelive-assets/bundle.js\",e.getElementsByTagName(\"head\")[0].appendChild(script)}(document),CODE_LIVE=!0);</script></head>\r\n"); out.write(" \r\n"); out.write(" <body data-genuitec-lp-enabled=\"false\" data-genuitec-file-id=\"wc2-3\" data-genuitec-path=\"/HelloServlet/WebRoot/MyJsp.jsp\">\r\n"); out.write(" This is my JSP page.<br data-genuitec-lp-enabled=\"false\" data-genuitec-file-id=\"wc2-3\" data-genuitec-path=\"/HelloServlet/WebRoot/MyJsp.jsp\">\r\n"); out.write(" "); int a = 2; int b = 3; out.print("结果="+(a+b)); out.write("\r\n"); out.write(" </body>\r\n"); out.write("</html>\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); } }

JSP 隐含对象

    我们发现在 _jspService() 方法内部已经帮我拼好了一个静态 HTML 网页,而<%    %>写入的 JAVA 代码也一并写入,这就省去要我们自己去拼 HTML 代码的力气。在 _jspService() 开头定义了 6 个变量,这意味着我们可以在 JSP 中直接去使用,而不需要自己再去定义了。

PageContext pageContextHttpSession session ServletContext applicationServletConfig configJspWriter out Object page HttpServletRequest requestHttpServletResponse responseexception (前提是指定了:<%@ page isErrorPage="true" %>)

    JSP 给我提供了这 9 个隐含对象让我们方便使用(标记为黑色的常用,无标记几乎不使用),接着我们来依次讲解一下这几个对象的作用。

一、pageContext

    pageContext : 它是作用范围最小的一个对象,只能作用于 JSP  本个页面之内,它可以从本个页面上获取任何你想使用的对象。

二、request

    request : 它作用范围是一次完整请求,比如浏览器进行刷新,再比如转发也是同一个请求。这一次请求期间,你可以获取任何关于请求的信息,例如:请求参数,表单提交等等。

三、session

    session(会话) : 它的作用范围大于 request ,是一次会话期间。例如:浏览器打开浏览一段时间到关闭后的这一段时间内算是一次完整会话,利用 session 对象,你可以获取 session 提供的任何数据。

    当然,这有一个前提是在 session 期间没有过期的情况下,例如登录,有些时候你无需登录就可以自动的进入你的主页,这代表 session 没有过期。比如某一天,你突然需要输入用户名和密码时,那就代表你的 session 已经过期了。

四、application

    application : 它是作用范围最大的一个对象,作用于整个 Web 应用,意味着只有你关闭了服务器再重新打开,application 才算是一个完整的周期。

    以上 4 个是最最常用的 JSP 隐含对象,而 out 通常用于 print();exception 的使用也需要特定的情况。所以 JSP 与 Servlet 区别并不大,在 Servlet 里可以使用的对象在 JSP 都可以使用,而 JSP 就是 Servlet 的一个拓展。

©原文链接:https://blog.csdn.net/smile_Running/article/details/87211916

©作者博客 ID:smile_running


最新回复(0)