【JSP学习笔记】2.JSP 结构、生命周期及语法

news2024/12/27 13:56:32

前言

本章介绍JSP的结构、生命周期及语法。

JSP 结构

网络服务器需要一个 JSP 引擎,也就是一个容器来处理 JSP 页面。容器负责截获对 JSP 页面的请求。本教程使用内嵌 JSP 容器的 Apache 来支持 JSP 开发。

JSP 容器与 Web 服务器协同合作,为JSP的正常运行提供必要的运行环境和其他服务,并且能够正确识别专属于 JSP 网页的特殊元素。

下图显示了 JSP 容器和 JSP 文件在 Web 应用中所处的位置。

在这里插入图片描述

JSP 处理
以下步骤表明了 Web 服务器是如何使用JSP来创建网页的:

  • 就像其他普通的网页一样,您的浏览器发送一个 HTTP 请求给服务器。
  • Web 服务器识别出这是一个对 JSP 网页的请求,并且将该请求传递给 JSP 引擎。通过使用 URL或者 .jsp 文件来完成。
  • JSP 引擎从磁盘中载入 JSP 文件,然后将它们转化为 Servlet。这种转化只是简单地将所有模板文本改用 println()语句,并且将所有的 JSP 元素转化成 Java 代码。
  • JSP 引擎将 Servlet 编译成可执行类,并且将原始请求传递给 Servlet 引擎。
  • Web 服务器的某组件将会调用 Servlet 引擎,然后载入并执行 Servlet 类。在执行过程中,Servlet 产生 HTML格式的输出并将其内嵌于 HTTP response 中上交给 Web 服务器。
  • Web 服务器以静态 HTML 网页的形式将 HTTP response 返回到您的浏览器中。
  • 最终,Web 浏览器处理 HTTP response 中动态产生的HTML网页,就好像在处理静态网页一样。

以上提及到的步骤可以用下图来表示:
在这里插入图片描述

一般情况下,JSP 引擎会检查 JSP 文件对应的 Servlet 是否已经存在,并且检查 JSP 文件的修改日期是否早于 Servlet。如果 JSP 文件的修改日期早于对应的 Servlet,那么容器就可以确定 JSP 文件没有被修改过并且 Servlet 有效。这使得整个流程与其他脚本语言(比如 PHP)相比要高效快捷一些。

总的来说,JSP 网页就是用另一种方式来编写 Servlet 而不用成为 Java 编程高手。除了解释阶段外,JSP 网页几乎可以被当成一个普通的 Servlet 来对待。

JSP 生命周期

理解JSP底层功能的关键就是去理解它们所遵守的生命周期。

JSP生命周期就是从创建到销毁的整个过程,类似于servlet生命周期,区别在于JSP生命周期还包括将JSP文件编译成servlet。

以下是JSP生命周期中所走过的几个阶段:

  • 编译阶段: servlet容器编译servlet源文件,生成servlet类
  • 初始化阶段: 加载与JSP对应的servlet类,创建其实例,并调用它的初始化方法
  • 执行阶段: 调用与JSP对应的servlet实例的服务方法
  • 销毁阶段: 调用与JSP对应的servlet实例的销毁方法,然后销毁servlet实例

很明显,JSP生命周期的四个主要阶段和servlet生命周期非常相似,下面给出图示:
在这里插入图片描述

JSP编译
当浏览器请求JSP页面时,JSP引擎会首先去检查是否需要编译这个文件。如果这个文件没有被编译过,或者在上次编译后被更改过,则编译这个JSP文件。

编译的过程包括三个步骤:

  • 解析JSP文件。
  • 将JSP文件转为servlet。
  • 编译servlet。

JSP初始化
容器载入JSP文件后,它会在为请求提供任何服务前调用jspInit()方法。如果您需要执行自定义的JSP初始化任务,复写jspInit()方法就行了,就像下面这样:

public void jspInit(){
  // 初始化代码
}

一般来讲程序只初始化一次,servlet也是如此。通常情况下您可以在jspInit()方法中初始化数据库连接、打开文件和创建查询表。

JSP执行
这一阶段描述了JSP生命周期中一切与请求相关的交互行为,直到被销毁。

当JSP网页完成初始化后,JSP引擎将会调用_jspService()方法。

_jspService()方法需要一个HttpServletRequest对象和一个HttpServletResponse对象作为它的参数,就像下面这样:

void _jspService(HttpServletRequest request,
                 HttpServletResponse response)
{
   // 服务端处理代码
}

_jspService()方法在每个request中被调用一次并且负责产生与之相对应的response,并且它还负责产生所有7个HTTP方法的回应,比如GET、POST、DELETE等等。

JSP清理
JSP生命周期的销毁阶段描述了当一个JSP网页从容器中被移除时所发生的一切。

jspDestroy()方法在JSP中等价于servlet中的销毁方法。当您需要执行任何清理工作时复写jspDestroy()方法,比如释放数据库连接或者关闭文件夹等等。

jspDestroy()方法的格式如下:

public void jspDestroy()
{
   // 清理代码
}

实例
JSP生命周期代码实例如下所示:

<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<html>
<head>
<title>life.jsp</title>
</head>
<body>

<%! 
  private int initVar=0;
  private int serviceVar=0;
  private int destroyVar=0;
%>
  
<%!
  public void jspInit(){
    initVar++;
    System.out.println("jspInit(): JSP被初始化了"+initVar+"次");
  }
  public void jspDestroy(){
    destroyVar++;
    System.out.println("jspDestroy(): JSP被销毁了"+destroyVar+"次");
  }
%>

<%
  serviceVar++;
  System.out.println("_jspService(): JSP共响应了"+serviceVar+"次请求");

  String content1="初始化次数 : "+initVar;
  String content2="响应客户请求次数 : "+serviceVar;
  String content3="销毁次数 : "+destroyVar;
%>
<h1>csdn教程 JSP 测试实例</h1>
<p><%=content1 %></p>
<p><%=content2 %></p>
<p><%=content3 %></p>

</body>
</html>

浏览器打开该页面,输出结果为:

在这里插入图片描述

JSP 语法

本小节将会简单地介绍一下JSP开发中的基础语法。

脚本程序
脚本程序可以包含任意量的Java语句、变量、方法或表达式,只要它们在脚本语言中是有效的。

脚本程序的语法格式:

<% 代码片段 %>

或者,您也可以编写与其等价的XML语句,就像下面这样:

<jsp:scriptlet>
   代码片段
</jsp:scriptlet>

任何文本、HTML标签、JSP元素必须写在脚本程序的外面。

下面给出一个示例,同时也是本教程的第一个JSP示例:

<html>
<head><title>Hello World</title></head>
<body>
Hello World!<br/>
<%
out.println("Your IP address is " + request.getRemoteAddr());
%>
</body>
</html>

注意:请确保Apache Tomcat已经安装在C:\apache-tomcat-7.0.2目录下并且运行环境已经正确设置。

将以上代码保存在hello.jsp中,然后将它放置在 C:\apache-tomcat-7.0.2\webapps\ROOT目录下,打开浏览器并在地址栏中输入http://localhost:8080/hello.jsp。运行后得到以下结果:

在这里插入图片描述

中文编码问题
如果我们要在页面正常显示中文,我们需要在 JSP 文件头部添加以下代码:

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

接下来我们将以上程序修改为:

<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>csdn教程(csdn.com)</title>
</head>
<body>
Hello World!<br/>
<%
out.println("你的 IP 地址 " + request.getRemoteAddr());
%>
</body>
</html>

这样中文就可以正常显示了。

JSP声明
一个声明语句可以声明一个或多个变量、方法,供后面的Java代码使用。在JSP文件中,您必须先声明这些变量和方法然后才能使用它们。

JSP声明的语法格式:

<%! declaration; [ declaration; ]+ ... %>

或者,您也可以编写与其等价的XML语句,就像下面这样:

<jsp:declaration>
   代码片段
</jsp:declaration>

程序示例:

<%! int i = 0; %> 
<%! int a, b, c; %> 
<%! Circle a = new Circle(2.0); %> 

JSP表达式
一个JSP表达式中包含的脚本语言表达式,先被转化成String,然后插入到表达式出现的地方。

由于表达式的值会被转化成String,所以您可以在一个文本行中使用表达式而不用去管它是否是HTML标签。

表达式元素中可以包含任何符合Java语言规范的表达式,但是不能使用分号来结束表达式。

JSP表达式的语法格式:

<%= 表达式 %>

同样,您也可以编写与之等价的XML语句:

<jsp:expression>
   表达式
</jsp:expression>

程序示例:

<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>csdn教程(csdn.com)</title>
</head>
<body>
<p>
   今天的日期是: <%= (new java.util.Date()).toLocaleString()%>
</p>
</body> 
</html> 

运行后得到以下结果:

今天的日期是: 2016-6-25 13:40:07

JSP注释
JSP注释主要有两个作用:为代码作注释以及将某段代码注释掉。

JSP注释的语法格式:

<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>csdn教程(csdn.com)</title>
</head>
<body>
<%-- 该部分注释在网页中不会被显示--%> 
<p>
   今天的日期是: <%= (new java.util.Date()).toLocaleString()%>
</p>
</body> 
</html> 

运行后得到以下结果:

今天的日期是: 2016-6-25 13:41:26

不同情况下使用注释的语法规则:

语法描述
<%-- 注释 --%>JSP注释,注释内容不会被发送至浏览器甚至不会被编译
<!-- 注释 -->HTML注释,通过浏览器查看网页源代码时可以看见注释内容
<%代表静态 <%常量
%>代表静态 %> 常量
在属性中使用的单引号
"在属性中使用的双引号

JSP指令
JSP指令用来设置与整个JSP页面相关的属性。

JSP指令语法格式:

<%@ directive attribute="value" %>

这里有三种指令标签:

指令描述
<%@ page … %>定义页面的依赖属性,比如脚本语言、error页面、缓存需求等等
<%@ include … %>包含其他文件
<%@ taglib … %>引入标签库的定义,可以是自定义标签

JSP行为
JSP行为标签使用XML语法结构来控制servlet引擎。它能够动态插入一个文件,重用JavaBean组件,引导用户去另一个页面,为Java插件产生相关的HTML等等。

行为标签只有一种语法格式,它严格遵守XML标准:

<jsp:action_name attribute="value" />

行为标签基本上是一些预先就定义好的函数,下表罗列出了一些可用的JSP行为标签::

语法描述
jsp:include用于在当前页面中包含静态或动态资源
jsp:useBean寻找和初始化一个JavaBean组件
jsp:setProperty设置 JavaBean组件的值
jsp:getProperty将 JavaBean组件的值插入到 output中
jsp:forward从一个JSP文件向另一个文件传递一个包含用户请求的request对象
jsp:plugin用于在生成的HTML页面中包含Applet和JavaBean对象
jsp:element动态创建一个XML元素
jsp:attribute定义动态创建的XML元素的属性
jsp:body定义动态创建的XML元素的主体
jsp:text用于封装模板数据

JSP隐含对象
JSP支持九个自动定义的变量,江湖人称隐含对象。这九个隐含对象的简介见下表:

对象描述
requestHttpServletRequest类的实例
responseHttpServletResponse类的实例
outPrintWriter类的实例,用于把结果输出至网页上
sessionHttpSession类的实例
applicationServletContext类的实例,与应用上下文有关
configServletConfig类的实例
pageContextPageContext类的实例,提供对JSP页面所有对象以及命名空间的访问
page类似于Java类中的this关键字
exception exception类的对象,代表发生错误的 JSP 页面中对应的异常对象

控制流语句
JSP提供对Java语言的全面支持。您可以在JSP程序中使用Java API甚至建立Java代码块,包括判断语句和循环语句等等。

判断语句
if…else 块,请看下面这个例子:

<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<%! int day = 3; %> 
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>csdn教程(csdn.com)</title>
</head>
<body>
<h3>IF...ELSE 实例</h3>
<% if (day == 1 || day == 7) { %>
      <p>今天是周末</p>
<% } else { %>
      <p>今天不是周末</p>
<% } %>
</body> 
</html> 

运行后得到以下结果:

IF...ELSE 实例
今天不是周末

现在来看看switch…case块,与if…else块有很大的不同,它使用out.println(),并且整个都装在脚本程序的标签中,就像下面这样:

<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<%! int day = 3; %> 
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>csdn教程(csdn.com)</title>
</head>
<body>
<h3>SWITCH...CASE 实例</h3>
<% 
switch(day) {
case 0:
   out.println("星期天");
   break;
case 1:
   out.println("星期一");
   break;
case 2:
   out.println("星期二");
   break;
case 3:
   out.println("星期三");
   break;
case 4:
   out.println("星期四");
   break;
case 5:
   out.println("星期五");
   break;
default:
   out.println("星期六");
}
%>
</body> 
</html> 

浏览器访问,运行后得出以下结果:

SWITCH...CASE 实例

星期三

循环语句
在JSP程序中可以使用Java的三个基本循环类型:for,while,和 do…while。

让我们来看看for循环的例子,以下输出的不同字体大小的"csdn教程":

<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<%! int fontSize; %> 
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>csdn教程(csdn.com)</title>
</head>
<body>
<h3>For 循环实例</h3>
<%for ( fontSize = 1; fontSize <= 3; fontSize++){ %>
   <font color="green" size="<%= fontSize %>">
    csdn教程
   </font><br />
<%}%>
</body> 
</html> 

运行后得到以下结果:

在这里插入图片描述

将上例改用 while 循环来写:

<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<%! int fontSize=0; %> 
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>csdn教程(csdn.com)</title>
</head>
<body>
<h3>While 循环实例</h3>
<%while ( fontSize <= 3){ %>
   <font color="green" size="<%= fontSize %>">
    csdn教程
   </font><br />
<%fontSize++;%>
<%}%>
</body> 
</html> 

浏览器访问,输出结果为(fontSize 初始化为0,所以多输出了一行):
在这里插入图片描述

JSP运算符
JSP支持所有Java逻辑和算术运算符。

下表罗列出了JSP常见运算符,优先级从高到底:

类别操作符结合性
后缀() [] . (点运算符)左到右
一元++ - - ! ~右到左
可乘性* / %左到右
可加性+ -左到右
移位>> >>> <<左到右
关系> >= < <=左到右
相等/不等== !=左到右
位与&左到右
位异或^左到右
位或|左到右
逻辑与&&左到右
逻辑或||左到右
条件判断?:右到左
赋值= += -= *= /= %= >>= <<= &= ^= |=右到左
逗号,左到右

JSP 字面量
JSP语言定义了以下几个字面量:

  • 布尔值(boolean):true 和 false;
  • 整型(int):与 Java 中的一样;
  • 浮点型(float):与 Java 中的一样;
  • 字符串(string):以单引号或双引号开始和结束;
  • Null:null。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/420885.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

springboot读取yml文件中的list列表、数组、map集合和对象方法实例

目录前言application.yml定义list集合application.yml定义数组类型总结 前言 springboot配置文件yml类型简单的风格&#xff0c;十分受大家的欢迎&#xff0c;支持字符string类型&#xff0c;支持列表list类型&#xff0c;支持集合map类型&#xff0c;支持数组array类型&#x…

MySQL数据库 - 基础篇

本文文章基于黑马《MySQL》课程所做的笔记 1、基础篇 1.1、MySQL概述 数据库相关概念 名称全称简介数据库存储数据的仓库&#xff0c;数据是有组织的进行存储DataBase(DB)数据库管理系统操纵和管理数据库的大型软件DataBase Management System(DBMS)SQL操作关系型数据库的编程…

ijkplayer 编译增加支持更多的音视频格式

ijkplayer是B站开源的一款基于ffmpeg的移动端播放器。但为了减少播放器的体积&#xff0c;很多音视频的格式播放默认都是不支持的&#xff0c;需要自己下载ijkplayer源码进行编译。这里以mac环境下android为例&#xff0c;简述ijkplayer的编译过程&#xff0c;以及为了支持更多…

最新版本 Stable Diffusion 开源 AI 绘画工具之图生图进阶篇

✨ 目录&#x1f388; 图生图基本参数&#x1f388; 图生图&#xff08;img2img&#xff09;&#x1f388; 涂鸦绘制&#xff08;Sketch&#xff09;&#x1f388; 局部绘制&#xff08;Inpaint&#xff09;&#x1f388; 涂鸦蒙版&#xff08;Inpaint sketch&#xff09;&…

Adams2020软件安装教程

目录 一、软件简介 二、软件下载 三、软件安装 一、软件简介 Adams是一款多领域仿真软件&#xff0c;可以对机械、电子、流体、化学等系统进行建模、仿真和分析。Adams具有强大的动力学分析功能&#xff0c;可以模拟多种复杂系统的运动、力学、热力学和控制行为&#xff0c;包…

点云目标检测:open3d多窗口联动可视化

多个模型之间的对比除了指标之外,还需要可以直观的对比可视化结果,这次介绍一下如何使用open3d同时打开两个窗口分别加载两个模型的结果,同时实现两个窗口的联动,也就是当一个窗口拖动或者缩放时另外一个窗口也跟着做同样的变换。 点云可视化:使用open3d实现点云连续播放这…

nginx虚拟主机

一、基于域名的nginx虚拟主机 1、基于域名的nginx虚拟主机的操作步骤 1.1 为虚拟主机提供域名和IP的映射(也可以使用DNS正向解析) echo "192.168.2.66 www.xkq.com www.wy.com" >> /etc/hosts1.2 为虚拟主机准备网页文档 mkdir -p /var/www/html/ly/ mkdir…

第一章 深度学习入门之流程初体验

效果图 文章中采用的是棋盘格数据&#xff0c;这张图里面用的是开源的模型&#xff0c;可以用于测试&#xff0c;此图为最终效果&#xff0c;加载mp4视频&#xff0c;通过opencv读取图像&#xff0c;传递到infer接口&#xff0c;进行推理识别&#xff0c;利用opencv显示出来 …

比较好的文档翻译软件-哪个翻译软件最精准

免费语言翻译软件可以帮助用户快速准确地翻译语言&#xff0c;其主要作用如下&#xff1a; 辅助语言学习&#xff1a;语言翻译软件可以帮助用户学习语言&#xff0c;让用户更好地理解在不同语言之间的差异&#xff0c;从而使语言学习更加高效。 翻译外语内容&#xff1a;语言翻…

Java中常见的几种分布式锁介绍及实战应用

文章目录什么是锁&#xff1f;场景描述代码示例总结Java中单体应用锁的局限性&分布式锁前言互联网系统架构的演进单体应用锁的局限性什么是分布式锁分布式锁的设计思路目前存在的分布式的方案Java中锁的解决方案前言乐观锁 与 悲观锁公平锁 与 非公平锁总结分布式锁设计如何…

Python基础教程:__call__用法

人生苦短&#xff0c;我用python python 安装包资料:点击此处跳转文末名片获取 __call__可以使得方法变成可被调用对象&#xff1b; (PS&#xff1a;python中的方法和普通函数有点区别&#xff1a; 方法的第一个参数是类实例) 允许一个类的实例像函数一样被调用。 实质上说…

相机雷达时间同步(基于ROS)

文章目录运行环境&#xff1a;思路&#xff1a;同步前和同步后效果对比1.1创建工作空间1.2创建功能包2.1编写源文件2.2编写头文件2.3编写可执行文件2.4配置文件3.1编译运行4.1录制时间同步后的rosbag4.2rviz可视化rosbag运行环境&#xff1a; ubuntu20.04 noetic usb_cam 速腾R…

小黑子—Java从入门到入土过程:第七章

Java零基础入门7.0Java系列第七章1. 游戏打包exe2. API2.1 Math2.2 练习2.2.1 判断质数2.2.2 判断水仙花数&#xff08;自幂数&#xff09;2.3 System2.4 Runtime2.5 Object2.5.1 Object 的成员方法(1) toString(2) equals 比较两个对象是否相等(3) clone方法&#xff08;Objec…

投放视频广告时,如何快速与第三方播放器兼容?

新媒体时代&#xff0c;广告样式越来越丰富。相较于传统的图文信息&#xff0c;视频类广告更具有直观性&#xff0c;能够让消费者在了解产品知识和功能的同时加深对产品的印象。 因此在各类网站或App上投放视频类广告是个很好的宣传方式&#xff0c;但广告商们如果想在网站上展…

1.14 从0开始学习Unity游戏开发--物理引擎

上一篇文章我们讲了如何动态创建物体&#xff0c;以及如何用Prefab机制复用我们制作好的物体和逻辑&#xff0c;那么本篇我们将会讲解如何利用这些功能&#xff0c;结合Unity自带的物理引擎&#xff0c;实现一个简单的FPS游戏的效果。 物理组件 首先我们需要先了解如何使用Un…

Linux基础(超级无敌认真好用,万字收藏篇!!!!)

文章目录Linux基础1 Linux概述1.1 Linux特点1.2 Linux和Window区别2 Linux安装2.1 什么是虚拟化2.2 安装虚拟机2.3 配置网络环境3 Linux文件目录4 Linux常用命令4.1 文件与目录操作4.2 查看文件内容4.3 文本内容处理4.4 查询操作4.5 网络相关4.6 其他命令4.7 解压缩命令5 VI/VI…

今天面了个腾讯拿 38K 出来的,让我见识到了基础的天花板

今天上班开早会就是新人见面仪式&#xff0c;听说来了个很厉害的大佬&#xff0c;年纪还不大&#xff0c;是上家公司离职过来的&#xff0c;薪资已经达到中高等水平&#xff0c;很多人都好奇不已&#xff0c;能拿到这个薪资应该人不简单&#xff0c;果然&#xff0c;自我介绍的…

0102加权quick_union和路径压缩-union-find-动态连通性-算法研究

3 union-find算法 3.5 加权quick-union算法 3.5.1 算法实现 quick-union出现最坏情况&#xff0c;因为我们是随意将一棵树链接到另外一棵树上&#xff0c;修改如下&#xff1a; 添加一个数组和一些代码记录树中节点数&#xff1b;链接时将节点数较小的树链接到较大的树上&a…

基础算法-双指针,滑动窗口,位运算,区间离散化

双指针 两种类型 for(int i0,j0;i<n;i) {while(i<j&&check(i,j)) j;// 每道题目具体逻辑}双指针最核心的性质 可以优化 输入一个字符串 把每个单词输出出来 i找到单词开头 j找到空格 vector<string> rs; for(int i0,j0;i<s.size();i) {ji;while(j&…

.Net Forms Resize 12 Crack

.Net Forms Resize 12 Crack 添加了对Microsoft Visual Studio 2022(v17.5.3)及更高版本的支持。 增加了对Microsoft Windows Server 2019和2022的支持。 改进并调整引擎大小(大约快20%)。 更新与受支持的第三方控件的新版本的兼容性。 添加了新的Microsoft Framework 4.8.1库。…