什么是 JSP? Jakarta Server Pages简介
Jakarta Server Pages(以前称为 JavaServer Pages)是一种 Java 标准技术,开发人员使用它为 Java Web 应用程序编写动态的、数据驱动的网页。 JSP 建立在 Java Servlet(又名 Jakarta Servlet)规范之上,是 Jakarta EE 中用于持续支持和升级的 Java Web 技术之一。
JSP 和 servlet 通常一起工作,尤其是在较旧的 Java Web 应用程序中。 从编码的角度来看,JSP 和 servlet 之间最明显的区别是,对于 servlet,您可以编写 Java 代码,然后将客户端标记(如 HTML)嵌入到该代码中。 使用 JSP,您从客户端脚本或标记开始,然后嵌入 JSP 标记以将您的页面连接到 Java 后端。
将 JSP 视为一种编写具有与后端交互的超能力的标记的方法。 通常,HTML 之类的标记会发送到客户端,并在客户端通过 JavaScript 与后端服务器进行交互。 JSP 使用特殊命令对 HTML 进行预处理以访问和使用服务器功能,然后将编译后的页面发送给客户端。
Jakarta EE 中的 JSP
在 Java EE 8 发布后,Oracle 将 Java 企业版 (Java EE) 的管理权移交给了 Eclipse 基金会。 展望未来,Java 企业平台更名为 Jakarta EE。 与 Servlet 和 JSF 规范一起,JSP 或 Jakarta Server Pages 现在是 Jakarta EE 的一部分。
JSP 和 JSF
JSP 与 JSF 或 Jakarta Server Faces(以前称为 JavaServer Faces)密切相关。 JSF 是用于构建模型-视图-控制器 (MVC) Web 应用程序的 Java 规范。 它是 Eclipse Mojarra、MyFaces 和 PrimeFaces 等 Java Web 框架的标准。 虽然将 JSP 用作旧版 JSF 应用程序的前端并不少见,但 Facelets 是现代 JSF 实现的首选视图技术。
开发人员还在使用 JSP 吗?
开发人员仍在为某些应用程序使用 JSP。 与 Jamstack 等更现代的方法或 Thymeleaf 等模板引擎相比,这是一种更简单的技术,但有时简单就是要走的路。
JSP 是 Java 的核心 Web 技术。 作为开发人员,我们可以相对快速、轻松地构建 JSP 页面,并且它们可以与 Tomcat 等 servlet 容器中的 servlet 无缝交互。 您可以说 JSP 是 Java 生态系统,等同于 .NET 世界中的 PHP 和 ASP。
您会在较旧的 Java Web 应用程序中遇到 JSP。 有时,您可能仍然会发现它对于构建简单的动态 Java 网页很有用。 作为 Java 开发人员,您应该熟悉 JSP 以及如何在您的程序中使用它。
学习 JSP 和 Jakarta 标准标签库
本文将简要介绍 JSP 或 Jakarta Server Faces,包括 Jakarta Standard Tag Library (JSTL)。 您将学习如何编写简单的 HTML 页面、嵌入 JSP 标记以连接到 servlet,以及如何在 servlet 容器中运行该页面。 请参阅本系列之前的文章以了解有关 servlet 和 JSF 的更多信息。
编写 JSP 页面
一个简单的 JSP 页面由嵌入了 JSP 标记的 HTML 标记组成。 JSP 文件的扩展名为 .jsp。 JSP 服务器(也称为 JSP 容器)被配置为将 HTTP 请求定向到特定的 JSP 页面,然后该页面负责呈现 HTTP 响应。
当请求到达时,文件在服务器上进行处理,HTML 呈现为应用程序视图,即网页。 嵌入的 JSP 标记将用于调用服务器端代码和数据。 JSP 的最终产品是客户端浏览器可以按原样理解的 vanilla HTML。 图 1 中的图表显示了 HTML、JSP 和 Web 应用程序服务器之间的交互。
国际数据集团
图 1. Web 应用程序中的 Jakarta Server Pages (JSP) 页面概述。
清单 1 显示了一个简单的 JSP 页面。
清单 1. 一个简单的 JSP 页面
<html>
<body>
<p>${2 * 2} should equal 4</p>
</body>
</html>
在这里,您会看到一个包含 JSP 表达式的 HTML 块,它是使用表达式语言 (EL) 编写的对 Java 服务器的指令。 在表达式中 ${2 * 2}
, 这 ${}
是用于将代码插入 HTML 的 JSP 语法。 带花括号的美元符号告诉 JSP 处理器:“稍等一下,我们即将开始讨论一些您需要注意的特殊事项。”执行时,JSP 页面将输出执行任何内容的结果在表达式中。在这种情况下,输出将是数字 4。
servlet 容器中的 JSP
JSP 页面必须部署在 servlet 容器内。 为了部署基于 JSP 和 servlet 的 Java Web 应用程序,您需要将 .jsp 文件、Java 代码和应用程序元数据打包到一个 .war 文件中,这是一个简单的 .zip 文件,具有 Web 应用程序的常规结构。
一旦将 JSP 加载到 servlet 容器中,它就会被编译成 servlet。 JSP 和 servlet 具有相似的特征,包括访问和响应请求对象的能力。
Servlet 容器与应用服务器
在 Java 世界中,servlet 容器,也称为 Web 服务器,就像应用服务器的精简版(啤酒)。 servlet 容器处理请求和响应交互,并允许这些交互与 Web 应用程序的 Java 企业功能子集交互。 Java 应用程序服务器包括 servlet 容器作为完整 Java 企业堆栈的一部分,包括 EJB、JPA、JMS 等。
如何在 Tomcat 中使用 JSP
我们将使用 Tomcat 中的示例应用程序来帮助您开始使用 Jakarta Server Pages。 如果您还没有安装 Tomcat,请浏览到 Tomcat 下载页面并为您的操作系统选择 Tomcat 安装。 在撰写本文时,Tomcat 10 是当前版本,与 Jakarta Servlet 6 和 Jakarta Server Pages 3.1 兼容。
您可以将 Tomcat 安装为 Windows 服务,或者从命令行运行它 /bin/catalina.sh
开始或 /bin/catalina.bat
. 无论哪种方式,启动 Tomcat,然后转到 localhost:8080 以查看图 2 中所示的 Tomcat 欢迎页面。
国际数据集团
图 2. Tomcat 欢迎页面。
JSP 中的隐式对象
在 Tomcat 欢迎页面上,单击示例链接,然后单击 JSP 示例。
接下来,打开隐式对象执行 Web 应用程序。 图 3 显示了这个示例应用程序的输出。 花点时间研究一下输出。 默认情况下,它描述的元素在 JSP 页面中始终可用。
国际数据集团
图 3. JSP 页面的示例输出。
请注意,JSP 2.0 和 JSP 3.0 之间不需要更改代码,这是 Jakarta EE 的当前更新。 隐式对象示例使用 JSP 2.0。
请求参数
隐式对象是可通过 JSP 页面访问的内置对象。 当您开发网页时,您将使用这些对象来访问诸如请求参数之类的东西,这些是在发出 HTTP 请求时从客户端浏览器发送过来的数据。
考虑隐式对象应用程序的浏览器 URL:http://localhost:8080/examples/jsp/jsp2/el/implicit-objects.jsp?foo=bar。
请注意,此页面没有什么特别之处; 我们只是用它来查看 URL 参数是如何被访问的。 参数是 ?foo=bar
,你可以看到它反映在网页的输出中,其中表格显示 EL Expression 并且值为 bar
. 要对此进行测试,请将 URL 更改为 http://localhost:8080/examples/jsp/jsp2/el/implicit-objects.jsp?foo=zork,按 Enter,您将看到输出中反映的更改。
这个例子非常简单的介绍了使用JSP标签访问服务器端的请求参数。 在这种情况下,JSP 页面使用名为 param
访问 Web 应用程序的请求参数。 这 param
object 在您在清单 1 中看到的 JSP 表达式语法中可用。在那个例子中,我们使用表达式来做一些数学运算: ${2 * 2}
,这导致输出 4。在这种情况下,表达式用于访问对象和该对象上的字段: ${param.foo}
. 接下来,我们将更仔细地查看隐式对象示例。
Web 应用程序中的 JSP
在 Implicit Objects 页面上,单击后退箭头,然后单击 Source 链接。 这将引导您找到隐式对象 Web 应用程序的 JSP 代码,如清单 2 所示。
清单 2. 隐式对象 Web 应用程序的 JSP 代码
<%@page contentType="text/html; charset=UTF-8" %>
<%@ taglib prefix="fn" uri="http://java.sun.com/jsp/jstl/functions" %>
<html>
<head>
<title>JSP 2.0 Expression Language - Implicit Objects</title>
</head>
<body>
<h1>JSP 2.0 Expression Language - Implicit Objects</h1>
<hr>
This example illustrates some of the implicit objects available
in the Expression Language. The following implicit objects are
available (not all illustrated here):
<ul>
<li>pageContext - the PageContext object</li>
<li>pageScope - a Map that maps page-scoped attribute names to
their values</li>
<li>requestScope - a Map that maps request-scoped attribute names
to their values</li>
<li>sessionScope - a Map that maps session-scoped attribute names
to their values</li>
<li>applicationScope - a Map that maps application-scoped attribute
names to their values</li>
<li>param - a Map that maps parameter names to a single String
parameter value</li>
<li>paramValues - a Map that maps parameter names to a String[] of
all values for that parameter</li>
<li>header - a Map that maps header names to a single String
header value</li>
<li>headerValues - a Map that maps header names to a String[] of
all values for that header</li>
<li>initParam - a Map that maps context initialization parameter
names to their String parameter value</li>
<li>cookie - a Map that maps cookie names to a single Cookie object.</li>
</ul>
<blockquote>
<u><b>Change Parameter</b></u>
<form action="implicit-objects.jsp" method="GET">
foo = <input type="text" name="foo" value="${fn:escapeXml(param["foo"])}">
<input type="submit">
</form>
<br>
<code>
<table border="1">
<thead>
<td><b>EL Expression</b></td>
<td><b>Result</b></td>
</thead>
<tr>
<td>${param.foo}</td>
<td>${fn:escapeXml(param["foo"])} </td>
</tr>
<tr>
<td>${param["foo"]}</td>
<td>${fn:escapeXml(param["foo"])} </td>
</tr>
<tr>
<td>${header["host"]}</td>
<td>${fn:escapeXml(header["host"])} </td>
</tr>
<tr>
<td>${header["accept"]}</td>
<td>${fn:escapeXml(header["accept"])} </td>
</tr>
<tr>
<td>${header["user-agent"]}</td>
<td>${fn:escapeXml(header["user-agent"])} </td>
</tr>
</table>
</code>
</blockquote>
</body>
</html>
JSP函数
如果您熟悉 HTML,那么清单 2 中的代码应该很容易理解。 你有预期的 HTML <td>
元素,然后是 ${ }
清单 1 中介绍的 JSP 表达式语法。但是请注意 param.foo
:
<td>${fn:escapeXml(param["foo"])} </td>
在这里, fn:escapeXML()
是一个 JSP 函数。
JSP 函数封装了一大块可重用的功能。 在这种情况下,功能是转义 XML。 JSP 提供了多种功能,您也可以自己创建功能。 要使用一个函数,您需要将它的库导入到您的 JSP 页面中,然后调用该函数。
在清单 2 中,我们包括 escapeXML
使用以下行运行:
<%@ taglib prefix="fn" uri="http://java.sun.com/jsp/jstl/functions" %>
语法非常清楚:它导入所需的函数并为它们分配一个前缀(在本例中为“fn
“) 可用于以下所有表达式。
雅加达标准标签库 (JSTL)
清单 2 中的导入行调用 taglib
,这是标签库的缩写。 在本例中,我们导入了 Jakarta 标准标签库 (JSTL)。 标记库为 JSP 定义了可重用的功能位。 JSTL 是标准标记库,包含每个 servlet 和 JSP 实现(包括 Tomcat)附带的标记库集合。
“函数”库只是 JSTL 中包含的标记库之一。 另一个常见的标签库是核心库,您可以通过调用导入它:
<%@ taglib uri = "http://java.sun.com/jsp/jstl/core" prefix = "c" %>
喜欢 "fn"
, 这 "c"
名称是约定俗成的; 您会在大多数 JSP 页面中看到它。
使用 JSTL 保护 JSP 页面
以下示例标记来自 JSTL 核心库: