• 【JavaWeb】JSP技术详解


    在这里插入图片描述
    本文被 系统学习JavaWeb 收录点击订阅专栏



    1 初探JSP

    1.1 何为JSP?

    JSP(java server pages), 即Java的服务器界面。其主要作用是 代替 Servlet 程序回传 html 页面数据。
    因为 Servlet 程序回传 html 页面数据很繁琐,维护成本比较高。

    如果通过Servlet程序回传html数据,演示代码如下:

    import javax.servlet.ServletException;
    import javax.servlet.http.HttpServlet;
    import javax.servlet.http.HttpServletRequest;
    import javax.servlet.http.HttpServletResponse;
    import java.io.IOException;
    import java.io.PrintWriter;
    
    /**
     * @author 兴趣使然黄小黄
     * @version 1.0
     * 演示传统Servlet回传html数据的繁琐
     */
    public class PrintHtml extends HttpServlet {
        @Override
        protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
            //通过响应的输出流回传html页面数据
            resp.setContentType("text/html;charset=UTF-8");
            PrintWriter writer = resp.getWriter();
            writer.write("\r\n");
            writer.write("\r\n");
            writer.write("\r\n");
            writer.write("    \r\n");
            writer.write("    Title\r\n");
            writer.write("\r\n");
            writer.write("\r\n");
            writer.write("这是html页面数据\r\n");
            writer.write("\r\n");
            writer.write("\r\n");
            writer.write("\r\n");
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31

    而实际开发时,html的代码多达千行万行,可见,传统Servlet程序回传html的方式相当繁琐!

    而JSP的主要作用就是代替Servlet程序回传html页面的数据:
    在这里插入图片描述

    <%@ page contentType="text/html;charset=UTF-8" language="java" %>
    <html>
    <head>
        <meta charset="UTF-8">
        <title>Titletitle>
    head>
    <body>
    这是html页面数据
    body>
    html>
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10

    如何访问JSP页面?
    a.jsp访问地址:http://ip:port/工程路径/a.jsp

    1.2 JSP的本质

    jsp页面的本质是一个Servlet程序。

    当第一次访问jsp页面时,Tomcat服务器会帮我们把jsp页面翻译成为一个java源文件,并将它翻译成为.class字节码文件。
    在这里插入图片描述
    源代码中,jsp页面所翻译出来的类继承了HttpJSPBase类,该类直接继承了HttpServlet类。即,jsp翻译出来的java类,间接继承了HttpServlet类,是一个Servlet程序。


    2 JSP的page指令

    jsp的page指令可以修改jsp页面中的一些重要属性或行为。
    在这里插入图片描述

    属性说明
    language属性表示jsp翻译后是什么语言文件,目前只支持java
    contentType属性表示jsp返回的数据类型。也是源码中response.setContentType()的参数值
    pageEncoding属性表示当前jsp页面文件本身的字符集
    import属性用于导包,导类
    autoFlush属性设置当out输出流缓冲区满了之后,是否自动刷新缓冲区,默认值是true
    buffer属性设置out缓冲区的大小,默认8kb
    errorPage属性设置当jsp页面运行出错时,自动跳转的错误页面路径
    isErrorPage属性设置当前jsp页面是否有错误信息,默认是false,如果是true可以获取异常信息
    session属性设置访问当前jsp页面,是否会创建HttpSession对象,默认是true
    extends属性设置jsp翻译出来的java类默认继承的父类

    3 JSP中的常用脚本

    3.1 声明脚本

    声明脚本的语法格式:

    <%! 声明java代码 %>
    
    • 1

    可以给jsp翻译出来的java类定义属性和方法,甚至是静态代码块,内部类等。

    演示代码如下:

    <%@ page import="java.util.Map" %>
    <%@ page import="java.util.HashMap" %><%--
      Created by IntelliJ IDEA.
      User: 26510
      Date: 2022/10/17
      Time: 8:52
      To change this template use File | Settings | File Templates.
    --%>
    <%@ page contentType="text/html;charset=UTF-8" language="java" %>
    <html>
    <head>
        <meta charset="UTF-8">
        <title>Title</title>
    </head>
    <body>
    <%--1.声明类属性--%>
    <%!
        private String id;
        private String name;
        private int age;
        private static Map<String, Object> map;
    %>
    
    <%--2.声明static静态代码块--%>
    <%!
        static {
            map = new HashMap<String, Object>();
            map.put("key1", "value1");
            map.put("key2", "value2");
        }
    %>
    
    <%--3.声明类方法--%>
    <%!
        public int sum(int a, int b){
            return a+b;
        }
    %>
    
    <%--4.生成内部类--%>
    <%!
        public static class A{
            private String telephone;
        }
    %>
    
    </body>
    </html>
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48

    3.2 表达式脚本(常用)

    表达式脚本的语法格式:

    <%= 表达式 %>
    
    • 1

    可以在jsp页面上输出数据。

    演示代码如下:

    <%--1.输出整型--%>
    <%=12  %><br>
    
    <%--2.输出浮点型--%>
    <%=12.12 %><br>
    
    <%--3.输出字符串--%>
    <%="我是黄小黄" %><br>
    
    <%--4.输出对象--%>
    <%=map %><br>
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11

    表达式脚本的特点:

    1. 所有的表达式脚本都会被翻译到_jspService方法中
    2. 表达式脚本会被翻译成为out.print()输出到页面上
    3. 由于表达式脚本翻译的内容都在_jspService方法中,所以_jspService方法中的对象都可以直接使用
    4. 表达式脚本中的表达式不能以分号结束

    3.3 代码脚本

    代码脚本的语法格式:

    <% java语句 %>
    
    • 1

    可以在jsp页面中,编写自己需要的功能。

    演示代码如下:

    <%--1.代码脚本:if语句--%>
    <%
        int i = 10;
        if (i == 10){
            System.out.println("i = 10");
        }else {
            System.out.println("i != 10");
        }
    %>
    
    <%--2.代码脚本:for语句--%>
    <%
        for (int j = 0; j < 10; j++) {
            System.out.println(j);
        }
    %>
    
    <%--3.翻译后java文件中_jspService方法内的代码都可以写--%>
    <%
        String username = request.getParameter("username");
        System.out.println("username = " + username);
    %>
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22

    代码脚本的特点:

    1. 代码脚本翻译后在_jspService方法中
    2. 所有在_jspService方法中的现有对象都可以直接使用
    3. 可以由多个代码脚本组合成一个完整的java语句
    4. 代码脚本可以与表达式脚本一起组合使用,在jsp页面上输出数据
    <%
        for (int j = 0; j < 10; j++) {
            
    %>
    <%=j %>
    <% 
        }
    %>
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8

    3.4 关于注释的说明

    在jsp中分为三种注释:

    • html注释
    
    
    • 1

    该注释会被翻译在java源代码中,在_jspService方法中,以out.write输出到客户端。

    • java注释
    //单行注释
    /*多行注释*/
    
    • 1
    • 2

    java注释会被翻译到java源代码中。

    • jsp注释
    <%--这是jsp注释--%>
    
    • 1

    jsp注释可以注释掉jsp中所有代码。

    3.5 练习:在jsp页面中输出乘法表

    test.jsp

    <%@ page contentType="text/html;charset=UTF-8" language="java" %>
    <html>
    <head>
        <title>乘法表</title>
    </head>
    <body>
    <table>
      <%for (int i = 1; i <= 9; i++) {%>
      <tr>
          <%for (int j = 1; j <= i; j++) {%>
        <td><%=j + "x" + i + "=" + (j*i)%></td>
          <%}%>
      </tr>
        <%}%>
    </table>
    </body>
    </html>
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17

    在这里插入图片描述


    4 JSP的内置对象

    jsp的内置对象,是指,Tomcat服务器在翻译jsp页面成为Servlet源代码后,内部提供的九大对象。

    4.1 jsp的九大对象概览

    对象说明
    request请求对象
    response响应对象
    pageContextjsp的上下文对象
    session会话对象
    applicationServletContext对象
    configServletConfig对象
    outjsp的输出流对象
    page指向当前的jsp对象
    exception异常对象

    其中exception异常对象需要在page指令的参数isErrorPage="true"时才存在。

    4.2 四大域对象

    域对象是可以像Map一样存取数据的对象,四个域对象的功能一样,区别是对数据的存取范围。

    下表列举了四个域对象和作用范围

    对象作用范围
    pageContext(PageContextImpl类)当前jsp页面范围
    request(HttpServletRequest类)一次请求内
    session(HttpSession类)一个会话范围内(打开浏览器访问服务器,直到关闭浏览器)
    application(ServletContext类)整个web工程范围内有效(只要web工程不停止,数据都在)

    在进行代码演示前,需要导入Tomcat中lib目录下的jsp与Servlet的jar包!
    在这里插入图片描述

    演示代码如下:

    <%@ page contentType="text/html;charset=UTF-8" language="java" %>
    <html>
    <head>
        <title>Title</title>
    </head>
    <body>
    <h1>scope.jsp页面</h1>
    <%
        //在四个域中都分别保存了数据
        pageContext.setAttribute("key", "pageContext");
        request.setAttribute("key", "request");
        session.setAttribute("key", "session");
        application.setAttribute("key", "application");
    %>
    pageContext域是否有值:<%=pageContext.getAttribute("key")%>
    request域是否有值:<%=pageContext.getAttribute("key")%>
    session域是否有值:<%=pageContext.getAttribute("key")%>
    application域是否有值:<%=pageContext.getAttribute("key")%>
    </body>
    </html>
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20

    可以尝试多创建一个jsp页面,关闭浏览器,再次部署web项目打开服务器的方式一步步扩大范围,最终结果与表中所述一致!

    四个域对象虽然都可以存取数据,但是 具有自己的优先顺序,优先级从小到大如下:

    1. pageContext
    2. request
    3. session
    4. application

    4.3 out输出与response.getWriter输出的区别

    response表示响应,用于设置返回给客户端的内容(输出);
    out 也是给用户输出使用的。

    演示案例:
    虽然out语句在response之前,但是结果确是response在前,out在后。

    <%@ page contentType="text/html;charset=UTF-8" language="java" %>
    <html>
    <head>
        <title>Title</title>
    </head>
    <body>
    <%
        out.write("out输出1 
    "
    ); out.write("out输出2
    "
    ); response.getWriter().write("response输出1
    "
    ); response.getWriter().write("response输出2
    "
    ); %> </body> </html>
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14

    在这里插入图片描述
    过程图解如下:
    在这里插入图片描述
    当jsp页面中的所有代码执行完成后会做如下的操作:

    1. 执行out.flush()操作,把out缓冲区中的数据追加写入到response缓冲区末尾
    2. 执行response的刷新操作,把数据写给客户端

    由于jsp翻译的servlet程序中源码都是out进行输出的,为了避免打乱页面的内容顺序,所以在jsp中一般统一使用out输出。

    关于out.write()与out.print()

    方法说明
    out.write()输出字符串
    out.print()输出任意数据类型(转换成字符串后调用了write输出

    5 JSP中的常用标签

    5.1 静态包含

    静态包含一般用于加载进页面显示后就再也不变的东西, 比如页眉、背景、标题等等。静态包含不会检查所含文件的变化,把文件包含进来后,被包含文件的修改变化是不会影响已被包含进来的内容的。

    静态包含发生在编译阶段。比如:a.jsp中使用了语句 <%@ include file=“b.jsp”%>,把b.jsp包含了进来,那么在编译a.jsp文件时, 会直接把b.jsp文件的内容全部内嵌到a.jsp文件中包含b的语句的位置。 然后运行a,显示a页面。也就是说,静态include是先把被包含文件的内容全部复制内嵌到包含文件中,再进行编译运行的。也 正是因为要把b包含进a,所以b中的变量等不能与a重复,否则会报错。

    演示案例:将footer.jsp内嵌在main.jsp中

    footer.jsp

    <%@ page contentType="text/html;charset=UTF-8" language="java" %>
    <html>
    <head>
        <title>Titletitle>
    head>
    <body>
    脚页信息<br>
    body>
    html>
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9

    main.jsp

    <%@ page contentType="text/html;charset=UTF-8" language="java" %>
    <html>
    <head>
        <title>Titletitle>
    head>
    <body>
    头部信息<br>
    主体内容<br>
    <%@include file="/include/footer.jsp"%>
    body>
    html>
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11

    在这里插入图片描述
    静态包含小结:

    • 静态包含不会翻译被包含的jsp页面;
    • 静态包含实际上是把被包含的jsp页面的代码拷贝到包含的位置执行输出。

    5.2 动态包含

    动态包含用于加载经常变化的、要求显示最新版本内容的东西。 比如提交时间戳:用户打开博客编辑页面时,有一个时间加载进来了。用户编写完博客,点击提交时,就应该使用/显示提交瞬间的时间而不是打开编辑页面时的那个时间。所以这里要用的就是最新时间。由上面我们知道,静态include是先包含进来,再编译,运行并传回浏览器显示的,所以不能满足我们要求某些部分使用最新内容的要求。那么,我们就要用到动态include。

    动态include与静态include的最大不同在于:包含文件与被包含文件都是先编译执行,再包含。二者的编译阶段是相互独立的,只有在包含文件的include语句处把被包含文件的执行结果包含进来。 换言之,包含文件先编译,执行。执行到了include语句的时候才触发被包含文件的编译、执行,并实时把结果包含进来。从而达到获取最新的被包含内容的目的。同样使用a.jsp包含b.jsp的例子:加入a.jsp中动态include了b.jsp。现在,a先编译成servlet类文件,然后运行,当运行到包含b的语句处,引起b的编译,运行,并把b的运行servlet运行结果包含进a。最后a顺利运行完毕,把a的servlet类运行结果输出到浏览器显示。

    案例代码:
    footer.jsp

    <%@ page contentType="text/html;charset=UTF-8" language="java" %>
    <html>
    <head>
        <title>Titletitle>
    head>
    <body>
    脚页信息<br>
    body>
    html>
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9

    main.jsp

    <%@ page contentType="text/html;charset=UTF-8" language="java" %>
    <html>
    <head>
        <title>Titletitle>
    head>
    <body>
    头部信息<br>
    主体内容<br>
    <jsp:include page="/include/footer.jsp">jsp:include>
    body>
    html>
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11

    运行结果页面与上个案例一致(但是底层原理和对象有区别)

    原理示意图:
    在这里插入图片描述

    动态包含小结:

    • 动态包含会把包含的jsp页面也翻译成java代码;
    • 动态包含底层代码使用如下代码调用被包含的jsp页面执行输出:
    JspRuntimeLibrary.include(request, response, "/include/footer.jsp", out, false);
    
    • 1
    • 动态包含可以传递参数。

    5.3 请求转发

    之前学过的请求转发:

    request.getRequestDispatcher("/include/footer.jsp").forward(request, response);
    
    • 1

    另一种形式

    <jsp:forward page="/include/footer.jsp"></jsp:forward>
    
    • 1

    写在最后

     本文部分内容参考:尚硅谷JavaWeb课程。好了,本文内容到这里就告一段落了,欢迎大家订阅专栏,加入JavaWeb学习!点击订阅

     如果你有任何问题,欢迎私信,感谢您的支持!
    在这里插入图片描述
    在这里插入图片描述

  • 相关阅读:
    软件项目管理 4.3.敏捷需求建模方法
    DCMM的定义和基础条件
    git设置代理
    光纤环形镜FBG传感器
    java计算机毕业设计springboot+vue小区防疫健康信息管理及出入登记平台
    2023.11.18 -自用hadoop高可用环境搭建命令
    我自己制作的导航页网站,源码分享~
    77 # koa 中间件的应用
    python数据分析(numpy)
    简要解析@SpringBootApplication
  • 原文地址:https://blog.csdn.net/m0_60353039/article/details/127356613