草庐IT

JSP基础知识总结

愚生浅末 2023-04-16 原文

目录

JSP概述

什么是 jsp

JSP(全称 Java Server Pages)是由 Sun 公司专门为了解决动态生成 HTML 文档的技术。

Servlet 程序输出 html 页面

在 jsp 技术之前,如果我们要往客户端输出一个页面。我们可以使用 Servlet 程序来实现。具体的代码如下:

public class HtmlServlet extends HttpServlet {
    private static final long serialVersionUID = 1L;
    protected void doGet(HttpServletRequest request,
                         HttpServletResponse response) throws ServletException, IOException {
        // 设置返回的数据内容的数据类型和编码
        response.setContentType("text/html; charset=utf-8");
        // 获取字符输出流
        Writer writer = response.getWriter();
        //输出页面内容
        writer.write("<!DOCTYPE html PUBLIC \"-//W3C//DTD HTML 4.01 Transitional//EN\"\"http://www.w3.org/TR/html4/loose.dtd\">");
        writer.write("<html>");
        writer.write("<head>");
        writer.write("<meta http-equiv=\"Content-Type\" content=\"text/html; charset=UTF-8\">");
        writer.write("<title>Insert title here</title>");
        writer.write("</head>");
        writer.write("<body>");
        writer.write("这是由 Servlet 程序输出的 html 页面内容!");
        writer.write("</body></html>");
    }
    protected void doPost(HttpServletRequest request,
                          HttpServletResponse response) throws ServletException, IOException {
    }
}

在浏览器中输入访问 Servlet 的程序地址得到以下结果:

从上面的代码可以发现。通过 Servlet 输出简单的 html 页面信息都非常不方便。
如果要输出一个复杂页面的时候,就更加的困难,而且不利于页面的维护和调试。
所以 sun 公司推出一种叫做 jsp 的动态页面技术来实现对页面的输出繁锁工作。

jsp 页面的访问不能像 HTML 页面一样拖到浏览器中。只能通过浏览器访问 Tomcat 服务器再访问 jsp 页面。

如何创建一个 jsp 动态页面程序

  1. 选中 Web 目录,右键创建一个 jsp 文件

  1. 输入 jsp 页面的文件名

  2. 在 body 标签中添加你想要显示的文本内容

  3. 先启动Tomcat服务器,

    然后在浏览器中输入 jsp 页面的访问地址。
    jsp 页面的访问地址和 html 页面的访问路径一样 http://ip:端口号/工程名/文件名
    也就是 http://127.0.0.1:8080/Test/Demo.jsphttp://localhost:8080/Test/Demo.jsp(以自己的工程路径为准)

    如何修改 jsp 文件的默认编码

    有些idea的默认编码格式可能是GBK格式或者其他格式的,然后在JSP编码时候可能会出现乱码,修改为UTF-8格式可以避免乱码。

注意事项:
1、jsp 页面是一个类似于 html 的一个页面。 jsp 直接存放到 WebContent 目录下,和 html 一样
访问 jsp 的时候,也和访问 html 一样
2、jsp 的默认编码集是 iso-8859-1 修改 jsp 的默认编码为 UTF-8

jsp 的运行原理

jsp的本质其实是一个Servlet程序。

首先我们去找到我们 Tomcat 的目录下的 work\Catalina\localhost 目录。

当我们新建Demo工程。并启动 Tomcat
服务器后。我们发现
在 work\Catalina\localhost 目录下多出来一个 JSPDemo目录。

一开始目录还是空目录。

然后,我们在浏览器输入一个 jsp 文件的访问路径访问。
比如 http://127.0.0.1:8080/JSPDemo/Demo.jsp访问Demo.jsp 文件
JSPDemo目录马上会生成 org\apache\jsp 目录。
并且在会中有两个文件。

Demo_jsp.class 文件很明显是 index_jsp.java 源文件编译后的字节码文件。
那么Demo_jsp.java 是个什么内容呢?
生成的 java 文件名,是以原来的文件名加上_jsp 得到。 xxxx_jsp.java 文件的名字
我们打开 Demo_jsp.java 文件查看里面的内容:
发现,生成的类继承于 HttpJspBase 类。这是一个 jsp 文件生成 Servlet 程序要继承的基类!!!

自动生成的java文件继承于HttpJspBase类

于是,关联源代码去查看一下 HttpJspBase 类的内容。从源码的类注释说明中,发现HttpJspBase 这个类就是所有 jsp 文件生成 Servlet 程序需要去继承的基类。并且这个 HttpJspBase 类继承于 HttpServlet 类。所以 jsp 也是一个 Servlet 小程序。

我们分别在工程的 Web 目录下创建多个 jsp 文件。然后依次访问。它们都被翻译为.java 文件并编译成为.class 字节码文件

打开 Demo_jsp.java 文件查看里面的内容可以发现。jsp 中的 html 页面内容都被翻译到 Servlet 中的 service
方法中直接输出。

小结:
从生成的文件我们不难发现一个规则。
a.jsp 翻译成 java 文件后的全名是 a_jsp.java 文件
b.jsp 翻译成 java 文件后的全名是 b_jsp.java 文件
么 那么 当我们访问 个 一个 xxx.jsp 文件后 成 翻译成 java 文件的全名是 xxx_jsp.java 文件
xxx_jsp.java 文件是一个 Servlet 程序。原来 jsp 中的 html 内容都被翻译到 Servlet 类的 service 方法中原样输出。

jsp 的语法

jsp 文件头部声明介绍(page 指令介绍)

<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8" %>

这是 jsp 文件的头声明。表示这是 jsp 页面。

属性 含义
language 属性值只能是 java,表示翻译的得到的是 java 语言的
contentType 设置响应头 contentType 的内容
pageEncoding 设置当前 jsp 页面的编码
import 给当前 jsp 页面导入需要使用的类包
autoFlush 设置是否自动刷新 out 的缓冲区,默认为 true
buffer 设置 out 的缓冲区大小。默认为 8KB
errorPage 设置当前 jsp 发生错误后,需要跳转到哪个页面去显示错误信息
isErrorPage 设置当前 jsp 页面是否是错误页面。是的话,就可以使用 exception 异常对象
session 设置当前 jsp 页面是否获取 session 对象,默认为 true
extends 给服务器厂商预留的 jsp 默认翻译的 servlet 继承于什么类

jsp 中的三种脚本介绍

一、声明脚本:

声明脚本格式如下:

<%!
java 代码
%>

在声明脚本块中,我们可以干 4 件事情
1.我们可以定义全局变量。
2.定义 static 静态代码块
3.定义方法
4.定义内部类
几乎可以写在类的内部写的代码,都可以通过声明脚本来实现

二、表达式脚本

表达式脚本格式如下:

<%=表达式 %>

表达式脚本 用于向页面输出内容。
表达式脚本 翻译到 Servlet 程序的 service 方法中 以 out.print() 打印输出
out 是 jsp 的一个内置对象,用于生成 html 的源代码
注意:表达式不要以分号结尾,否则会报错
表达式脚本可以输出任意类型。
比如:
1.输出整型
2.输出浮点型
3.输出字符串
4.输出对象

三、代码脚本

代码脚本如下:

<% java 代码 %>

代码脚本里可以书写任意的 java 语句。
代码脚本的内容都会被翻译到 service 方法中。
所以 service 方法中可以写的 java 代码,都可以书写到代码脚本中

jsp 中的注释

// 单行 java 注释
/*
多行 java 代码注释
*/
单行注释和多行注释能在翻译后的 java 源代码中看见。
<%-- jsp 注释 --%>
jsp 注释在翻译的时候会直接被忽略掉
<!-- html 注释 -->
html 的注释会被翻译到 java 代码中输出到 html 页面中查看

jsp 九大内置对象

我们打开翻译后的 java 文件。查看_jspService 方法。

通过源码可以发现 jsp 中九大内置对象分别是:

对象 含义
request 对象 请求对象,可以获取请求信息
response 对象 响应对象。可以设置响应信息
pageContext 对象 当前页面上下文对象。可以在当前上下文保存属性信息
session 对象 会话对象。可以获取会话信息
exception 对象 异常对象只有在 jsp 页面的 page 指令中设置 isErrorPage="true" 的时候才会存在
application 对象 ServletContext 对象实例,可以获取整个工程的一些信息
config 对象 ServletConfig 对象实例,可以获取 Servlet 的配置信息
out 对象 输出流
page 对象 表示当前 Servlet 对象实例(无用,用它不如使用 this 对象)

九大内置对象 , 都是我们可以在 【 代码脚本 】 中或 【 表达式脚本 】 中直接使用的对象。

jsp 四大域对象

四大域对象经常用来保存数据信息。

域对象 含义
pageContext 可以保存数据在同一个 jsp 页面中使用
request 可以保存数据在同一个 request 对象中使用。经常用于在转发的时候传递数据
session 可以保存在一个会话中使用
application(ServletContext) 就是 ServletContext 对象

四个作用域的测试代码:
新建两个 jsp 页面。分别取名叫:context1.jspcontext2.jsp

context1.jsp 的页面代码如下:

<%--
  Created by IntelliJ IDEA.
  User: Kohler
  Date: 2022/8/26
  Time: 20:00
  To change this template use File | Settings | File Templates.
--%>
<%@ 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>context1</title>
    </head>
    <body>
        这是 context1 页面<br/>
        <%
            //设置 page 域的数据
            pageContext.setAttribute("key", "pageContext-value");
        //设置 request 域的数据
            request.setAttribute("key", "request-value");
        //设置 session 域的数据
            session.setAttribute("key", "session-value");
        //设置 application 域的数据
            application.setAttribute("key", "application-value");
        %>
        <%-- 测试当前页面作用域 --%>
        <%=pageContext.getAttribute("key") %><br/>
        <%=request.getAttribute("key") %><br/>
        <%=session.getAttribute("key") %><br/>
        <%=application.getAttribute("key") %><br/>
        <%
            // 测试 request 作用域
        // request.getRequestDispatcher("/context2.jsp").forward(request, response);
        %>
    </body>
</html>

context2.jsp 的页面代码如下:

<%--
  Created by IntelliJ IDEA.
  User: Kohler
  Date: 2022/8/26
  Time: 20:03
  To change this template use File | Settings | File Templates.
--%>
<%@ 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>context2</title>
  </head>
  <body>
    这是 context2 页面 <br/>
    <%=pageContext.getAttribute("key") %><br/>
    <%=request.getAttribute("key") %><br/>
    <%=session.getAttribute("key") %><br/>
    <%=application.getAttribute("key") %><br/>
  </body>
</html>

测试 pageContext 作用域:

直接访问 context1.jsp 文件,结果:

测试 request 作用域:

1.在 context1.jsp 文件中添加转发到 context2.jsp(有数据)
2.直接访问 context2.jsp 文件 (没有数据)

测试 session 作用域:
1.访问完 context1.jsp 文件
2.关闭浏览器。但是要保持服务器一直开着
3.打开浏览器,直接访问 context2.jsp 文件

测试 application 作用域:
1.访问完 context1.jsp 文件,然后关闭浏览器
2.停止服务器。再启动服务器。
3.打开浏览器访问 context2.jsp 文件

context1.jsp的页面

context2.jsp的页面

context1.jsp页面中:

context1页面的pageContent的值成为null了,因为添加转发跳转到了另一个jsp页面

request还有值是因为,虽然跳转到了另一个页面但是这还属于一次请求。

context1和context2中session还有值是因为当前都是在一个浏览器中访问,换一个浏览器的结果:

application一直有值是因为当前tomcat一直在一次运行中,如果重新部署或者重启服务器就会变为null

重启服务器:

jsp中out输出流和response.getwriter()输出流

jsp中out 和response的writer的区别演示

<%--
  Created by IntelliJ IDEA.
  User: Kohler
  Date: 2022/8/26
  Time: 20:41
  To change this template use File | Settings | File Templates.
--%>
<%@ 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>output</title>
    </head>
    <body>
        <%
            // out 输出
            out.write("这是 out 的第一次输出<br/>");
        // out flush 之后。会把输出的内容写入 writer 的缓冲区中
            out.flush();
        // 最后一次的输出,由于没有手动 flush,会在整个页面输出到客户端的时候,自动写入到 writer 缓冲区
            out.write("这是 out 的第二次输出<br/>");
        // writer 的输出
            response.getWriter().write("这是 writer 的第一次输出<br/>");
            response.getWriter().write("这是 writer 的第二次输出<br/>");
        %>
    </body>
</html>

在浏览器里输入 http://localhost:8080/JSPDemo/output.jsp运行查看的结果:

out 流和 writer 流的两个缓冲区如何工作

jsp 的常用标签

<%-- 静态包含 --%>
<%-- 动态包含 --%>
<%-- 转发 --%>

静态包含--很常用

<%@ include file="" %>

静态包含是把包含的页面内容原封装不动的输出到包含的位置。

动态包含--很少用

<jsp:include page=""></jsp:include>

动态包含会把包含的 jsp 页面单独翻译成 servlet 文件,然后在执行到时候再调用翻译的 servlet 程序。并把
计算的结果返回。
动态包含是在执行的时候,才会加载。所以叫动态包含。

页面转发--常用

<jsp:forward page=""></jsp:forward>

<jsp:forward 转发功能相当于
request.getRequestDispatcher("/xxxx.jsp").forward(request, response); 的功能。

静态包含 动态包含
是否生成 java 文件 不生成 生成
service 方法中的区别 把包含的内容原封拷贝到 service 中 JspRuntimeLibrary.include 方法
是否可以传递参数 不能 可以
编译次数 1 包含的文件 + 1
适用范围 适用包含纯静态内容(CSS,HTML,JS),或没有;非常耗时操作。或大量 java 代码的 jsp 包含需要传递参数。含有大量 java 代码,运算,耗时很长的操作。

补充

在工作中,几乎都是使用静态包含。理由很简单。因为 jsp 页面虽然可以写 java 代码,做其他的功能操作。但是由于 jsp 在开发过程中被定位为专门用来展示页面的技术。也就是说。jsp 页面中,基本上只有 html,css,js。还有一些简单的 EL,表达式脚本等输出语句。所以我们都使用静态包含。

Listener 监听器

什么是 Listener 监听器

什么是监听器?监听器就是实时监视一些事物状态的程序,我们称为监听器。
就好像朝阳群众?朝阳区只要有哪个明星有什么不好的事,他们都会知道,然后举报。
那么朝阳群众就是监听器,明星就是被监视的事物,举报就是响应的内容。
又或者说是,电动车的报警器。当报警器锁上的时候。我们去碰电动车,电动车就会报警。
报警器,就是监听器,电动车就是被监视的对象。报警就是响应的内容。

ServletContextListener 监听器

javax.servlet.ServletContextListener      ServletContext 监听器

监听器的使用步骤。
第一步:我们需要定义一个类。然后去继承生命周期的监听器接口。
第二步:然后在 Web.xml 文件中配置。
ServletContextListener 监听器,一定要在 web.xml 文件中配置之后才会生效

<listener>
<listener-class>全类名</listener-class>
</listener>

生命周期监听器两个方法:

public void contextInitialized(ServletContextEvent sce) 是 ServletContext 对象的
创建回调
public void contextDestroyed(ServletContextEvent sce) 是 ServletContext 对象的销
毁回调

以 ServletContext 的监听器为例:

创建一个 ServletContextListenerImpl 类实现 ServletContextListener 接口。

package com.kailong.servlet;

import javax.servlet.ServletContextEvent;
import javax.servlet.ServletContextListener;
public class ServletContextListenerImpl implements ServletContextListener {
    @Override
    public void contextInitialized(ServletContextEvent sce) {
        System.out.println("ServletContext 对象被创建了");
    }
    @Override
    public void contextDestroyed(ServletContextEvent sce) {
        System.out.println("ServletContext 对象被销毁了");
    }
}

在 web.xml 文件中的配置如下:

    <listener>
        <listener-class>com.kailong.servlet.ServletContextListenerImpl</listener-class>
    </listener>

这个时候,启动 web 工程和正常停止 web 工程,后台都会如下打印:

如图片失效等情况请参阅公众号文章:https://mp.weixin.qq.com/s/jWej5-yDpj6DZJz_saYZ_Q

欢迎关注公众号:愚生浅末

有关JSP基础知识总结的更多相关文章

  1. postman接口测试工具-基础使用教程 - 2

    1.postman介绍Postman一款非常流行的API调试工具。其实,开发人员用的更多。因为测试人员做接口测试会有更多选择,例如Jmeter、soapUI等。不过,对于开发过程中去调试接口,Postman确实足够的简单方便,而且功能强大。2.下载安装官网地址:https://www.postman.com/下载完成后双击安装吧,安装过程极其简单,无需任何操作3.使用教程这里以百度为例,工具使用简单,填写URL地址即可发送请求,在下方查看响应结果和响应状态码常用方法都有支持请求方法:getpostputdeleteGet、Post、Put与Delete的作用get:请求方法一般是用于数据查询,

  2. 软件测试基础 - 2

    Ⅰ软件测试基础一、软件测试基础理论1、软件测试的必要性所有的产品或者服务上线都需要测试2、测试的发展过程3、什么是软件测试找bug,发现缺陷4、测试的定义使用人工或自动的手段来运行或者测试某个系统的过程。目的在于检测它是否满足规定的需求。弄清预期结果和实际结果的差别。5、测试的目的以最小的人力、物力和时间找出软件中潜在的错误和缺陷6、测试的原则28原则:20%的主要功能要重点测(eg:支付宝的支付功能,其他功能都是次要的)80%的错误存在于20%的代码中7、测试标准8、测试的基本要求功能测试性能测试安全性测试兼容性测试易用性测试外观界面测试可靠性测试二、质量模型衡量一个优秀软件的维度①功能性功

  3. SPI接收数据异常问题总结 - 2

    SPI接收数据左移一位问题目录SPI接收数据左移一位问题一、问题描述二、问题分析三、探究原理四、经验总结最近在工作在学习调试SPI的过程中遇到一个问题——接收数据整体向左移了一位(1bit)。SPI数据收发是数据交换,因此接收数据时从第二个字节开始才是有效数据,也就是数据整体向右移一个字节(1byte)。请教前辈之后也没有得到解决,通过在网上查阅前人经验终于解决问题,所以写一个避坑经验总结。实际背景:MCU与一款芯片使用spi通信,MCU作为主机,芯片作为从机。这款芯片采用的是它规定的六线SPI,多了两根线:RDY和INT,这样从机就可以主动请求主机给主机发送数据了。一、问题描述根据从机芯片手

  4. ES基础入门 - 2

    ES一、简介1、ElasticStackES技术栈:ElasticSearch:存数据+搜索;QL;Kibana:Web可视化平台,分析。LogStash:日志收集,Log4j:产生日志;log.info(xxx)。。。。使用场景:metrics:指标监控…2、基本概念Index(索引)动词:保存(插入)名词:类似MySQL数据库,给数据Type(类型)已废弃,以前类似MySQL的表现在用索引对数据分类Document(文档)真正要保存的一个JSON数据{name:"tcx"}二、入门实战{"name":"DESKTOP-1TSVGKG","cluster_name":"elasticsear

  5. ruby - 我怎样才能更好地了解/了解更多关于 Ruby 的知识? - 2

    按照目前的情况,这个问题不适合我们的问答形式。我们希望答案得到事实、引用或专业知识的支持,但这个问题可能会引发辩论、争论、投票或扩展讨论。如果您觉得这个问题可以改进并可能重新打开,visitthehelpcenter指导。关闭9年前。我最近开始学习Ruby,这是我的第一门编程语言。我对语法感到满意,并且我已经完成了许多只教授相同基础知识的教程。我已经写了一些小程序(包括我自己的数组排序方法,在有人告诉我谷歌“冒泡排序”之前我认为它非常聪明),但我觉得我需要尝试更大更难的东西来理解更多关于Ruby.关于如何执行此操作的任何想法?

  6. 【网络】-- 网络基础 - 2

    (本文是网络的宏观的概念铺垫)目录计算机网络背景网络发展认识"协议"网络协议初识协议分层OSI七层模型TCP/IP五层(或四层)模型报头以太网碰撞路由器IP地址和MAC地址IP地址与MAC地址总结IP地址MAC地址计算机网络背景网络发展        是最开始先有的计算机,计算机后来因为多项技术的水平升高,逐渐的计算机变的小型化、高效化。后来因为计算机其本身的计算能力比较的快速:独立模式:计算机之间相互独立。    如:有三个人,每个人做的不同的事物,但是是需要协作的完成。    而这三个人所做的事是需要进行协作的,然而刚开始因为每一台计算机之间都是互相独立的。所以前面的人处理完了就需要将数据

  7. Simulink方法总结和避坑指南(一)——Simulink入门与基本调试方法 - 2

    文章目录一、项目场景二、基本模块原理与调试方法分析——信源部分:三、信号处理部分和显示部分:四、基本的通信链路搭建:四、特殊模块:interpretedMATLABfunction:五、总结和坑点提醒一、项目场景  最近一个任务是使用simulink搭建一个MIMO串扰消除的链路,并用实际收到的数据进行测试,在搭建的过程中也遇到了不少的问题(当然这比vivado里面的debug好不知道多少倍)。准备趁着这个机会,先以一个很基本的通信链路对simulink基础和相关的debug方法进行总结。  在本篇中,主要记录simulink的基本原理和基本的SISO通信传输链路(QPSK方式),计划在下篇记

  8. 【Elasticsearch基础】Elasticsearch索引、文档以及映射操作详解 - 2

    文章目录概念索引相关操作创建索引更新副本查看索引删除索引索引的打开与关闭收缩索引索引别名查询索引别名文档相关操作新建文档查询文档更新文档删除文档映射相关操作查询文档映射创建静态映射创建索引并添加映射概念es中有三个概念要清楚,分别为索引、映射和文档(不用死记硬背,大概有个印象就可以)索引可理解为MySQL数据库;映射可理解为MySQL的表结构;文档可理解为MySQL表中的每行数据静态映射和动态映射上面已经介绍了,映射可理解为MySQL的表结构,在MySQL中,向表中插入数据是需要先创建表结构的;但在es中不必这样,可以直接插入文档,es可以根据插入的文档(数据),动态的创建映射(表结构),这就

  9. c++基础-运算符 - 2

    目录1关系运算符2运算符优先级3关系表达式的书写代码实例:下面是面试中可能遇到的问题:1关系运算符C++中有6个关系运算符,用于比较两个值的大小关系,它们分别是:运算符描述==等于!=不等于小于>大于小于等于>=大于等于这些运算符返回一个布尔值,即true或false。例如,当x等于y时,x==y的结果为true,否则结果为false。2运算符优先级在C++中,关系运算符的优先级高于赋值运算符,但低于算术运算符。以下是关系运算符的优先级,从高到低排列:运算符描述>,,>=,关系运算符==,!=相等性运算符&&逻辑与`如果在表达式中有多个运算符,则按照优先级顺序依次进行运算。3关系表达式的书写在

  10. 计算机必读基础书籍 - 2

    一.计算机组成原理    这本书利用组合逻辑、同步时序逻辑电路设计的相关知识,从逻辑门开始逐步构建运算器、存储器、数据通路和控制器,最终集成为完整的CU原型系统,使读者从设计者的角度理解计算机部件构成及运行的基本原理,掌握软硬件协同的概念。    全书共9章,主要内容包括计算机系统概述、数据信息的表示、运算方法与运算器、存储系统、指令系统、中央处理器、指令流水线、总线系统、输入输出系统。1.计算机系统概述1.1计算机发展历程    计算机是一种能够按照事先存储的程序,自动、高速、准确地对相关信息进行处理的电子设备。1946年2月,世界上第一台电子数字计算机ENIAC(ElectronicNum

随机推荐