JSP
文章参考:http://c.biancheng.net/jsp2/
一、前言
JSP 是 Java Server Pages 的缩写,是一种动态网页开发技术,动态网页是指跟静态网页相对的一种网页编程技术:
- 静态网页,随着 HTML 代码的生成,页面的内容和显示基本上不会发生变化,除非修改页面代码;
- 动态网页显示的内容可以随着时间、环境或者数据库操作的结果而发生改变;
JSP 本质是一个 Java 类(Servlet),我们可以在 JSP 页面中嵌入 Java 代码,即:JSP = HTML + Java
;
基本原理:请求 JSP 时,服务器内部
会经历一次动态资源(JSP)到静态资源(HTML)的转化,服务器会自动把 JSP 中的 HTML 片段和数据拼接成静态资源响应给浏览器。即JSP 运行在服务器端,最终发给客户端的是已经转换好的 HTML 静态页面;
JSP 的功能与 CGI 相似,但相对于 CGI 来说,JSP 具有很多优势。
- JSP 性能更加优越。因为 JSP 可以直接在 HTML 页面中嵌入动态元素,而不需要单独的引入 CGI 文件;
- JSP 会在服务器调用之前进行编译,而不是像 CGI/Perl 必须先加载解释器和目标脚本;
- JSP 基于 Java Servlet API,因此,JSP 可以使用各种强大的企业级 Java API,包括 JDBC、JNDI、EJB 和 JAXP 等;
- JSP 页面可以和处理业务逻辑的 Servlet 一起使用;
JSP 是 Java EE 不可或缺的一部分,是一个完整的企业级应用平台,这意味着 JSP 可以用最简单的方式来实现最复杂的应用;
1.JSP概述
JSP技术全称为Java Server Pages,是一种动态网页开发技术;
JSP运行在服务器端,返回给客户端的通常都是一个HTML文件,因此只需要客户端有浏览器就能查看JSP页面;
JSP文件是指在传统的HTML文件中插入Java代码和JSP标签,JSP文件的后缀名为.jsp:
- JSP 使用 JSP 标签在 HTML 网页中插入 Java 代码,标签通常以
<%
开头,以%>
结束。JSP 标签有多种功能,比如访问数据库和 JavaBean 组件等,还可以在不同的网页之间传递和共享信息;
JSP和Servlet的关系:
- JSP 是 Servlet 的扩展,可以在 JSP 中使用 Servlet 的所有功能。另外,JSP 还提供了一些其他功能,例如 EL 表达式、自定义标签等;
- JSP 依赖于 Servlet,用户访问 JSP 页面时,JSP 代码会被翻译成 Servlet 代码,最终,以字符串的形式向外输出 HTML 代码。所以,JSP 只是在 Servlet 的基础上做了进一步封装;
JSP 具有以下特点:
- JSP 具有 Servlet 的所有优点,例如 JSP 文件跨平台,即一次编写,处处运行(本质上是Java的优点);
- JSP 比 CGI 性能更加优越,因为 JSP 可以直接在 HTML 中嵌入标签,而 CGI 需要单独引用 CGI 文件;
- JSP 比 Servlet 更易于维护,JSP 将业务逻辑与网页设计分离,使其更加灵活(Servlet在一定程度上是将业务逻辑和网页设计交互混合,但是也不是直观上的将Servlet类和HTML完全写在一起);
- 使用 JSP,Web 开发人员可以更注重于网页设计,Java 开发人员可以更注重于逻辑处理;
1.1 JSP起源
在Servlet刚推出的时候,当时的Java Web体系结构中只有Servlet,所以接收用户请求、处理业务逻辑、生成 HTML 代码
等都在 Servlet 中完成。Servlet 不能像 PHP、ASP 等语言镶嵌 HTML 代码,因此输出 HTML 比较困难,且部署过程复杂;
因此,Sun在之后推出了JSP,在生成 HTML 代码方面 JSP 比 Servlet 方便许多,而且不需要特殊部署,只需要复制到服务器下面即可运行。简而言之,JSP 就是为了简化 Servlet 工作而出现的替代;
JSP 包括很多技术,包括 Java Bean、自定义标签(Custom Tags)、EL 表达式(Expression Language)、JSTL 标准标签类库(Java Standard Tag Library)等。这些强大成熟的技术使得 JSP 在视图层(View)具有很大的优势;
1.2 JSP&Servlet
JSP与Servlet的相同点在于两者都用于生成动态网页;
不同点主要如下(这个表格是理解JSP和Servlet的重点!!!)
JSP相对Servlet主要有如下优点:
易于维护:相对于 Servlet 来说,JSP 更易于管理。在 JSP 中,我们可以轻松地将业务逻辑与网页设计分开,而在 Servlet 技术中,它们是混合在一起的。
快速开发:无需重新编译和部署,JSP 页面被修改后,不需要重新编译和部署项目。而 Servlet 被修改后,需要重新编译和部署。
代码简洁:在 JSP 中,我们可以使用 EL、JSTL、自定义标签、隐式对象等,能够有效的减少代码。
2.JSP生命周期
JSP 生命周期定义了 JSP 从创建到销毁的整个过程。这类似于 Servlet 生命周期,不同的是,JSP 需要先被编译成 Servlet;
JSP 生命周期阶段如下:
- 编译
- 当浏览器请求 JSP 时,JSP 容器会首先检查是否需要编译页面。如果该页面从未被编译过,或者自上次编译以来对其进行了修改,则编译该页面。编译过程主要包括三个步骤:
- 解析 JSP:JSP 容器(本质上JSP容器就是Servlet容器)解析 JSP 文件,查看是否有语法错误;
- 翻译 JSP:JSP 容器把 JSP 文件翻译为 Servlet 类;
- 编译 Servlet;
- 当浏览器请求 JSP 时,JSP 容器会首先检查是否需要编译页面。如果该页面从未被编译过,或者自上次编译以来对其进行了修改,则编译该页面。编译过程主要包括三个步骤:
- 初始化(容器调用 jspInit() 方法)
- 当容器加载 JSP 时,它将在处理任何请求之前调用 jspInit() 方法。如果需要自定义 JSP 的初始化内容,可以重写 jspInit() 方法;
- 一般情况下,程序只初始化一次。与 Servlet init 方法一样,我们通常在 jspInit() 方法中初始化数据库连接、打开文件;
- 执行(容器调用 _jspService() 方法)
- 此阶段表示了 JSP 生命周期中所有与请求相关的交互行为,直到被销毁;
- JSP 页面完成初始化后,JSP 将会调用 _jspService() 方法,该方法以 HttpServletRequest 对象和 HttpServletResponse 对象作为方法参数,根据 request 来生成相应的 response,并且它还负责生成对 HTTP 方法的响应,即 GET、POST、DELETE 等;
- 销毁(容器调用 jspDestroy() 方法)
- JSP 生命周期的销毁阶段表示从容器中删除 JSP;
- jspDestroy() 方法等效于 Servlet 中的 destroy() 方法。如果需要自定义 JSP 的销毁内容,可以重写 jspDestroy() 方法;
- 通常在 jspDestroy() 方法中释放数据库连接、关闭打开的文件;
二、JSP基础
1.创建JSP
在学习之前可以先简单创建一个JSP程序来体验一下,参考教程:
- 手动创建JSP程序:第一个JSP程序 (biancheng.net);
- Eclipse创建JSP程序:Eclipse创建JSP项目(图解) (biancheng.net);
1.1 JSP注释
在 JSP 中可以使用以下 4 种注释,在 JSP 规范中,它们都属于 JSP 中的注释,但语法规则和运行效果都各不相同:
- HTML 注释:由于 JSP 文件中可以包含 HTML 标记,所以 HTML 中的注释同样可以在 JSP 文件中使用。 HTML 注释中的内容是不会在客户端浏览器中显示的,但可以通过 HTML 源代码看到这些注释内容;
1 |
|
- 带有 JSP 表达式的注释:包含该注释语句的 JSP 页面被请求后,服务器能够自动识别并执行注释中的 JSP 表达式,对于注释中的其他内容则不做任何操作;
1 |
|
- 隐藏注释:上面介绍的两种注释并不安全(会被客户端通过HTML源代码看到),隐藏注释的内容,不会显示在客户端的任何位置(包括 HTML 源代码),安全性较高;
1 |
|
脚本程序(Scriptlet)中的注释:脚本程序中包含的是一段 Java 代码,所以在脚本程序中的注释与在 Java 中的注释是相同的,脚本程序中包括下面 3 种注释方法
- 单行注释:符号“//”后面的内容为注释的内容,服务器对该内容不进行任何操作。由于脚本程序的代码在客户端通过查看源代码是不可见的,因此在脚本程序中通过该方法注释的内容也是不可见的;
1
//注释内容
- 多行注释:多行注释的符号必须成对出现,在它们之间的注释内容可以换行。与单行注释一样,注释的所有内容,服务器都不会做任何处理,即使被注释的内容是 JSP 表达式或其他脚本程序也不例外;
1
2
3
4/*
注释内容1
注释内容2
*/多行注释的开始标记和结束标记可以不在同一个脚本程序中同时出现;
- 文档注释:文档注释的内容会被 Javadoc 文档工具在生成文档时读取,文档是对代码结构和功能的描述。与多行注释一样,被注释的所有内容,服务器不会做任何处理
1
2
3
4/**
提示信息1
提示信息2
*/
2.JSP脚本
文章参考:(1条消息) jsp脚本_Pursuit_li的博客-CSDN博客_什么是jsp脚本;
在JSP中可以借助JSP脚本写入Java代码,JSP脚本也被称为Java脚本
(惊不惊喜,这就是学习的意义,在学习的过程中将以前未知或者难以理解的知识点融会贯通),本质上就是Java代码片段;
注意,JavaScript不是Java语言的脚本形式,两者是两套完全不同的语言架构;
关于Java Servlet、Java Script(JS)和Java Server Pages(JSP)的区别参考(1条消息) JS和JSP的区别_电子科技大学的博客-CSDN博客_js和jsp;
JSP与HTML和Java脚本之间的关系如下:
注:任何文本、HTML 标签和 JSP 元素(声明,表达式等)都必须在脚本程序之外;
JSP脚本可以包括任意数量的Java语句、变量、方法和表达式,JSP脚本会将包含的内容插入到Servlet的service()方法中;
JSP脚本指的是使用“<%%>”括起来的jsp页面中的java脚本 —— 所有能在java程序中执行的代码,都可以通过jsp脚本执行;
JSP脚本最基本的三种类型如下(注意无论是什么样的脚本最后在HTML源码或者客户端浏览器都不会显示,注意和注释区分):
- <%…%>:Java语句,也就是普通脚本;
- <%=…%>:Java表达式脚本,是产生输出功能的脚本,
不能以分号结尾
; - <%!…%>:Java定义类成员,也称为声明脚本,用于定义全局变量和方法;
JSP普通脚本的语法如下
1 |
|
等价于
1 |
|
2.1 声明脚本
JSP 声明脚本用于声明一个或多个变量、方法,以供后面的 Java 代码使用 —— 必须先对变量和方法进行声明,之后才能使用;
JSP声明脚本的语法如下
1 |
|
等价于
1 |
|
需要注意的是,JSP普通脚本只能声明变量不能声明方法,但是JSP声明语句既可以声明语句也可以声明方法:
- JSP 普通脚本会把包含的内容转译插入到 Servlet 的 service() 方法中,也就是
<% %>
中定义的变量是局部变量,这也是 JSP 脚本不能声明方法的原因,因为 Java 不允许方法中嵌套方法; - JSP 声明会把包含的内容添加到 Servlet 类中(在任何方法之外),也就是
<%! %>
中定义的变量是成员变量,方法是成员方法;
2.2 表达式脚本
JSP 表达式可以把变量或者表达式输出到网页上,不需要 out.print() 就能输出数据,通常用于打印变量和方法的值;
JSP表达式脚本的语法如下
1 |
|
等价于
1 |
|
可以将 <%=表达式 %> 理解为 <% out.println(表达式) %> 的简写方式,JSP 表达式不能以分号结尾;
3.JSP动态标签
3.1 JSP指令
JSP指令属于动态标签的一种,这里我们先介绍一些JSP指令;
JSP指令用于告诉Web服务器如何处理JSP页面的请求和响应,服务器会根据JSP指令来编译JSP生成Java文件;
JSP指令不会产生任何可见输出,在生成的Java文件中不存在JSP指令;
JSP指令以<%@
开始,以%>
结束,语法如下
1 |
|
注意:
[ ]
中的内容是可选的,@
符号和指令名称之间,以及最后一个属性和结束%>
之间的空格是可选的;
指令主要分为如下三种类型
3.1.1 JSP page指令
JSP page 指令用来定义当前页面的相关属性,page 指令可以在 JSP 页面的任意位置编写,通常放在 JSP 页面的顶部;
page 指令的语法如下
1 |
|
下表是与 page 指令相关的属性
以上属性除了 import 可以声明多个外,其它属性都只能出现一次
3.1.2 JSP include指令
include 指令用于在 JSP 页面引入其它内容,可以是 JSP 文件、html 文件和文本文件等,相当于把文件的内容复制到 JSP 页面。引入的文件和 JSP 页面同时编译运行,可以在页面的任何位置编写 include 指令;
使用 include 指令有以下优点:
- 增加代码的可重用性
- 使 JSP 页面的代码结构清晰易懂
- 维护简单
include 的语法如下
1 |
|
其中,file 指定需要引入文件的相对路径;
3.1.3 JSP taglib指令
在 JSP 中,我们可以使用 taglib 指令声明并引入标签库。Java API 允许在页面中自定义标签,标签库就是自定义标签的集合;
taglib 指令的语法如下
1 |
|
其中,uri 指定自定义标签库的存放位置;prefix 指定标签库的前缀。为了区分不同的标签库,在页面中使用标签库以对应的 prefix 开头;
3.2 JSP动作
JSP 动作使用 XML 语法格式的标签来控制服务器的行为,利用 JSP 动作可以动态地插入文件、重用 JavaBean 组件、把用户重定向到另一个页面、为 Java 插件生成 HTML 代码等;
JSP 动作与 JSP 指令的不同之处如下:
- JSP 指令在
翻译阶段执行
,从而设置整个 JSP 页面的属性。JSP 页面被执行时首先进入翻译阶段,程序会先查找页面中的 JSP 指令,并将它们转换成 Servlet。所以,JSP 指令是在页面转换时期被编译执行的,且编译一次; - JSP 动作在
请求处理阶段执行
,它们只有执行时才实现自己的功能。通常用户每请求一次,动作标识就会执行一次;
JSP动作语法如下
1 |
|
或
1 |
|
action_name 表示 JSP 动作名称,attribute 表示相应 JSP 动作的属性名称,常用的 JSP 动作如下表所示
关于上述几个JSP动作,这里不再赘述,详情参考JSP动作 (biancheng.net);
4.内置对象
为了简化页面的开发过程,JSP 提供了一些内置对象;
JSP 内置对象又称为隐式对象,它们由容器实现和管理。在 JSP 页面中,这些内置对象不需要预先声明,也不需要进行实例化,我们可以直接在脚本和表达式中使用;
注意:JSP 内置对象只能在脚本和表达式中使用,在声明中不能使用;
JSP 中定义了 9 个内置对象,它们分别是:request、response、session、application、out、pagecontext、config、page 和 exception,这些对象在客户端和服务器端交互的过程中分别完成不同的功能
JSP 的内置对象主要有以下特点:
- 由 JSP 规范提供,不用编写者实例化;
- 通过 Web 容器实现和管理;
- 所有 JSP 页面均可使用;
- 只有在脚本元素的表达式或代码段中才能使用;
在 JSP 九大内置对象中,包含四个域对象,它们分别是:pageContext(page 域对象)、request(request 域对象)、session(session 域对象)、以及 application(application 域对象);JSP 中的 4 个域对象都能通过以下 3 个方法,对属性进行保存、获取和移除操作
JSP 中的 4 个域对象的作用域各不相同
关于上述九个内置对象这里我们不再赘述,详情参考JSP九大内置对象一览表 (biancheng.net);
三、JSTL标签库
注意,JSP自定义标签和动态标签是JSP自己的标签,不是由第三方提供,所以使用JSP动态标签时无需使用taglib指令“导包”;
JSTL标签库可以看作是第三方提供的库;
无论是自定义的JSP标签,还是JSP自己的动态标签,还有第三方的标签,最终都会对应一组方法的调用;
JSTL也称为JSP Standard Tag Library,即JSP标准标签库,是JSP标签的集合,封装了JSP应用的通用核心功能;
JSP 标签是一组与 HTML 标签相似,但又比 HTML 标签强大的功能标签。JSTL 用来简化 JSP 开发,可以使我们不用嵌入 Java 代码就能够开发出复杂的 JSP 页面;
JSTL 包含 5 类标签库:core 标签库、fmt 标签库、fn 标签库、XML 标签库和 SQL 标签库。这 5 类标签库基本覆盖了 Web 开发中的所涉及的技术展示;
使用 taglib 指令导入标签库描述符文件,例如要使用 JSTL 核心标签库,需要在 JSP 页面的上方增加如下指令
1 |
|
taglib 指令通过 uri 属性引入某个标签库的配置文件,JSP 页面中通过 prefix 属性指定的前缀即可访问该标签库中的某个标签功能,如 <c:out>
;
1.core 标签库
JSTL 核心(core)标签是最常用的 JSTL 标签,导入核心标签库的语法如下
1 |
|
2.fmt 标签库
JSTL 格式化(fmt)标签可以通过很简单的方式转换数字、日期,导入格式化标签库的语法如下
1 |
|
3.SQL 标签库
JSTL SQL 标签提供了许多操作数据库(MySQL、Oracle、SQL Server 等)的标签。虽然在大型的网站中不建议使用这种标签库,但在小型网站中经常会用到。导入 SQL 标签库的语法如下
1 |
|
4.fn 标签库
JSTL 函数(fn)标签大部分是通用的字符串处理函数,导入函数标签库的语法如下
1 |
|