JSP - 快速指南
JSP - Overview
什么是JavaServer Pages?
JavaServer Pages(JSP)是一种用于开发支持动态内容的Web页面的技术。 这有助于开发人员通过使用特殊的JSP标记在HTML页面中插入Java代码,其中大多数标记以结尾。
JavaServer Pages组件是一种Java servlet,旨在实现Java Web应用程序的用户界面角色。 Web开发人员将JSP编写为组合HTML或XHTML代码,XML元素以及嵌入式JSP操作和命令的文本文件。
使用JSP,您可以通过网页表单收集用户的输入,从数据库或其他来源显示记录,并动态创建Web页面。
JSP标记可用于各种目的,例如从数据库检索信息或注册用户首选项,访问JavaBeans组件,在页面之间传递控制,以及在请求,页面等之间共享信息。
为什么要使用JSP?
JavaServer Pages通常与使用Common Gateway Interface (CGI)实现的程序具有相同的用途。 但与CGI相比,JSP提供了几个优势。
性能明显更好,因为JSP允许在HTML页面中嵌入动态元素而不是单独的CGI文件。
JSP总是在服务器处理之前进行编译,这与CGI/Perl不同,后者要求服务器在每次请求页面时加载解释器和目标脚本。
JavaServer Pages构建于Java Servlets API之上,因此与Servlet一样,JSP也可以访问所有强大的Enterprise Java API,包括JDBC, JNDI, EJB, JAXP,等。
JSP页面可以与处理业务逻辑的servlet结合使用,Java servlet模板引擎支持该模型。
最后,JSP是Java EE的一个组成部分,Java EE是企业级应用程序的完整平台。 这意味着JSP可以在最复杂和最苛刻的应用程序中发挥作用。
JSP的优点
下表列出了使用JSP优于其他技术的其他优点 -
与Active Server Pages(ASP)
JSP的优点是双重的。 首先,动态部分是用Java编写的,而不是用Visual Basic或其他MS特定语言编写的,因此它更强大,更易于使用。 其次,它可以移植到其他操作系统和非Microsoft Web服务器。
与Pure Servlets相比
编写(和修改!)常规HTML比使用大量生成HTML的println语句更方便。
vs. Server-Side Includes (SSI)
SSI实际上仅用于简单包含,而不是用于使用表单数据,进行数据库连接等的“真实”程序。
vs. JavaScript
JavaScript可以在客户端上动态生成HTML,但很难与Web服务器交互以执行复杂的任务,如数据库访问和图像处理等。
与静态HTML
当然,常规HTML不能包含动态信息。
接下来是什么 (What is Next?)
我会带你一步一步地设置你的环境,从JSP开始。 我假设您已经熟练掌握Java编程以继续学习JSP。
如果您不了解Java编程语言,那么我们建议您通过我们的Java教程来理解Java编程。
JSP - Environment Setup
您可以在开发环境中开发JSP程序,测试它们并最终运行它们。
本教程将指导您设置JSP开发环境,其中包括以下步骤 -
设置Java Development Kit
此步骤涉及下载Java软件开发工具包(SDK)的实现并适当地设置PATH环境变量。
您可以从Oracle的Java站点下载SDK - Java SE下载 。
下载Java实现后,请按照给出的说明安装和配置设置。 最后设置PATH and JAVA_HOME环境变量来引用包含java和javac的目录,通常分别是java_install_dir/bin和java_install_dir 。
如果您运行的是Windows并在C:\jdk1.5.0_20安装SDK,则需要在C:\autoexec.bat文件中添加以下行。
set PATH = C:\jdk1.5.0_20\bin;%PATH%
set JAVA_HOME = C:\jdk1.5.0_20
或者,在Windows NT/2000/XP ,您也可以右键单击“ My Computer ,选择“ Properties ,然后选择“ Advanced ,再选择“ Environment Variables 。 然后,您将更新PATH值并按OK按钮。
在Unix(Solaris,Linux等)上,如果SDK安装在/usr/local/jdk1.5.0_20并且您使用C shell,则将以下内容放入.cshrc文件中。
setenv PATH /usr/local/jdk1.5.0_20/bin:$PATH
setenv JAVA_HOME /usr/local/jdk1.5.0_20
或者,如果您使用Integrated Development Environment (IDE)如Borland JBuilder, Eclipse, IntelliJ IDEA或Sun ONE Studio ,请编译并运行一个简单程序以确认IDE知道您在何处安装Java。
设置Web服务器:Tomcat
市场上有许多支持JavaServer Pages和Servlets开发的Web服务器。 有些Web服务器可以免费下载,Tomcat就是其中之一。
Apache Tomcat是JavaServer Pages和Servlet技术的开源软件实现,可以作为测试JSP和Servlet的独立服务器,并且可以与Apache Web Server集成。 以下是在您的计算机上设置Tomcat的步骤 -
从https://tomcat.apache.org/下载最新版本的Tomcat。
下载安装后,将二进制分发包解压到一个方便的位置。 例如,在C:\apache-tomcat-5.5.29 on windows, or /usr/local/apache-tomcat-5.5.29 Linux/Unix上的C:\apache-tomcat-5.5.29 on windows, or /usr/local/apache-tomcat-5.5.29 ,创建指向这些位置的CATALINA_HOME环境变量。
可以通过在Windows机器上执行以下命令来启动Tomcat -
%CATALINA_HOME%\bin\startup.bat
or
C:\apache-tomcat-5.5.29\bin\startup.bat
可以通过在Unix(Solaris,Linux等)机器上执行以下命令来启动Tomcat -
$CATALINA_HOME/bin/startup.sh
or
/usr/local/apache-tomcat-5.5.29/bin/startup.sh
成功启动后,Tomcat附带的默认Web应用程序将通过访问http://localhost:8080/ 。
执行后,您将收到以下输出 -
有关配置和运行Tomcat的更多信息,请参见此处包含的文档以及Tomcat网站 - https://tomcat.apache.org/ 。
可以通过在Windows机器上执行以下命令来停止Tomcat -
%CATALINA_HOME%\bin\shutdown
or
C:\apache-tomcat-5.5.29\bin\shutdown
可以通过在Unix(Solaris,Linux等)机器上执行以下命令来停止Tomcat -
$CATALINA_HOME/bin/shutdown.sh
or
/usr/local/apache-tomcat-5.5.29/bin/shutdown.sh
设置CLASSPATH
由于servlet不是Java Platform,Standard Edition的一部分,因此必须为编译器识别servlet类。
如果您运行的是Windows,则需要在C:\autoexec.bat文件中添加以下行。
set CATALINA = C:\apache-tomcat-5.5.29
set CLASSPATH = %CATALINA%\common\lib\jsp-api.jar;%CLASSPATH%
或者,在Windows NT/2000/XP ,您也可以右键单击“ My Computer ,选择“ Properties ,然后选择“ Advanced ,再选择“ Environment Variables 。 然后,您将更新CLASSPATH值并按“确定”按钮。
在Unix(Solaris,Linux等)上,如果您使用的是C shell,则可以将以.cshrc放入.cshrc文件中。
setenv CATALINA = /usr/local/apache-tomcat-5.5.29
setenv CLASSPATH $CATALINA/common/lib/jsp-api.jar:$CLASSPATH
NOTE - 假设您的开发目录是C:\JSPDev (Windows)或/usr/JSPDev (Unix) ,那么您还需要在CLASSPATH中添加这些目录。
JSP - Architecture
Web服务器需要JSP引擎,即处理JSP页面的容器。 JSP容器负责拦截JSP页面的请求。 本教程使用具有内置JSP容器的Apache来支持JSP页面开发。
JSP容器与Web服务器一起使用,以提供JSP所需的运行时环境和其他服务。 它知道如何理解作为JSP一部分的特殊元素。
下图显示了JSP容器和JSP文件在Web应用程序中的位置。
JSP处理
以下步骤说明了Web服务器如何使用JSP创建网页 -
与普通页面一样,您的浏览器会向Web服务器发送HTTP请求。
Web服务器识别出HTTP请求是针对JSP页面的,并将其转发到JSP引擎。 这是通过使用以.jsp而不是.html结尾的URL或JSP页面来完成的。
JSP引擎从磁盘加载JSP页面并将其转换为servlet内容。 这种转换非常简单,其中所有模板文本都转换为println()语句,并且所有JSP元素都转换为Java代码。 此代码实现页面的相应动态行为。
JSP引擎将servlet编译为可执行类,并将原始请求转发给servlet引擎。
称为servlet引擎的Web服务器的一部分加载Servlet类并执行它。 在执行期间,servlet以HTML格式生成输出。 输出通过HTTP响应中的servlet引擎传递给Web服务器。
Web服务器根据静态HTML内容将HTTP响应转发到您的浏览器。
最后,Web浏览器处理HTTP响应中动态生成的HTML页面,就像它是静态页面一样。
所有上述步骤均可在下图中看到 -
通常,JSP引擎检查JSP文件的servlet是否已存在,以及JSP上的修改日期是否早于servlet。 如果JSP比其生成的servlet旧,则JSP容器假定JSP未更改,并且生成的servlet仍与JSP的内容匹配。 这使得该过程比使用其他脚本语言(例如PHP)更高效,因此更快。
所以在某种程度上,JSP页面实际上只是编写servlet的另一种方式,而不必是Java编程。 除了转换阶段之外,JSP页面的处理方式与常规servlet完全相同。
JSP - Lifecycle
在本章中,我们将讨论JSP的生命周期。 理解JSP的低级功能的关键是理解它们遵循的简单生命周期。
JSP生命周期被定义为从创建到销毁的过程。 这类似于servlet生命周期,其中包含将JSP编译为servlet所需的附加步骤。
JSP遵循的路径
以下是JSP遵循的路径 -
- Compilation
- Initialization
- Execution
- Cleanup
JSP生命周期的四个主要阶段与Servlet生命周期非常相似。 以下描述了四个阶段 -
JSP编译
当浏览器请求JSP时,JSP引擎首先检查是否需要编译页面。 如果页面从未编译过,或者自上次编译后JSP已被修改,则JSP引擎将编译该页面。
编译过程包括三个步骤 -
- 解析JSP。
- 将JSP转换为servlet。
- 编译servlet。
JSP初始化
当容器加载JSP时,它会在处理任何请求之前调用jspInit()方法。 如果需要执行特定于JSP的初始化,请覆盖jspInit()方法 -
public void jspInit(){
// Initialization code...
}
通常,初始化只执行一次,与servlet init方法一样,通常初始化数据库连接,打开文件,并在jspInit方法中创建查找表。
JSP执行
JSP生命周期的这一阶段表示在销毁JSP之前与请求的所有交互。
每当浏览器请求JSP并且页面已加载并初始化时,JSP引擎就会调用JSP中的_jspService()方法。
_jspService()方法将HttpServletRequest和HttpServletResponse作为其参数,如下所示 -
void _jspService(HttpServletRequest request, HttpServletResponse response) {
// Service handling code...
}
JSP的_jspService()方法是在请求的基础上调用的。 这负责为该请求生成响应,并且该方法还负责生成对所有七种HTTP方法的响应,即GET, POST, DELETE等。
JSP清理
JSP生命周期的销毁阶段表示从容器中删除JSP的时间。
jspDestroy()方法是servlet的destroy方法的JSP等价物。 需要执行任何清理时覆盖jspDestroy,例如释放数据库连接或关闭打开的文件。
jspDestroy()方法具有以下形式 -
public void jspDestroy() {
// Your cleanup code goes here.
}
JSP - Syntax
在本章中,我们将讨论JSP中的语法。 我们将理解JSP开发所涉及的简单语法(即元素)的基本用法。
JSP的元素
JSP的元素已在下面描述 -
Scriptlet
scriptlet可以包含任意数量的JAVA语言语句,变量或方法声明,或者在页面脚本语言中有效的表达式。
以下是Scriptlet的语法 -
<% code fragment %>
您可以编写上述语法的XML等价物,如下所示 -
<jsp:scriptlet>
code fragment
</jsp:scriptlet>
您编写的任何文本,HTML标记或JSP元素都必须位于scriptlet之外。 以下是JSP的简单和第一个示例 -
<html>
<head><title>Hello World</title></head>
<body>
Hello World!<br/>
<%
out.println("Your IP address is " + request.getRemoteAddr());
%>
</body>
</html>
NOTE - 假设Apache Tomcat安装在C:\apache-tomcat-7.0.2中,并且您的环境是根据环境设置教程设置的。
让我们将上述代码保存在JSP文件hello.jsp ,并将此文件放在C:\apache-tomcat7.0.2\webapps\ROOT目录中。 使用URL http://localhost:8080/hello.jsp浏览相同的http://localhost:8080/hello.jsp 。 上面的代码将生成以下结果 -
JSP声明
声明声明可以在JSP文件中稍后在Java代码中使用的一个或多个变量或方法。 在JSP文件中使用变量或方法之前,必须声明该变量或方法。
以下是JSP声明的语法 -
<%! declaration; [ declaration; ]+ ... %>
您可以编写上述语法的XML等价物,如下所示 -
<jsp:declaration>
code fragment
</jsp:declaration>
以下是JSP声明的示例 -
<%! int i = 0; %>
<%! int a, b, c; %>
<%! Circle a = new Circle(2.0); %>
JSP表达式
JSP表达式元素包含一个脚本语言表达式,该表达式被计算,转换为String,并插入表达式出现在JSP文件中的位置。
因为表达式的值转换为String,所以您可以在JSP文件中使用文本行中的表达式,无论它是否用HTML标记。
表达式元素可以包含根据Java语言规范有效的任何表达式,但不能使用分号来结束表达式。
以下是JSP表达式的语法 -
<%= expression %>
您可以编写上述语法的XML等价物,如下所示 -
<jsp:expression>
expression
</jsp:expression>
以下示例显示了JSP表达式 -
<html>
<head><title>A Comment Test</title></head>
<body>
<p>Today's date: <%= (new java.util.Date()).toLocaleString()%></p>
</body>
</html>
上面的代码将生成以下结果 -
<p>Today's date: 11-Sep-2010 21:24:25</p>
JSP评论
JSP注释标记JSP容器应忽略的文本或语句。 当您想要隐藏或“注释掉”JSP页面的一部分时,JSP注释很有用。
以下是JSP注释的语法 -
<%-- This is JSP comment --%>
以下示例显示了JSP注释 -
<html>
<head><title>A Comment Test</title></head>
<body>
<h2>A Test of Comments</h2>
<%-- This comment will not be visible in the page source --%>
</body>
</html>
上面的代码将生成以下结果 -
<h2>A Test of Comments</h2>
在各种情况下,您可以使用少量特殊构造来插入注释或字符,否则这些注释或字符将被特殊处理。 这是一个总结 -
S.No. | 语法和目的 |
---|---|
1 | 《%-- comment --%》 JSP评论。 被JSP引擎忽略。 |
2 | 《!-- comment --》 HTML评论。 被浏览器忽略。 |
3 | 《\% 表示静态 |
4 | %\》 表示静态%> literal。 |
5 | \' 使用单引号的属性中的单引号。 |
6 | \" 使用双引号的属性中的双引号。 |
JSP指令
JSP指令会影响servlet类的整体结构。 它通常有以下形式 -
<%@ directive attribute="value" %>
指令标签有三种类型 -
S.No. | 指令和说明 |
---|---|
1 | 《%@ page ... %》 定义与页面相关的属性,例如脚本语言,错误页面和缓冲要求。 |
2 | 《%@ include ... %》 在翻译阶段包含一个文件。 |
3 | 《%@ taglib ... %》 声明包含页面中使用的自定义操作的标记库 |
我们将在JSP-Directives的单独章节中解释JSP指令
JSP动作
JSP操作使用XML语法中的构造来控制servlet引擎的行为。 您可以动态插入文件,重用JavaBeans组件,将用户转发到另一个页面,或者为Java插件生成HTML。
Action元素只有一种语法,因为它符合XML标准 -
<jsp:action_name attribute="value" />
Action元素基本上是预定义的函数。 下表列出了可用的JSP操作 -
S.No. | 语法和目的 |
---|---|
1 | jsp:include 在请求页面时包含文件。 |
2 | jsp:useBean 查找或实例化JavaBean。 |
3 | jsp:setProperty 设置JavaBean的属性。 |
4 | jsp:getProperty 将JavaBean的属性插入到输出中。 |
5 | jsp:forward 将请求者转发到新页面。 |
6 | jsp:plugin 生成特定于浏览器的代码,为Java插件生成OBJECT或EMBED标记。 |
7 | jsp:element 动态定义XML元素。 |
8 | jsp:attribute 定义动态定义的XML元素的属性。 |
9 | jsp:body 定义动态定义的XML元素的主体。 |
10 | jsp:text 用于在JSP页面和文档中编写模板文本。 |
我们将在JSP - Actions的单独章节中解释JSP 操作
JSP隐式对象
JSP支持九个自动定义的变量,也称为隐式对象。 这些变量是 -
S.No. | 对象和描述 |
---|---|
1 | request 这是与请求关联的HttpServletRequest对象。 |
2 | response 这是与客户端响应关联的HttpServletResponse对象。 |
3 | out 这是用于将输出发送到客户端的PrintWriter对象。 |
4 | session 这是与请求关联的HttpSession对象。 |
5 | application 这是与应用程序上下文关联的ServletContext对象。 |
6 | config 这是与页面关联的ServletConfig对象。 |
7 | pageContext 这封装了特定于服务器的功能,如性能更高的JspWriters 。 |
8 | page 这只是它的同义词,用于调用已转换的servlet类定义的方法。 |
9 | Exception Exception对象允许指定的JSP访问异常数据。 |
我们将在JSP - Implicit Objects的单独章节中解释JSP Implicit Objects 。
Control-Flow Statements
您可以在JSP编程中使用Java的所有API和构建块,包括决策语句,循环等。
Decision-Making Statements
if...else块像普通的Scriptlet一样开始,但Scriptlet在每一行都关闭,Scriptlet标签之间包含HTML文本。
<%! int day = 3; %>
<html>
<head><title>IF...ELSE Example</title></head>
<body>
<% if (day == 1 || day == 7) { %>
<p> Today is weekend</p>
<% } else { %>
<p> Today is not weekend</p>
<% } %>
</body>
</html>
上面的代码将生成以下结果 -
Today is not weekend
现在看看下面的switch...case块,它使用out.println()和Scriptletas内部写了一点点不同 -
<%! int day = 3; %>
<html>
<head><title>SWITCH...CASE Example</title></head>
<body>
<%
switch(day) {
case 0:
out.println("It\'s Sunday.");
break;
case 1:
out.println("It\'s Monday.");
break;
case 2:
out.println("It\'s Tuesday.");
break;
case 3:
out.println("It\'s Wednesday.");
break;
case 4:
out.println("It\'s Thursday.");
break;
case 5:
out.println("It\'s Friday.");
break;
default:
out.println("It's Saturday.");
}
%>
</body>
</html>
上面的代码将生成以下结果 -
<p>It's Wednesday.</p>
循环语句
您还可以在Java中使用三种基本类型的循环块: for, while, and do…while JSP编程中的块。
让我们看一下以下for循环示例 -
<%! int fontSize; %>
<html>
<head><title>FOR LOOP Example</title></head>
<body>
<%for ( fontSize = 1; fontSize <= 3; fontSize++){ %>
<font color = "green" size = "<%= fontSize %>">
JSP Tutorial
</font><br />
<%}%>
</body>
</html>
上面的代码将生成以下结果 -
<font color="green" size="1">
JSP Tutorial
</font>
<font color="green" size="2">
JSP Tutorial
</font>
<font color="green" size="3">
JSP Tutorial
</font>
以上示例可以使用while循环编写如下 -
<%! int fontSize; %>
<html>
<head><title>WHILE LOOP Example</title></head>
<body>
<%while ( fontSize <= 3){ %>
<font color = "green" size = "<%= fontSize %>">
JSP Tutorial
</font><br />
<%fontSize++;%>
<%}%>
</body>
</html>
上面的代码将生成以下结果 -
<font color="green" size="1">
JSP Tutorial
</font>
<font color="green" size="2">
JSP Tutorial
</font>
<font color="green" size="3">
JSP Tutorial
</font>
JSP运算符
JSP支持Java支持的所有逻辑和算术运算符。 下表列出了所有具有最高优先级的运算符出现在表的顶部,那些最低的运算符出现在底部。
在表达式中,将首先评估更高优先级的运算符。
类别 | 操作者 | 关联性 |
---|---|---|
Postfix | ()[]。 (点运算符) | 左到右 |
Unary | ++ - - ! 〜 | 右到左 |
Multiplicative | * /% | 左到右 |
Additive | + - | 左到右 |
Shift | >> >>> << | 左到右 |
Relational | >> = << = | 左到右 |
Equality | ==!= | 左到右 |
Bitwise AND | & | 左到右 |
Bitwise XOR | ^ | 左到右 |
Bitwise OR | | | 左到右 |
Logical AND | && | 左到右 |
Logical OR | || | 左到右 |
Conditional | ?: | 右到左 |
Assignment | = + = - = * =/=%= >> = << =&= ^ = | = | 右到左 |
Comma | , | 左到右 |
JSP文字
JSP表达式语言定义了以下文字 -
Boolean - true和false
Integer - 与Java一样
Floating point - 就像在Java中一样
String - 带单引号和双引号; “被转义为\”,“被转义为\”,\被转义为\\。
Null - 无效
JSP - Directives
在本章中,我们将讨论JSP中的指令。 这些指令为容器提供了指导和说明,告诉它如何处理JSP处理的某些方面。
JSP指令会影响servlet类的整体结构。 它通常有以下形式 -
<%@ directive attribute = "value" %>
指令可以有许多属性,您可以将这些属性列为键值对,并用逗号分隔。
@符号和指令名称之间以及最后一个属性和结束%>之间的空格是可选的。
指令标签有三种类型 -
S.No. | 指令和说明 |
---|---|
1 | 《%@ page ... %》 定义与页面相关的属性,例如脚本语言,错误页面和缓冲要求。 |
2 | 《%@ include ... %》 在翻译阶段包含一个文件。 |
3 | 《%@ taglib ... %》 声明包含页面中使用的自定义操作的标记库 |
JSP - 页面指令
page指令用于向容器提供指令。 这些说明适用于当前的JSP页面。 您可以在JSP页面中的任何位置编写页面指令。 按照惯例,页面指令在JSP页面的顶部进行编码。
以下是页面指令的基本语法 -
<%@ page attribute = "value" %>
您可以编写上述语法的XML等价物,如下所示 -
<jsp:directive.page attribute = "value" />
属性 (Attributes)
下表列出了与page指令相关的属性 -
S.No. | 属性和目的 |
---|---|
1 | buffer 指定输出流的缓冲模型。 |
2 | autoFlush 控制servlet输出缓冲区的行为。 |
3 | contentType 定义字符编码方案。 |
4 | errorPage 定义报告Java未经检查的运行时异常的另一个JSP的URL。 |
5 | isErrorPage 指示此JSP页面是否是由另一个JSP页面的errorPage属性指定的URL。 |
6 | extends 指定生成的servlet必须扩展的超类。 |
7 | import 指定JSP中使用的包或类的列表,如Java import语句对Java类所做的那样。 |
8 | info 定义可以使用servlet的getServletInfo()方法访问的字符串。 |
9 | isThreadSafe 定义生成的servlet的线程模型。 |
10 | language 定义JSP页面中使用的编程语言。 |
11 | session 指定JSP页面是否参与HTTP会话 |
12 | isELIgnored 指定是否忽略JSP页面中的EL表达式。 |
13 | isScriptingEnabled 确定是否允许使用脚本元素。 |
在Page Directive上查看与上述所有属性相关的更多详细信息。
包含指令
include伪指令用于在转换阶段包含文件。 该指令告诉容器在转换阶段将其他外部文件的内容与当前JSP合并。 您可以在JSP页面中的任何位置编写include指令。
该指令的一般使用形式如下 -
<%@ include file = "relative url" >
include伪指令中的文件名实际上是一个相对URL。 如果只指定没有关联路径的文件名,JSP编译器会假定该文件与JSP位于同一目录中。
您可以编写上述语法的XML等价物,如下所示 -
<jsp:directive.include file = "relative url" />
有关include指令的更多详细信息,请查看Include Directive 。
taglib指令
JavaServer Pages API允许您定义看起来像HTML或XML标记的自定义JSP标记,标记库是一组实现自定义行为的用户定义标记。
taglib指令声明JSP页面使用一组自定义标记,标识库的位置,并提供在JSP页面中标识自定义标记的方法。
taglib指令遵循以下语法 -
<%@ taglib uri="uri" prefix = "prefixOfTag" >
这里, uri属性值解析为容器理解的位置, prefix属性通知容器标记的哪些位是自定义操作。
您可以编写上述语法的XML等价物,如下所示 -
<jsp:directive.taglib uri = "uri" prefix = "prefixOfTag" />
有关taglib指令的更多详细信息,请查看Taglib指令 。
JSP - Actions
在本章中,我们将讨论JSP中的Actions。 这些操作使用XML语法中的构造来控制servlet引擎的行为。 您可以动态插入文件,重用JavaBeans组件,将用户转发到另一个页面,或者为Java插件生成HTML。
Action元素只有一种语法,因为它符合XML标准 -
<jsp:action_name attribute = "value" />
Action元素基本上是预定义的函数。 下表列出了可用的JSP操作 -
S.No. | 语法和目的 |
---|---|
1 | jsp:include 在请求页面时包含文件。 |
2 | jsp:useBean 查找或实例化JavaBean。 |
3 | jsp:setProperty 设置JavaBean的属性。 |
4 | jsp:getProperty 将JavaBean的属性插入到输出中。 |
5 | jsp:forward 将请求者转发到新页面。 |
6 | jsp:plugin 生成特定于浏览器的代码,为Java插件生成OBJECT或EMBED标记。 |
7 | jsp:element 动态定义XML元素。 |
8 | jsp:attribute 定义动态定义的XML元素的属性。 |
9 | jsp:body 定义动态定义的XML元素的主体。 |
10 | jsp:text 用于在JSP页面和文档中编写模板文本。 |
共同属性
所有Action元素都有两个共同的属性: id属性和scope属性。
Id属性
id属性唯一标识Action元素,并允许在JSP页面内引用该操作。 如果Action创建对象的实例,则可以使用id值通过隐式对象PageContext引用它。
范围属性
此属性标识Action元素的生命周期。 id属性和scope属性直接相关,因为scope属性确定与id关联的对象的生命周期。 scope属性有四个可能的值: (a) page, (b)request, (c)session和(d) application 。
动作
此操作允许您将文件插入到正在生成的页面中。 语法如下所示 -
<jsp:include page = "relative URL" flush = "true" />
与include指令不同, include指令在JSP页面转换为servlet时插入文件,此操作在请求页面时插入文件。
下表列出了与include操作相关的属性 -
S.No. | 属性和描述 |
---|---|
1 | page 要包含的页面的相对URL。 |
2 | flush boolean属性确定包含的资源是否在其包含之前刷新其缓冲区。 |
例子 (Example)
让我们定义以下两个文件(a)date.jsp和(b) main.jsp如下 -
以下是date.jsp文件的内容 -
<p>Today's date: <%= (new java.util.Date()).toLocaleString()%></p>
以下是main.jsp文件的内容 -
<html>
<head>
<title>The include Action Example</title>
</head>
<body>
<center>
<h2>The include action Example</h2>
<jsp:include page = "date.jsp" flush = "true" />
</center>
</body>
</html>
现在让我们将所有这些文件保存在根目录中,并尝试访问main.jsp 。 您将收到以下输出 -
<center>
<h2>The include action Example</h2>
Today's date: 12-Sep-2010 14:54:22
</center>
Action
useBean动作非常通用。 它首先使用id和scope变量搜索现有对象。 如果找不到对象,则会尝试创建指定的对象。
加载bean的最简单方法如下 -
<jsp:useBean id = "name" class = "package.class" />
加载bean类后,可以使用jsp:setProperty和jsp:getProperty操作来修改和检索bean属性。
下表列出了与useBean操作相关的属性 -
S.No. | 属性和描述 |
---|---|
1 | class 指定bean的完整包名称。 |
2 | type 指定将引用该对象的变量的类型。 |
3 | beanName 给出java.beans.Beans类的instantiate()方法指定的bean的名称。 |
现在让我们在给出与这些操作相关的有效示例之前讨论jsp:setProperty和jsp:getProperty操作。
Action
setProperty操作设置Bean的属性。 必须先在此操作之前定义Bean。 使用setProperty操作有两种基本方法 -
您可以在jsp:useBean元素之后使用jsp:setProperty ,如下所示 -
<jsp:useBean id = "myName" ... />
...
<jsp:setProperty name = "myName" property = "someProperty" .../>
在这种情况下,无论是否实例化新bean或找到现有bean,都会执行jsp:setProperty 。
jsp:setProperty可以出现的第二个上下文位于jsp:useBean元素的主体内部,如下所示 -
<jsp:useBean id = "myName" ... >
...
<jsp:setProperty name = "myName" property = "someProperty" .../>
</jsp:useBean>
这里,只有在实例化新对象时才执行jsp:setProperty,而不是在找到现有对象时执行。
下表列出了与setProperty操作关联的属性 -
S.No. | 属性和描述 |
---|---|
1 | name 指定将设置其属性的bean。 Bean必须先前已定义。 |
2 | property 表示要设置的属性。 值“*”表示名称与bean属性名称匹配的所有请求参数都将传递给相应的setter方法。 |
3 | value 要分配给给定属性的值。 参数的值为null,或者参数不存在,将忽略setProperty操作。 |
4 | param param属性是请求参数的名称,该属性将接收其值。 您不能同时使用值和参数,但允许不使用它们。 |
动作
getProperty操作用于检索给定属性的值并将其转换为字符串,最后将其插入到输出中。
getProperty操作只有两个属性,这两个属性都是必需的。 getProperty操作的语法如下 -
<jsp:useBean id = "myName" ... />
...
<jsp:getProperty name = "myName" property = "someProperty" .../>
下表列出了与getProperty操作关联的必需属性 -
S.No. | 属性和描述 |
---|---|
1 | name 具有要检索的属性的Bean的名称。 Bean必须先前已定义。 |
2 | property property属性是要检索的Bean属性的名称。 |
例子 (Example)
让我们定义一个将在我们的示例中进一步使用的测试bean -
/* File: TestBean.java */
package action;
public class TestBean {
private String message = "No message specified";
public String getMessage() {
return(message);
}
public void setMessage(String message) {
this.message = message;
}
}
将上面的代码编译为生成的TestBean.class文件,并确保在C:\apache-tomcat-7.0.2\webapps\WEB-INF\classes\action文件夹中复制了TestBean.class,并且CLASSPATH变量也应该是设置为此文件夹 -
现在在main.jsp文件中使用以下代码。 这会加载bean并设置/获取一个简单的String参数 -
<html>
<head>
<title>Using JavaBeans in JSP</title>
</head>
<body>
<center>
<h2>Using JavaBeans in JSP</h2>
<jsp:useBean id = "test" class = "action.TestBean" />
<jsp:setProperty name = "test" property = "message"
value = "Hello JSP..." />
<p>Got message....</p>
<jsp:getProperty name = "test" property = "message" />
</center>
</body>
</html>
现在让我们尝试访问main.jsp ,它会显示以下结果 -
<center>
<h2>Using JavaBeans in JSP</h2>
Got message....
Hello JSP...
</center>
动作
forward操作终止当前页面的操作,并将请求转发到另一个资源,例如静态页面,另一个JSP页面或Java Servlet。
以下是forward动作的语法 -
<jsp:forward page = "Relative URL" />
下表列出了与前进行动相关的必要属性 -
S.No. | 属性和描述 |
---|---|
1 | page 应包含另一个资源的相对URL,例如静态页面,另一个JSP页面或Java Servlet。 |
例子 (Example)
让我们重用以下两个文件(a) date.jsp和(b) main.jsp如下 -
以下是date.jsp文件的内容 -
<p>Today's date: <%= (new java.util.Date()).toLocaleString()%></p>
以下是main.jsp文件的内容 -
<html>
<head>
<title>The include Action Example</title>
</head>
<body>
<center>
<h2>The include action Example</h2>
<jsp:forward page = "date.jsp" />
</center>
</body>
</html>
现在让我们将所有这些文件保存在根目录中,并尝试访问main.jsp 。 这将显示如下结果。
这里它从主页面中丢弃了内容,仅显示转发页面中的内容。
<center>
Today's date: 12-Sep-2010 14:54:22
</center>
动作
plugin操作用于将Java组件插入JSP页面。 它确定浏览器的类型,并根据需要插入《object》或《embed》标签。
如果不存在所需的插件,则下载插件然后执行Java组件。 Java组件可以是Applet或JavaBean。
插件操作有几个属性,对应于用于格式化Java组件的常用HTML标记。 《param》元素也可用于将参数发送到Applet或Bean。
以下是使用插件操作的典型语法 -
<jsp:plugin type = "applet" codebase = "dirname" code = "MyApplet.class"
width = "60" height = "80">
<jsp:param name = "fontcolor" value = "red" />
<jsp:param name = "background" value = "black" />
<jsp:fallback>
Unable to initialize Java Plugin
</jsp:fallback>
</jsp:plugin>
如果您有兴趣,可以使用一些小程序尝试此操作。 新元素《fallback》元素可用于指定在组件发生故障时要发送给用户的错误字符串。
<h2>The <jsp:element> Action</h2>
<h2>The <jsp:attribute> Action</h2>
<h2>The <jsp:body> Action</h2>
《jsp:element》, 《jsp:attribute》和《jsp:body》动作用于动态定义XML元素。 动态这个词非常重要,因为它意味着XML元素可以在请求时生成,而不是在编译时静态生成。
以下是动态定义XML元素的简单示例 -
<%@page language = "java" contentType = "text/html"%>
<html xmlns = "http://www.w3c.org/1999/xhtml"
xmlns:jsp = "http://java.sun.com/JSP/Page">
<head><title>Generate XML Element</title></head>
<body>
<jsp:element name = "xmlElement">
<jsp:attribute name = "xmlElementAttr">
Value for the attribute
</jsp:attribute>
<jsp:body>
Body for XML element
</jsp:body>
</jsp:element>
</body>
</html>
这将在运行时生成以下HTML代码 -
<html xmlns = "http://www.w3c.org/1999/xhtml" xmlns:jsp = "http://java.sun.com/JSP/Page">
<head><title>Generate XML Element</title></head>
<body>
<xmlElement xmlElementAttr = "Value for the attribute">
Body for XML element
</xmlElement>
</body>
</html>
动作
《jsp:text》操作可用于在JSP页面和文档中编写模板文本。 以下是此操作的简单语法 -
<jsp:text>Template data</jsp:text>
模板的主体不能包含其他元素; 它只能包含文本和EL表达式(注意 - EL表达式将在后续章节中介绍)。 请注意,在XML文件中,您不能使用${whatever 》 0}等表达式,因为大于号是非法的。 相反,使用gt表单,例如${whatever gt 0}或者替代方法是将值嵌入CDATA部分。
<jsp:text><![CDATA[<br>]]></jsp:text>
如果您需要包含DOCTYPE声明(例如XHTML ,则还必须使用《jsp:text》元素,如下所示 -
<jsp:text><![CDATA[<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
"DTD/xhtml1-strict.dtd">]]></jsp:text>
<head><title>jsp:text action</title></head>
<body>
<books><book><jsp:text>
Welcome to JSP Programming
</jsp:text></book></books>
</body>
</html>
使用和不使用《jsp:text》操作尝试上面的示例。
JSP - Implicit Objects
在本章中,我们将讨论JSP中的隐式对象。 这些对象是JSP容器为每个页面中的开发人员提供的Java对象,开发人员可以直接调用它们而无需显式声明。 JSP隐式对象也称为pre-defined variables 。
下表列出了JSP支持的九个隐式对象 -
S.No. | 对象和描述 |
---|---|
1 | request 这是与请求关联的HttpServletRequest对象。 |
2 | response 这是与客户端响应关联的HttpServletResponse对象。 |
3 | out 这是用于将输出发送到客户端的PrintWriter对象。 |
4 | session 这是与请求关联的HttpSession对象。 |
5 | application 这是与应用程序上下文关联的ServletContext对象。 |
6 | config 这是与页面关联的ServletConfig对象。 |
7 | pageContext 这封装了特定于服务器的功能,如性能更高的JspWriters 。 |
8 | page 这只是它的同义词,用于调用已转换的servlet类定义的方法。 |
9 | Exception Exception对象允许指定的JSP访问异常数据。 |
请求对象
请求对象是javax.servlet.http.HttpServletRequest对象的实例。 每次客户端请求页面时,JSP引擎都会创建一个新对象来表示该请求。
请求对象提供了获取HTTP头信息的方法,包括表单数据,cookie,HTTP方法等。
我们可以在后续章节中介绍与请求对象关联的一整套方法 - JSP - 客户端请求 。
响应对象
响应对象是javax.servlet.http.HttpServletResponse对象的一个实例。 就像服务器创建请求对象一样,它也会创建一个对象来表示对客户端的响应。
响应对象还定义了处理创建新HTTP标头的接口。 通过这个对象,JSP程序员可以添加新的cookie或日期戳,HTTP状态代码等。
我们将在后续章节中介绍与响应对象关联的一整套方法 - JSP - 服务器响应 。
out对象
out隐式对象是javax.servlet.jsp.JspWriter对象的一个实例,用于在响应中发送内容。
初始JspWriter对象的实例化取决于页面是否缓冲。 通过使用page指令的buffered = 'false'属性,可以轻松关闭buffered = 'false' 。
JspWriter对象包含与java.io.PrintWriter类相同的大多数方法。 但是,JspWriter还有一些其他方法可用于处理缓冲。 与PrintWriter对象不同,JspWriter会抛出IOExceptions 。
下表列出了我们将用于编写boolean char, int, double, object, String等的重要方法。
S.No. | 方法和描述 |
---|---|
1 | out.print(dataType dt) 打印数据类型值 |
2 | out.println(dataType dt) 打印数据类型值,然后使用换行符终止该行。 |
3 | out.flush() 冲洗流。 |
会话对象
session对象是javax.servlet.http.HttpSession一个实例,其行为与Java Servlets下会话对象的行为完全相同。
会话对象用于跟踪客户端请求之间的客户端会话。 我们将在后续章节中介绍会话对象的完整用法 - JSP - 会话跟踪 。
应用程序对象
应用程序对象是生成的Servlet的ServletContext对象的直接包装器,实际上是javax.servlet.ServletContext对象的实例。
该对象是JSP页面整个生命周期的表示。 初始化JSP页面时会创建此对象,并且在jspDestroy()方法删除JSP页面时将删除该对象。
通过向应用程序添加属性,可以确保构成Web应用程序的所有JSP文件都可以访问它。
我们将在JSP - Hits Counter章节中检查Application Object的使用。
配置对象
config对象是javax.servlet.ServletConfig的实例化,是生成的servlet的ServletConfig对象的直接包装器。
该对象允许JSP程序员访问Servlet或JSP引擎初始化参数,例如路径或文件位置等。
以下config方法是您可能使用的唯一方法,其用法很简单 -
config.getServletName();
这将返回servlet名称,该《servlet-name》是WEB-INF\web.xml文件中定义的《servlet-name》元素中包含的字符串。
pageContext对象
pageContext对象是javax.servlet.jsp.PageContext对象的一个实例。 pageContext对象用于表示整个JSP页面。
此对象旨在作为访问有关页面信息的方法,同时避免大多数实现细节。
此对象存储对每个请求的请求和响应对象的引用。 application, config, session和输出对象是通过访问此对象的属性派生的。
pageContext对象还包含有关发布到JSP页面的指令的信息,包括缓冲信息,errorPageURL和页面范围。
PageContext类定义了几个字段,包括PAGE_SCOPE, REQUEST_SCOPE, SESSION_SCOPE,和APPLICATION_SCOPE ,它们标识了四个范围。 它还支持40多种方法,其中大约一半是从javax.servlet.jsp.JspContext class继承的。
其中一个重要的方法是removeAttribute 。 此方法接受一个或两个参数。 例如, pageContext.removeAttribute ("attrName")从所有范围中删除该属性,而以下代码仅从页面范围中删除它 -
pageContext.removeAttribute("attrName", PAGE_SCOPE);
可以在JSP - File Uploading章节中检查pageContext的使用。
页面对象
此对象是对页面实例的实际引用。 它可以被认为是表示整个JSP页面的对象。
页面对象实际上是this对象的直接同义词。
异常对象
异常对象是一个包装器,包含从上一页抛出的异常。 它通常用于生成对错误条件的适当响应。
我们将在JSP - 异常处理章节中介绍该对象的完整用法。
JSP - Client Request
在本章中,我们将讨论JSP中的客户端请求。 当浏览器请求网页时,它会向Web服务器发送大量信息。 无法直接读取此信息,因为此信息作为HTTP请求标头的一部分传播。 您可以检查HTTP协议以获取更多信息。
下表列出了来自浏览器的重要标题信息。 此信息经常用于Web编程 -
S.No. | 标题和说明 |
---|---|
1 | Accept 此标头指定浏览器或其他客户端可以处理的MIME类型。 image/png或image/jpeg是两种最常见的可能性。 |
2 | Accept-Charset 此标头指定浏览器可用于显示信息的字符集。 例如, ISO-8859-1 。 |
3 | Accept-Encoding 此标头指定浏览器知道如何处理的编码类型。 gzip或compress值是两种最常见的可能性。 |
4 | Accept-Language 此标头指定客户端的首选语言,以防servlet以多种语言生成结果。 例如en, en-us, ru等。 |
5 | Authorization 客户端使用此标头在访问受密码保护的网页时标识自己。 |
6 | Connection 此标头指示客户端是否可以处理持久HTTP连接。 持久连接允许客户端或其他浏览器使用单个请求检索多个文件。 Keep-Alive值意味着应该使用持久连接。 |
7 | Content-Length 此标头仅适用于POST请求,并以字节为单位给出POST数据的大小。 |
8 | Cookie 此标头将cookie返回给先前已将其发送到浏览器的服务器。 |
9 | Host 此标头指定原始URL中给出的主机和端口。 |
10 | If-Modified-Since 此标头指示客户端仅在指定日期之后更改页面时才需要该页面。 如果没有可用的更新结果,服务器发送代码304,这意味着Not Modified标头。 |
11 | If-Unmodified-Since 此标头与If-Modified-Since相反; 它指定仅当文档早于指定日期时操作才会成功。 |
12 | Referer 此标头指示引用网页的URL。 例如,如果您在网页1并单击指向网页2的链接,则当浏览器请求网页2时,网页1的URL将包含在Referer标头中。 |
13 | User-Agent 此标头标识发出请求的浏览器或其他客户端,可用于将不同内容返回到不同类型的浏览器。 |
HttpServletRequest对象
请求对象是javax.servlet.http.HttpServletRequest对象的实例。 每次客户端请求页面时,JSP引擎都会创建一个新对象来表示该请求。
请求对象提供了获取HTTP头信息的form data, cookies, HTTP methods ,包括form data, cookies, HTTP methods等。
下表列出了可用于在JSP程序中读取HTTP头的重要方法。 这些方法可用于HttpServletRequest对象,该对象表示对Web服务器的客户端请求。
S.No. | 方法和描述 |
---|---|
1 | Cookie[] getCookies() 返回一个数组,其中包含客户端使用此请求发送的所有Cookie对象。 |
2 | Enumeration getAttributeNames() 返回包含此请求可用属性名称的Enumeration。 |
3 | Enumeration getHeaderNames() 返回此请求包含的所有标头名称的枚举。 |
4 | Enumeration getParameterNames() 返回String对象的枚举,其中包含此请求中包含的参数的名称。 |
5 | HttpSession getSession() 返回与此请求关联的当前会话,或者如果请求没有会话,则创建一个会话。 |
6 | HttpSession getSession(boolean create) 返回与此请求关联的当前HttpSession,如果没有当前会话且create为true,则返回新会话。 |
7 | Locale getLocale() 根据Accept-Language标头返回客户端将接受内容的首选区域设置。 |
8 | Object getAttribute(String name) 以Object形式返回指定属性的值,如果不存在给定名称的属性,则返回null。 |
9 | ServletInputStream getInputStream() 使用ServletInputStream以二进制数据的形式检索请求的主体。 |
10 | String getAuthType() 返回用于保护servlet的身份验证方案的名称,例如“BASIC”或“SSL”,如果JSP未受保护,则返回null。 |
11 | String getCharacterEncoding() 返回此请求正文中使用的字符编码的名称。 |
12 | String getContentType() 返回请求正文的MIME类型,如果类型未知,则返回null。 |
13 | String getContextPath() 返回请求URI的一部分,指示请求的上下文。 |
14 | String getHeader(String name) 以String形式返回指定请求标头的值。 |
15 | String getMethod() 返回用于发出此请求的HTTP方法的名称,例如,GET,POST或PUT。 |
16 | String getParameter(String name) 以String形式返回请求参数的值,如果参数不存在,则返回null。 |
17 | String getPathInfo() 返回与客户端发出此请求时发送的URL关联的任何额外路径信息。 |
18 | String getProtocol() 返回请求使用的协议的名称和版本。 |
19 | String getQueryString() 返回路径后请求URL中包含的查询字符串。 |
20 | String getRemoteAddr() 返回发送请求的客户端的Internet协议(IP)地址。 |
21 | String getRemoteHost() 返回发送请求的客户端的完全限定名称。 |
22 | String getRemoteUser() 如果用户已通过身份验证,则返回发出此请求的用户的登录名;如果用户尚未通过身份验证,则返回null。 |
23 | String getRequestURI() 将此请求的URL部分从协议名称返回到HTTP请求第一行中的查询字符串。 |
24 | String getRequestedSessionId() 返回客户端指定的会话ID。 |
25 | String getServletPath() 返回此请求调用JSP的URL的一部分。 |
26 | String[] getParameterValues(String name) 返回包含给定请求参数所具有的所有值的String对象数组,如果参数不存在,则返回null。 |
27 | boolean isSecure() 返回一个布尔值,指示此请求是否是使用安全通道(如HTTPS)进行的。 |
28 | int getContentLength() 返回请求正文的长度(以字节为单位),并由输入流提供,如果长度未知,则返回-1。 |
29 | int getIntHeader(String name) 以int形式返回指定请求标头的值。 |
30 | int getServerPort() 返回接收此请求的端口号。 |
HTTP标头请求示例
以下是使用HttpServletRequest getHeaderNames()方法读取HTTP头信息的示例。 此方法返回一个Enumeration,其中包含与当前HTTP请求关联的标头信息。
一旦我们有了Enumeration,我们就可以以标准方式循环Enumeration。 我们将使用hasMoreElements()方法来确定何时停止,并使用nextElement()方法来获取每个参数名称的名称。
<%@ page import = "java.io.*,java.util.*" %>
<html>
<head>
<title>HTTP Header Request Example</title>
</head>
<body>
<center>
<h2>HTTP Header Request Example</h2>
<table width = "100%" border = "1" align = "center">
<tr bgcolor = "#949494">
<th>Header Name</th>
<th>Header Value(s)</th>
</tr>
<%
Enumeration headerNames = request.getHeaderNames();
while(headerNames.hasMoreElements()) {
String paramName = (String)headerNames.nextElement();
out.print("<tr><td>" + paramName + "</td>\n");
String paramValue = request.getHeader(paramName);
out.println("<td> " + paramValue + "</td></tr>\n");
}
%>
</table>
</center>
</body>
</html>
现在让我们将上面的代码放在main.jsp并尝试访问它。
HTTP标头请求示例
标题名称 | 标题值 |
---|---|
accept | */* |
accept-language | en-us |
user-agent | Mozilla/4.0(兼容; MSIE 7.0; Windows NT 5.1; Trident/4.0; InfoPath.2; MS-RTC LM 8) |
accept-encoding | gzip, deflate |
host | localhost:8080 |
connection | Keep-Alive |
cache-control | no-cache |
您可以尝试以类似的方式处理所有方法。
JSP - Server Response
在本章中,我们将讨论JSP中的服务器响应。 当Web服务器响应HTTP请求时,响应通常由状态行,一些响应头,空行和文档组成。 典型的回答看起来像这样 -
HTTP/1.1 200 OK
Content-Type: text/html
Header2: ...
...
HeaderN: ...
(Blank Line)
<!doctype ...>
<html>
<head>...</head>
<body>
...
</body>
</html>
状态行包括HTTP版本(HTTP/1.1 in the example) ,状态代码(200 in the example) ,以及与状态代码对应的非常短的消息(OK in the example) 。
以下是从Web服务器返回浏览器的最有用的HTTP 1.1响应标头的摘要。 这些标题经常用于Web编程 -
S.No. | 标题和说明 |
---|---|
1 | Allow 此标头指定服务器支持的请求方法( GET, POST等)。 |
2 | Cache-Control 此标头指定可以安全地缓存响应文档的环境。 它可以具有public, private或no-cache等值。公共意味着文档是可缓存的,私有意味着文档是针对单个用户的,并且只能存储在私有(非共享)缓存中,而无缓存意味着永远不应缓存文档。 |
3 | Connection 此标头指示浏览器是否使用持久HTTP连接。 值close指示浏览器不使用持久HTTP连接, keep-alive意味着使用持久连接。 |
4 | Content-Disposition 此标头允许您请求浏览器要求用户将响应保存到给定名称的文件中。 |
5 | Content-Encoding 此标头指定在传输过程中页面的编码方式。 |
6 | Content-Language 此标头表示文档的编写语言。 例如, en, en-us, ru,等。 |
7 | Content-Length 此标头指示响应中的字节数。 仅当浏览器使用持久(保持活动)HTTP连接时才需要此信息。 |
8 | Content-Type 此标头提供响应文档的MIME ( Multipurpose Internet Mail Extension )类型。 |
9 | Expires 此标头指定内容应被视为过期的时间,因此不再被缓存。 |
10 | Last-Modified 此标头指示文档上次更改的时间。 然后,客户端可以缓存文档,并在以后的请求中通过If-Modified-Since请求标头提供日期。 |
11 | Location 此标头应包含在状态代码为300s的所有响应中。 这会通知浏览器文档地址。 浏览器会自动重新连接到此位置并检索新文档。 |
12 | Refresh 此标头指定浏览器应该多久要求更新的页面。 您可以指定刷新页面的时间(以秒为单位)。 |
13 | Retry-After 此标头可与503 (Service Unavailable)响应结合使用,以告知客户端可以多快重复其请求。 |
14 | Set-Cookie 此标头指定与页面关联的cookie。 |
HttpServletResponse对象
响应对象是javax.servlet.http.HttpServletResponse object一个实例。 就像服务器创建请求对象一样,它也会创建一个对象来表示对客户端的响应。
响应对象还定义了处理创建新HTTP标头的接口。 通过这个对象,JSP程序员可以添加新的cookie或日期戳,HTTP状态代码等。
可以使用以下方法在servlet程序中设置HTTP响应头。 这些方法可用于HttpServletResponse对象。 此对象表示服务器响应。
S.No. | 方法和描述 |
---|---|
1 | String encodeRedirectURL(String url) 对指定的URL进行编码以在sendRedirect方法中使用,或者,如果不需要编码,则返回URL不变。 |
2 | String encodeURL(String url) 通过在其中包含会话ID来对指定的URL进行编码,或者,如果不需要编码,则返回不变的URL。 |
3 | boolean containsHeader(String name) 返回一个布尔值,指示是否已设置指定的响应头。 |
4 | boolean isCommitted() 返回一个布尔值,指示响应是否已提交。 |
5 | void addCookie(Cookie cookie) 将指定的cookie添加到响应中。 |
6 | void addDateHeader(String name, long date) 添加具有给定名称和日期值的响应标头。 |
7 | void addHeader(String name, String value) 添加具有给定名称和值的响应标头。 |
8 | void addIntHeader(String name, int value) 添加具有给定名称和整数值的响应标头。 |
9 | void flushBuffer() 强制将缓冲区中的任何内容写入客户端。 |
10 | void reset() 清除缓冲区中存在的所有数据以及状态代码和标头。 |
11 | void resetBuffer() 清除响应中底层缓冲区的内容,而不清除标头或状态代码。 |
12 | void sendError(int sc) 使用指定的状态代码向客户端发送错误响应并清除缓冲区。 |
13 | void sendError(int sc, String msg) 使用指定的状态向客户端发送错误响应。 |
14 | void sendRedirect(String location) 使用指定的重定向位置URL向客户端发送临时重定向响应。 |
15 | void setBufferSize(int size) 设置响应正文的首选缓冲区大小。 |
16 | void setCharacterEncoding(String charset) 设置发送到客户端的响应的字符编码(MIME字符集),例如,设置为UTF-8。 |
17 | void setContentLength(int len) 设置响应中内容主体的长度在HTTP servlet中; 此方法还设置HTTP Content-Length标头。 |
18 | void setContentType(String type) 如果尚未提交响应,则设置发送到客户端的响应的内容类型。 |
19 | void setDateHeader(String name, long date) 设置具有给定名称和日期值的响应标头。 |
20 | void setHeader(String name, String value) 设置具有给定名称和值的响应标头。 |
21 | void setIntHeader(String name, int value) 设置具有给定名称和整数值的响应标头。 |
22 | void setLocale(Locale loc) 如果尚未提交响应,则设置响应的区域设置。 |
23 | void setStatus(int sc) 设置此响应的状态代码。 |
HTTP标头响应示例
以下示例将使用setIntHeader()方法设置Refresh标头以模拟数字时钟 -
<%@ page import = "java.io.*,java.util.*" %>
<html>
<head>
<title>Auto Refresh Header Example</title>
</head>
<body>
<center>
<h2>Auto Refresh Header Example</h2>
<%
// Set refresh, autoload time as 5 seconds
response.setIntHeader("Refresh", 5);
// Get current time
Calendar calendar = new GregorianCalendar();
String am_pm;
int hour = calendar.get(Calendar.HOUR);
int minute = calendar.get(Calendar.MINUTE);
int second = calendar.get(Calendar.SECOND);
if(calendar.get(Calendar.AM_PM) == 0)
am_pm = "AM";
else
am_pm = "PM";
String CT = hour+":"+ minute +":"+ second +" "+ am_pm;
out.println("Current Time is: " + CT + "\n");
%>
</center>
</body>
</html>
现在将上面的代码放在main.jsp并尝试访问它。 这将显示每5秒后的当前系统时间,如下所示。 运行JSP。 您将收到以下输出: -
<center>
<h2 align="center">Auto Refresh Header Example</h2>
Current Time is: 9:44:50 PM
</center>
您可以尝试以类似的方式研究其他方法。
JSP - Http Status Codes
在本章中,我们将讨论JSP中的Http状态代码。 HTTP请求的格式和HTTP响应消息类似,并具有以下结构 -
初始状态行+ CRLF(回车符+换行符即新行)
零个或多个标题行+ CRLF
一条空行即。 一个CRLF
可选的消息体,如文件,查询数据或查询输出。
例如,服务器响应头如下所示 -
HTTP/1.1 200 OK
Content-Type: text/html
Header2: ...
...
HeaderN: ...
(Blank Line)
<!doctype ...>
<html>
<head>...</head>
<body>
...
</body>
</html>
状态行包括HTTP version (HTTP/1.1 in the example) ,状态代码(示例中为200),以及与状态代码对应的非常短的消息(OK in the example) 。
下表列出了可能从Web服务器返回的HTTP状态代码和相关消息 -
码 | 信息 | 描述 |
---|---|---|
100 | Continue | 服务器只收到请求的一部分,但只要它没有被拒绝,客户端就应该继续请求 |
101 | 切换协议 | 服务器切换协议。 |
200 | OK | 请求没问题 |
201 | Created | 请求已完成,并且已创建新资源 |
202 | Accepted | 请求被接受处理,但处理不完整。 |
203 | 非权威信息 | |
204 | 无内容 | |
205 | 重置内容 | |
206 | 部分内容 | |
300 | 多种选择 | 链接列表; 用户可以选择一个链接并转到该位置。 最多五个地址。 |
301 | 永久移动 | 请求的页面已移至新网址。 |
302 | Found | 请求的页面暂时移动到新的URL。 |
303 | 见其他 | 请求的页面可以在不同的URL下找到。 |
304 | 没有修改 | |
305 | 使用代理服务器 | |
306 | Unused | 此代码用于以前的版本。 它已不再使用,但代码保留。 |
307 | 临时重定向 | 请求的页面暂时移动到新的URL。 |
400 | 错误的请求 | 服务器不理解请求。 |
401 | Unauthorized | 请求的页面需要用户名和密码。 |
402 | 需要付款 | You can not use this code yet. |
403 | Forbidden | 禁止访问所请求的页面 |
404 | 未找到 | 服务器找不到请求的页面。 |
405 | 方法不允许 | 不允许在请求中指定的方法。 |
406 | 不能接受的 | 服务器只能生成客户端不接受的响应。 |
407 | 需要代理验证 | 在提供此请求之前,您必须使用代理服务器进行身份验证。 |
408 | 请求超时 | 请求花费的时间比服务器准备等待的时间长。 |
409 | Conflict | 由于冲突,请求无法完成。 |
410 | Gone | 请求的页面不再可用。 |
411 | 长度要求 | “内容长度”未定义。 没有它,服务器将不接受请求。 |
412 | 前提条件失败 | 请求中给出的前提条件由服务器评估为false。 |
413 | 请求的实体太大 | 服务器不接受请求,因为请求实体太大。 |
414 | 请求网址太长 | 服务器不接受请求,因为网址太长。 当您使用长查询信息将“发布”请求转换为“获取”请求时,会发生这种情况。 |
415 | 不支持的媒体类型 | 服务器不接受请求,因为不支持媒体类型。 |
417 | 期望失败 | |
500 | 内部服务器错误 | 请求未完成。 服务器遇到意外情况。 |
501 | 未实现 | 请求未完成。 服务器不支持所需的功能。 |
502 | 错误的网关 | 请求未完成。 服务器从上游服务器收到无效响应。 |
503 | 暂停服务 | 请求未完成。 服务器暂时超载或关闭。 |
504 | 网关超时 | 网关已超时。 |
505 | 不支持HTTP版本 | 服务器不支持"http protocol"版本。 |
设置HTTP状态代码的方法
以下方法可用于在servlet程序中设置HTTP状态代码。 这些方法可用于HttpServletResponse对象。
S.No. | 方法和描述 |
---|---|
1 | public void setStatus ( int statusCode ) 此方法设置任意状态代码。 setStatus方法将int(状态代码)作为参数。 如果您的响应包含特殊状态代码和文档,请setStatus在使用PrintWriter实际返回任何内容之前调用setStatus 。 |
2 | public void sendRedirect(String url) 此方法生成302响应以及提供新文档的URL的Location标头。 |
3 | public void sendError(int code, String message) 此方法发送状态代码(通常为404)以及在HTML文档内自动格式化并发送到客户端的短消息。 |
HTTP状态代码示例
以下示例显示如何将407错误代码发送到客户端浏览器。 在此之后,浏览器会显示“ Need authentication!!! ”消息。
<html>
<head>
<title>Setting HTTP Status Code</title>
</head>
<body>
<%
// Set error code and reason.
response.sendError(407, "Need authentication!!!" );
%>
</body>
</html>
您将收到以下输出 -
<h1 style="font-family:Tahoma,Arial,sans-serif;color:white;background-color:#525D76;">HTTP Status 407 - Need authentication!!!</h1>
<p><b style="font-family:Tahoma,Arial,sans-serif;color:white;background-color:#525D76;" class="notranslate">type</b> Status report</p>
<p><b style="font-family:Tahoma,Arial,sans-serif;color:white;background-color:#525D76;" class="notranslate">message</b> <u>Need authentication!!!</u></p>
<p><b style="font-family:Tahoma,Arial,sans-serif;color:white;background-color:#525D76;" class="notranslate">description</b> <u>The client must first authenticate itself with the proxy (Need authentication!!!).</u></p>
<h3 style="font-family:Tahoma,Arial,sans-serif;color:white;background-color:#525D76;">Apache Tomcat/5.5.29</h3>
要更加熟悉HTTP状态代码,请尝试设置不同的状态代码及其说明。
JSP - Form Processing
在本章中,我们将讨论JSP中的表单处理。 当您需要将某些信息从浏览器传递到Web服务器并最终传递到后端程序时,您必须遇到很多情况。 浏览器使用两种方法将此信息传递给Web服务器。 这些方法是GET方法和POST方法。
表格处理中的方法
现在让我们讨论表单处理中的方法。
GET方法
GET方法发送附加到页面请求的编码用户信息。 页面和编码信息由?分隔。 性格如下 -
http://www.test.com/hello?key1=value1&key2=value2
GET方法是将信息从浏览器传递到Web服务器的默认方法,它会生成一个长字符串,显示在浏览器的Location:box 。 建议最好不要使用GET方法。 如果您有密码或其他敏感信息传递给服务器。
GET方法有大小限制: only 1024 characters can be in a request string 。
此信息使用QUERY_STRING header传递,并且可以通过QUERY_STRING环境变量访问,该变量可以使用请求对象的getQueryString()和getParameter()方法进行处理。
POST方法
将信息传递给后端程序的一般更可靠的方法是POST方法。
此方法以与GET方法完全相同的方式打包信息,但不是在文本字符串之后将其作为文本字符串发送? 在URL中,它将其作为单独的消息发送。 此消息以标准输入的形式提供给后端程序,您可以解析并用于处理。
JSP使用getParameter()方法处理此类请求以读取简单参数,并使用getInputStream()方法读取来自客户端的二进制数据流。
使用JSP读取表单数据
JSP根据情况使用以下方法自动处理表单数据解析 -
getParameter() - 您调用request.getParameter()方法来获取表单参数的值。
getParameterValues() - 如果参数出现多次并返回多个值(例如复选框getParameterValues() ,则调用此方法。
getParameterNames() - 如果需要当前请求中所有参数的完整列表,请调用此方法。
getInputStream() - 调用此方法读取来自客户端的二进制数据流。
使用URL获取GET方法示例
以下URL将使用GET方法将两个值传递给HelloForm程序。
http://localhost:8080/main.jsp?first_name=ZARA&last_name=ALI
下面是main.jsp JSP程序,用于处理Web浏览器提供的输入。 我们将使用getParameter()方法,这使得访问传递的信息变得非常容易 -
<html>
<head>
<title>Using GET Method to Read Form Data</title>
</head>
<body>
<h1>Using GET Method to Read Form Data</h1>
<ul>
<li><p><b>First Name:</b>
<%= request.getParameter("first_name")%>
</p></li>
<li><p><b>Last Name:</b>
<%= request.getParameter("last_name")%>
</p></li>
</ul>
</body>
</html>
现在在浏览器的Location:box键入http://localhost:8080/main.jsp?first_name=ZARA&last_name=ALI 。 这将产生以下结果 -
Using GET Method to Read Form Data
|
使用表格获取方法示例
以下是使用HTML FORM和提交按钮传递两个值的示例。 我们将使用相同的JSP main.jsp来处理此输入。
<html>
<body>
<form action = "main.jsp" method = "GET">
First Name: <input type = "text" name = "first_name">
<br />
Last Name: <input type = "text" name = "last_name" />
<input type = "submit" value = "Submit" />
</form>
</body>
</html>
将此HTML保存在文件Hello.htm中,并将其放在《Tomcat-installation-directory》/webapps/ROOT directory 。 当您访问http://localhost:8080/Hello.htm ,您将收到以下输出。
尝试输入名字和姓氏,然后单击“提交”按钮以在运行tomcat的本地计算机上查看结果。
根据提供的输入,它将生成与上例中提到的类似的结果。使用表单的POST方法示例
让我们在上面的JSP中做一点修改来处理GET和POST方法。 下面是main.jsp JSP程序,用于处理Web浏览器使用GET或POST方法给出的输入。
事实上,上述JSP没有变化,因为传递参数的唯一方法是更改,并且没有二进制数据传递给JSP程序。 文件处理相关概念将在我们需要读取二进制数据流的单独章节中解释。
<html>
<head>
<title>Using GET and POST Method to Read Form Data</title>
</head>
<body>
<center>
<h1>Using POST Method to Read Form Data</h1>
<ul>
<li><p><b>First Name:</b>
<%= request.getParameter("first_name")%>
</p></li>
<li><p><b>Last Name:</b>
<%= request.getParameter("last_name")%>
</p></li>
</ul>
</body>
</html>
以下是Hello.htm文件的内容 -
<html>
<body>
<form action = "main.jsp" method = "POST">
First Name: <input type = "text" name = "first_name">
<br />
Last Name: <input type = "text" name = "last_name" />
<input type = "submit" value = "Submit" />
</form>
</body>
</html>
现在让我们将main.jsp和hello.htm保存在《Tomcat-installationdirectory》/webapps/ROOT directory 。 当您访问http://localhost:8080/Hello.htm ,您将收到以下输出。
尝试输入名字和姓氏,然后单击“提交”按钮以在运行tomcat的本地计算机上查看结果。
根据提供的输入,您将收到与上述示例类似的结果。
将Checkbox数据传递给JSP程序
如果需要选择多个选项,则使用复选框。
以下是一个示例HTML code, CheckBox.htm ,用于包含两个复选框的表单。
<html>
<body>
<form action = "main.jsp" method = "POST" target = "_blank">
<input type = "checkbox" name = "maths" checked = "checked" /> Maths
<input type = "checkbox" name = "physics" /> Physics
<input type = "checkbox" name = "chemistry" checked = "checked" /> Chemistry
<input type = "submit" value = "Select Subject" />
</form>
</body>
</html>
上面的代码将生成以下结果 -
以下是main.jsp JSP程序,用于处理Web浏览器为复选框按钮提供的输入。
<html>
<head>
<title>Reading Checkbox Data</title>
</head>
<body>
<h1>Reading Checkbox Data</h1>
<ul>
<li><p><b>Maths Flag:</b>
<%= request.getParameter("maths")%>
</p></li>
<li><p><b>Physics Flag:</b>
<%= request.getParameter("physics")%>
</p></li>
<li><p><b>Chemistry Flag:</b>
<%= request.getParameter("chemistry")%>
</p></li>
</ul>
</body>
</html>
上述程序将产生以下结果 -
<h1>Reading Checkbox Data</h1>
Maths Flag : ::开
Physics Flag: :: null
Chemistry Flag: :上
阅读所有表格参数
以下是一个通用示例,它使用HttpServletRequest的getParameterNames()方法来读取所有可用的表单参数。 此方法返回一个Enumeration,其中包含未指定顺序的参数名称。
一旦我们有了Enumeration,我们就可以用标准方式循环Enumeration,使用hasMoreElements()方法确定何时停止并使用nextElement()方法获取每个参数名称。
<%@ page import = "java.io.*,java.util.*" %>
<html>
<head>
<title>HTTP Header Request Example</title>
</head>
<body>
<center>
<h2>HTTP Header Request Example</h2>
<table width = "100%" border = "1" align = "center">
<tr bgcolor = "#949494">
<th>Param Name</th>
<th>Param Value(s)</th>
</tr>
<%
Enumeration paramNames = request.getParameterNames();
while(paramNames.hasMoreElements()) {
String paramName = (String)paramNames.nextElement();
out.print("<tr><td>" + paramName + "</td>\n");
String paramValue = request.getHeader(paramName);
out.println("<td> " + paramValue + "</td></tr>\n");
}
%>
</table>
</center>
</body>
</html>
以下是Hello.htm的内容 -
<html>
<body>
<form action = "main.jsp" method = "POST" target = "_blank">
<input type = "checkbox" name = "maths" checked = "checked" /> Maths
<input type = "checkbox" name = "physics" /> Physics
<input type = "checkbox" name = "chemistry" checked = "checked" /> Chem
<input type = "submit" value = "Select Subject" />
</form>
</body>
</html>
现在尝试使用上面的Hello.htm调用JSP; 这将根据提供的输入生成如下所示的结果 -
阅读所有表格参数
参数名称 | 参数价值 |
---|---|
maths | on |
chemistry | on |
您可以尝试使用上面的JSP来读取任何其他表单的数据,这些数据包含其他对象,如文本框,单选按钮或下拉列表等。
JSP - Filters
在本章中,我们将讨论JSP中的Filters。 Servlet和JSP过滤器是可用于Servlet和JSP编程的Java类,用于以下目的 -
在客户端访问后端资源之前拦截客户端的请求。
在将服务器发送回客户端之前操纵服务器的响应。
规格建议有各种类型的过滤器 -
- 验证过滤器
- 数据压缩过滤器
- 加密过滤器
- 触发资源访问事件的过滤器
- 图像转换滤镜
- 记录和审核过滤器
- MIME-TYPE链过滤器
- 标记过滤器
- 转换XML内容的XSL/T过滤器
过滤器部署在部署描述符文件web.xml ,然后映射到应用程序部署描述符中的servlet或JSP名称或URL模式。 部署描述符文件web.xml可以在《Tomcat-installation-directory》\conf目录中找到。
当JSP容器启动Web应用程序时,它会创建您在部署描述符中声明的每个过滤器的实例。 过滤器按照在部署描述符中声明的顺序执行。
Servlet过滤方法
过滤器只是一个实现javax.servlet.Filter接口的Java类。 javax.servlet.Filter接口定义了三个方法 -
S.No. | 方法和描述 |
---|---|
1 | public void doFilter (ServletRequest, ServletResponse, FilterChain) 每次由于客户端请求链末端的资源而请求/响应对通过链时,容器都会调用此方法。 |
2 | public void init(FilterConfig filterConfig) Web容器调用此方法以向过滤器指示它正在投入使用。 |
3 | public void destroy() Web容器调用此方法以向过滤器指示它正在停止服务。 |
JSP过滤器示例
以下示例显示了每次访问任何JSP文件时如何打印客户端的IP地址和当前日期时间。 此示例将为您提供对JSP过滤器的基本了解,但您可以使用相同的概念编写更复杂的过滤器应用程序 -
// Import required java libraries
import java.io.*;
import javax.servlet.*;
import javax.servlet.http.*;
import java.util.*;
// Implements Filter class
public class LogFilter implements Filter {
public void init(FilterConfig config) throws ServletException {
// Get init parameter
String testParam = config.getInitParameter("test-param");
//Print the init parameter
System.out.println("Test Param: " + testParam);
}
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain)
throws java.io.IOException, ServletException {
// Get the IP address of client machine.
String ipAddress = request.getRemoteAddr();
// Log the IP address and current timestamp.
System.out.println("IP "+ ipAddress + ", Time "+ new Date().toString());
// Pass request back down the filter chain
chain.doFilter(request,response);
}
public void destroy( ) {
/* Called before the Filter instance is removed
from service by the web container*/
}
}
以通常的方式编译LogFilter.java并将LogFilter.class文件放在《Tomcat-installation-directory》/webapps/ROOT/WEB-INF/classes 。
Web.xml中的JSP过滤器映射
定义过滤器,然后映射到URL或JSP文件名,其方式与定义Servlet的方式非常相似,然后映射到web.xml文件中的URL模式。 在部署描述符文件web.xml为filter标记创建以下条目
<filter>
<filter-name>LogFilter</filter-name>
<filter-class>LogFilter</filter-class>
<init-param>
<param-name>test-param</param-name>
<param-value>Initialization Paramter</param-value>
</init-param>
</filter>
<filter-mapping>
<filter-name>LogFilter</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
上面的过滤器将适用于所有servlet和JSP,因为我们在配置中指定了/* 。 如果要在少数servlet或JSP上应用过滤器,则可以指定特定的servlet或JSP路径。
现在尝试调用任何servlet或JSP,您将在Web服务器日志中看到生成的日志。 您可以使用Log4J logger将上面的日志记录在单独的文件中。
使用多个过滤器
您的Web应用程序可能会定义具有特定用途的多个不同过滤器 考虑一下,您定义了两个过滤器AuthenFilter和LogFilter 。 除了您需要创建如下所述的不同映射外,其余过程将保持如上所述 -
<filter>
<filter-name>LogFilter</filter-name>
<filter-class>LogFilter</filter-class>
<init-param>
<param-name>test-param</param-name>
<param-value>Initialization Paramter</param-value>
</init-param>
</filter>
<filter>
<filter-name>AuthenFilter</filter-name>
<filter-class>AuthenFilter</filter-class>
<init-param>
<param-name>test-param</param-name>
<param-value>Initialization Paramter</param-value>
</init-param>
</filter>
<filter-mapping>
<filter-name>LogFilter</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
<filter-mapping>
<filter-name>AuthenFilter</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
筛选应用程序订单
web.xml中filter-mapping元素的顺序决定了Web容器将过滤器应用于servlet或JSP的顺序。 要反转过滤器的顺序,您只需要反转web.xml文件中的过滤器映射元素。
例如,上面的示例将首先应用LogFilter然后将AuthenFilter应用于任何servlet或JSP; 以下示例将颠倒顺序 -
<filter-mapping>
<filter-name>AuthenFilter</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
<filter-mapping>
<filter-name>LogFilter</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
JSP - Cookies Handling
在本章中,我们将讨论JSP中的Cookies处理。 Cookie是存储在客户端计算机上的文本文件,用于各种信息跟踪目的。 JSP使用底层servlet技术透明地支持HTTP cookie。
识别和返回用户涉及三个步骤 -
服务器脚本将一组cookie发送到浏览器。 例如,姓名,年龄或身份证号码等。
浏览器将此信息存储在本地计算机上以备将来使用。
当下次浏览器向Web服务器发送任何请求时,它将这些cookie信息发送到服务器,并且服务器使用该信息来识别用户或者也可以用于其他目的。
本章将教您如何设置或重置cookie,如何访问它们以及如何使用JSP程序删除它们。
Cookie的剖析
Cookie通常设置在HTTP标头中(尽管JavaScript也可以直接在浏览器上设置cookie)。 设置cookie的JSP可能会发送看起来像这样的标题 -
HTTP/1.1 200 OK
Date: Fri, 04 Feb 2000 21:03:38 GMT
Server: Apache/1.3.9 (UNIX) PHP/4.0b3
Set-Cookie: name = xyz; expires = Friday, 04-Feb-07 22:03:38 GMT;
path = /; domain = iowiki.com
Connection: close
Content-Type: text/html
如您所见, Set-Cookie header包含a name value pair, a GMT date, a path和a domain 。 名称和值将进行URL编码。 expires字段是浏览器在给定时间和日期之后"forget" cookie的指令。
如果浏览器配置为存储cookie,则会将此信息保留到有效期。 如果用户将浏览器指向与cookie的路径和域匹配的任何页面,则会将cookie重新发送到服务器。 浏览器的标题可能看起来像这样 -
GET/HTTP/1.0
Connection: Keep-Alive
User-Agent: Mozilla/4.6 (X11; I; Linux 2.2.6-15apmac ppc)
Host: zink.demon.co.uk:1126
Accept: image/gif, */*
Accept-Encoding: gzip
Accept-Language: en
Accept-Charset: iso-8859-1,*,utf-8
Cookie: name = xyz
然后,JSP脚本将通过请求方法request.getCookies()访问cookie,该请求方法返回Cookie对象的数组。
Servlet Cookie方法
下表列出了与在Cookie中操作Cookie时可以使用的Cookie对象相关的有用方法 -
S.No. | 方法和描述 |
---|---|
1 | public void setDomain(String pattern) 此方法设置cookie适用的域; 例如,iowiki.com。 |
2 | public String getDomain() 此方法获取cookie适用的域; 例如,iowiki.com。 |
3 | public void setMaxAge(int expiry) 此方法设置cookie到期之前应经过多长时间(以秒为单位)。 如果您未设置此值,则cookie将仅持续当前会话。 |
4 | public int getMaxAge() 此方法返回cookie的最大年龄,以秒为单位指定。默认情况下, -1表示cookie将持续存在直到浏览器关闭。 |
5 | public String getName() 此方法返回cookie的名称。 创建后无法更改名称。 |
6 | public void setValue(String newValue) 此方法设置与cookie关联的值。 |
7 | public String getValue() 此方法获取与cookie关联的值。 |
8 | public void setPath(String uri) 此方法设置此cookie应用的路径。 如果未指定路径,则会为与当前页面相同的目录中的所有URL以及所有子目录返回cookie。 |
9 | public String getPath() 此方法获取此cookie应用的路径。 |
10 | public void setSecure(boolean flag) 此方法设置布尔值,指示是否应仅通过加密(即SSL)连接发送cookie。 |
11 | public void setComment(String purpose) 此方法指定描述cookie用途的注释。 如果浏览器将cookie提供给用户,则注释很有用。 |
12 | public String getComment() 此方法返回描述此cookie用途的注释,如果cookie没有注释,则返回null。 |
使用JSP设置Cookie
使用JSP设置cookie涉及三个步骤 -
第1步:创建Cookie对象
您使用cookie名称和cookie值调用Cookie构造函数,两者都是字符串。
Cookie cookie = new Cookie("key","value");
请记住,名称和值都不应包含空格或以下任何字符 -
[ ] ( ) = , "/? @ : ;
第2步:设置最大年龄
您可以使用setMaxAge指定cookie应该有效的时间长度(以秒为单位)。 以下代码将设置24小时的cookie。
cookie.setMaxAge(60*60*24);
第3步:将Cookie发送到HTTP响应标头中
您可以使用response.addCookie在HTTP响应标头中添加cookie,如下所示
response.addCookie(cookie);
例子 (Example)
让我们修改表单示例 ,为名字和姓氏设置cookie。
<%
// Create cookies for first and last names.
Cookie firstName = new Cookie("first_name", request.getParameter("first_name"));
Cookie lastName = new Cookie("last_name", request.getParameter("last_name"));
// Set expiry date after 24 Hrs for both the cookies.
firstName.setMaxAge(60*60*24);
lastName.setMaxAge(60*60*24);
// Add both the cookies in the response header.
response.addCookie( firstName );
response.addCookie( lastName );
%>
<html>
<head>
<title>Setting Cookies</title>
</head>
<body>
<center>
<h1>Setting Cookies</h1>
</center>
<ul>
<li><p><b>First Name:</b>
<%= request.getParameter("first_name")%>
</p></li>
<li><p><b>Last Name:</b>
<%= request.getParameter("last_name")%>
</p></li>
</ul>
</body>
</html>
让我们将上面的代码放在main.jsp文件中,并在以下HTML页面中使用它 -
<html>
<body>
<form action = "main.jsp" method = "GET">
First Name: <input type = "text" name = "first_name">
<br />
Last Name: <input type = "text" name = "last_name" />
<input type = "submit" value = "Submit" />
</form>
</body>
</html>
将上述HTML内容保存在文件hello.jsp ,并将hello.jsp和main.jsp放在《Tomcat-installation-directory》/webapps/ROOT目录中。 当您访问http://localhost:8080/hello.jsp ,以下是上述表单的实际输出。
尝试输入名字和姓氏,然后单击“提交”按钮。 这将在屏幕上显示名字和姓氏,并且还将设置两个cookie firstName和lastName 。 下次单击“提交”按钮时,这些cookie将被传递回服务器。
在下一节中,我们将解释如何在Web应用程序中访问这些cookie。
用JSP读取Cookies
要读取cookie,需要通过调用HttpServletRequest的getCookies( )方法来创建javax.servlet.http.Cookie对象的数组。 然后遍历数组,并使用getName()和getValue()方法访问每个cookie和相关值。
例子 (Example)
现在让我们读一下上一个例子中设置的cookie -
<html>
<head>
<title>Reading Cookies</title>
</head>
<body>
<center>
<h1>Reading Cookies</h1>
</center>
<%
Cookie cookie = null;
Cookie[] cookies = null;
// Get an array of Cookies associated with the this domain
cookies = request.getCookies();
if( cookies != null ) {
out.println("<h2> Found Cookies Name and Value</h2>");
for (int i = 0; i < cookies.length; i++) {
cookie = cookies[i];
out.print("Name : " + cookie.getName( ) + ", ");
out.print("Value: " + cookie.getValue( )+" <br/>");
}
} else {
out.println("<h2>No cookies founds</h2>");
}
%>
</body>
</html>
现在让我们将上面的代码放在main.jsp文件中并尝试访问它。 如果将first_name cookie设置为“John”并将last_name cookie为“Player”,则运行http://localhost:8080/main.jsp将显示以下结果 -
<h2> Found Cookies Name and Value</h2>
<p>Name : first_name, Value: John</p>
<p>Name : last_name, Value: Player</p>
使用JSP删除Cookies
删除cookie非常简单。 如果你想删除一个cookie,那么你只需要按照这三个步骤 -
读取已存在的cookie并将其存储在Cookie对象中。
使用setMaxAge()方法将cookie年龄设置为零以删除现有cookie。
将此cookie添加回响应标头。
例子 (Example)
下面的示例将向您展示如何删除名为"first_name"的现有cookie,并在下次运行main.jsp JSP时,它将为first_name返回null值。
<html>
<head>
<title>Reading Cookies</title>
</head>
<body>
<center>
<h1>Reading Cookies</h1>
</center>
<%
Cookie cookie = null;
Cookie[] cookies = null;
// Get an array of Cookies associated with the this domain
cookies = request.getCookies();
if( cookies != null ) {
out.println("<h2> Found Cookies Name and Value</h2>");
for (int i = 0; i < cookies.length; i++) {
cookie = cookies[i];
if((cookie.getName( )).compareTo("first_name") == 0 ) {
cookie.setMaxAge(0);
response.addCookie(cookie);
out.print("Deleted cookie: " +
cookie.getName( ) + "<br/>");
}
out.print("Name : " + cookie.getName( ) + ", ");
out.print("Value: " + cookie.getValue( )+" <br/>");
}
} else {
out.println(
"<h2>No cookies founds</h2>");
}
%>
</body>
</html>
现在让我们将上面的代码放在main.jsp文件中并尝试访问它。 它将显示以下结果 -
<h2>Cookies Name and Value</h2>
<p>Deleted cookie : first_name</p>
<p>Name : first_name, Value: John</p>
<p>Name : last_name, Value: Player</p>
现在再次运行http://localhost:8080/main.jsp ,它应该只显示一个cookie,如下所示 -
<h2> Found Cookies Name and Value</h2>
Name : last_name, Value: Player
您可以手动在Internet Explorer中删除Cookie。 从“工具”菜单开始,然后选择“Internet选项”。 要删除所有cookie,请单击“删除Cookies”按钮。
JSP - Session Tracking
在本章中,我们将讨论JSP中的会话跟踪。 HTTP是一种“无状态”协议,这意味着每次客户端检索网页时,客户端都会打开与Web服务器的单独连接,并且服务器自动不会保留以前客户端请求的任何记录。
维护Web客户端和服务器之间的会话
现在让我们讨论一些维护Web客户端和Web服务器之间会话的选项 -
Cookies
Web服务器可以将唯一的会话ID作为cookie分配给每个Web客户端,并且对于来自客户端的后续请求,可以使用收到的cookie来识别它们。
这可能不是一种有效的方式,因为浏览器有时不支持cookie。 建议不要使用此过程来维护会话。
隐藏的表单字段
Web服务器可以发送隐藏的HTML表单字段以及唯一的会话ID,如下所示 -
<input type = "hidden" name = "sessionid" value = "12345">
此条目表示在提交表单时,指定的名称和值将自动包含在GET或POST数据中。 每次Web浏览器发回请求时, session_id值都可用于保持不同Web浏览器的跟踪。
这可以是跟踪会话的有效方式,但单击常规()超文本链接不会导致表单提交,因此隐藏的表单字段也不能支持常规会话跟踪。
URL重写
您可以在每个URL的末尾附加一些额外的数据。 该数据标识会话; 服务器可以将该会话标识符与其存储的有关该会话的数据相关联。
例如,使用http://iowiki.com/file.htm;sessionid=12345 ,会话标识符作为sessionid = 12345附加,可以在Web服务器上访问以标识客户端。
URL重写是一种更好的方式来维护会话,并在浏览器不支持cookie时适用于浏览器。 这里的缺点是你必须动态生成每个URL以分配会话ID,尽管页面是一个简单的静态HTML页面。
会话对象
除了上面提到的选项之外,JSP还使用了servlet提供的HttpSession接口。 此界面提供了一种识别用户的方法。
- 一页请求或
- 访问网站或
- 存储有关该用户的信息
默认情况下,JSP启用会话跟踪,并自动为每个新客户端实例化一个新的HttpSession对象。 禁用会话跟踪需要通过将页面指令会话属性设置为false来显式关闭它,如下所示 -
<%@ page session = "false" %>
JSP引擎通过隐式session对象将HttpSession对象公开给JSP作者。 由于session对象已经提供给JSP程序员,程序员可以立即开始存储和检索来自对象的数据,而无需任何初始化或getSession() 。
以下是通过会话对象提供的重要方法的摘要 -
S.No. | 方法和描述 |
---|---|
1 | public Object getAttribute(String name) 此方法返回在此会话中使用指定名称绑定的对象,如果名称下没有绑定任何对象,则返回null。 |
2 | public Enumeration getAttributeNames() 此方法返回Enumeration of String对象,其中包含绑定到此会话的所有对象的名称。 |
3 | public long getCreationTime() 此方法返回创建此会话的时间,以格林威治标准时间1970年1月1日午夜以来的毫秒数为单位进行测量。 |
4 | public String getId() 此方法返回包含分配给此会话的唯一标识符的字符串。 |
5 | public long getLastAccessedTime() 此方法返回客户端上次发送与此会话关联的请求的最后一次,作为自格林威治标准时间1970年1月1日午夜起的毫秒数。 |
6 | public int getMaxInactiveInterval() 此方法返回servlet容器在客户端访问之间保持此会话打开的最长时间间隔(以秒为单位)。 |
7 | public void invalidate() 此方法使此会话无效并取消绑定绑定到它的任何对象。 |
8 | public boolean isNew() 如果客户端尚未了解会话或客户端选择不加入会话,则此方法返回true。 |
9 | public void removeAttribute(String name) 此方法从此会话中删除与指定名称绑定的对象。 |
10 | public void setAttribute(String name, Object value) 此方法使用指定的名称将对象绑定到此会话。 |
11 | public void setMaxInactiveInterval(int interval) 此方法指定servlet容器使此会话失效之前的客户端请求之间的时间(以秒为单位)。 |
会话跟踪示例
此示例描述如何使用HttpSession对象查找会话的创建时间和上次访问时间。 如果一个新会话尚不存在,我们会将该会话与该请求相关联。
<%@ page import = "java.io.*,java.util.*" %>
<%
// Get session creation time.
Date createTime = new Date(session.getCreationTime());
// Get last access time of this Webpage.
Date lastAccessTime = new Date(session.getLastAccessedTime());
String title = "Welcome Back to my website";
Integer visitCount = new Integer(0);
String visitCountKey = new String("visitCount");
String userIDKey = new String("userID");
String userID = new String("ABCD");
// Check if this is new comer on your Webpage.
if (session.isNew() ){
title = "Welcome to my website";
session.setAttribute(userIDKey, userID);
session.setAttribute(visitCountKey, visitCount);
}
visitCount = (Integer)session.getAttribute(visitCountKey);
visitCount = visitCount + 1;
userID = (String)session.getAttribute(userIDKey);
session.setAttribute(visitCountKey, visitCount);
%>
<html>
<head>
<title>Session Tracking</title>
</head>
<body>
<center>
<h1>Session Tracking</h1>
</center>
<table border = "1" align = "center">
<tr bgcolor = "#949494">
<th>Session info</th>
<th>Value</th>
</tr>
<tr>
<td>id</td>
<td><% out.print( session.getId()); %></td>
</tr>
<tr>
<td>Creation Time</td>
<td><% out.print(createTime); %></td>
</tr>
<tr>
<td>Time of Last Access</td>
<td><% out.print(lastAccessTime); %></td>
</tr>
<tr>
<td>User ID</td>
<td><% out.print(userID); %></td>
</tr>
<tr>
<td>Number of visits</td>
<td><% out.print(visitCount); %></td>
</tr>
</table>
</body>
</html>
现在将上面的代码放在main.jsp并尝试访问http://localhost:8080/main.jsp 。 运行URL后,您将收到以下结果 -
欢迎来到我的网站
Session Information
会话信息 | 值 |
---|---|
id | 0AE3EC93FF44E3C525B4351B77ABB2D5 |
创作时间 | Tue Jun 08 17:26:40 GMT + 04:00 2010 |
最后访问时间 | Tue Jun 08 17:26:40 GMT + 04:00 2010 |
用户身份 | ABCD |
访问次数 | 0 |
现在尝试第二次运行相同的JSP,您将收到以下结果。
欢迎回到我的网站
Session Information
信息类型 | 值 |
---|---|
id | 0AE3EC93FF44E3C525B4351B77ABB2D5 |
创作时间 | Tue Jun 08 17:26:40 GMT + 04:00 2010 |
最后访问时间 | Tue Jun 08 17:26:40 GMT + 04:00 2010 |
用户身份 | ABCD |
访问次数 | 1 |
删除会话数据
完成用户的会话数据后,您有多种选择 -
Remove a particular attribute - 您可以调用public void removeAttribute(String name)方法来删除与特定键关联的值。
Delete the whole session - 您可以调用public void invalidate()方法来丢弃整个会话。
Setting Session timeout - 您可以调用public void setMaxInactiveInterval(int interval)方法来单独设置会话的超时。
Log the user out - 支持servlet 2.4的服务器,您可以调用logout将客户端记录到Web服务器之外,并使属于所有用户的所有会话无效。
web.xml Configuration - 如果您使用的是Tomcat,除了上述方法之外,您还可以在web.xml文件中配置会话超时,如下所示。
<session-config>
<session-timeout>15</session-timeout>
</session-config>
超时以分钟表示,并覆盖Tomcat中的默认超时30分钟。
servlet中的getMaxInactiveInterval( )方法以秒为单位返回该会话的超时时间。 因此,如果您的会话在web.xml中配置了15分钟,则getMaxInactiveInterval( )将返回900。
JSP - File Uploading
在本章中,我们将讨论JSP中的文件上载。 JSP可以与HTML表单标记一起使用,以允许用户将文件上载到服务器。 上传的文件可以是文本文件,也可以是二进制文件或图像文件,也可以是任何文档。
创建文件上载表单
现在让我们了解如何创建文件上载表单。 以下HTML代码创建了一个上传器表单。 以下是需要注意的重点 -
表单method属性应设置为POST方法,并且不能使用GET方法。
表单enctype属性应设置为multipart/form-data 。
表单action属性应设置为JSP文件,该文件将处理后端服务器上的文件上载。 以下示例是使用uploadFile.jsp程序文件上传文件。
要上传单个文件,您应该使用带有属性type = "file"的单个《input .../》标记。 要允许多个文件上载,请包含多个具有不同name属性值的输入标记。 浏览器将“浏览”按钮与每个按钮相关联。
<html>
<head>
<title>File Uploading Form</title>
</head>
<body>
<h3>File Upload:</h3>
Select a file to upload: <br />
<form action = "UploadServlet" method = "post"
enctype = "multipart/form-data">
<input type = "file" name = "file" size = "50" />
<br />
<input type = "submit" value = "Upload File" />
</form>
</body>
</html>
这将显示以下结果。 您现在可以从本地PC中选择一个文件,当用户单击“上传文件”时,表单将与所选文件一起提交 -
<b class="notranslate">File Upload</b> −
<p>Select a file to upload −</p>
<input type="file" name="file" size="50">
<input type="button" value="Upload File">
NOTE - 上面的表单只是虚拟表单,不起作用,你应该尝试在你的机器上面的代码使其工作。
编写后端JSP脚本
现在让我们定义一个存储上传文件的位置。 您可以在程序中对此进行硬编码,也可以使用外部配置(例如web.xml中的context-param元素)添加此目录名,如下所示 -
<web-app>
....
<context-param>
<description>Location to store uploaded file</description>
<param-name>file-upload</param-name>
<param-value>
c:\apache-tomcat-5.5.29\webapps\data\
</param-value>
</context-param>
....
</web-app>
以下是UploadFile.jsp的源代码。 这可以一次处理多个文件的上传。 现在让我们在继续上传文件之前考虑以下事项。
以下示例依赖于FileUpload ; 确保在类路径中有最新版本的commons-fileupload.xxjar文件。 您可以从https://commons.apache.org/fileupload/下载它。
FileUpload依赖于Commons IO; 确保在类路径中有最新版本的commons-io-xxjar文件。 您可以从https://commons.apache.org/io/下载。
在测试以下示例时,您应该上传一个比maxFileSize的文件,否则不会上传该文件。
确保您提前创建了目录c:\temp和c:\apache-tomcat5.5.29\webapps\data 。
<%@ page import = "java.io.*,java.util.*, javax.servlet.*" %>
<%@ page import = "javax.servlet.http.*" %>
<%@ page import = "org.apache.commons.fileupload.*" %>
<%@ page import = "org.apache.commons.fileupload.disk.*" %>
<%@ page import = "org.apache.commons.fileupload.servlet.*" %>
<%@ page import = "org.apache.commons.io.output.*" %>
<%
File file ;
int maxFileSize = 5000 * 1024;
int maxMemSize = 5000 * 1024;
ServletContext context = pageContext.getServletContext();
String filePath = context.getInitParameter("file-upload");
// Verify the content type
String contentType = request.getContentType();
if ((contentType.indexOf("multipart/form-data") >= 0)) {
DiskFileItemFactory factory = new DiskFileItemFactory();
// maximum size that will be stored in memory
factory.setSizeThreshold(maxMemSize);
// Location to save data that is larger than maxMemSize.
factory.setRepository(new File("c:\\temp"));
// Create a new file upload handler
ServletFileUpload upload = new ServletFileUpload(factory);
// maximum file size to be uploaded.
upload.setSizeMax( maxFileSize );
try {
// Parse the request to get file items.
List fileItems = upload.parseRequest(request);
// Process the uploaded file items
Iterator i = fileItems.iterator();
out.println("<html>");
out.println("<head>");
out.println("<title>JSP File upload</title>");
out.println("</head>");
out.println("<body>");
while ( i.hasNext () ) {
FileItem fi = (FileItem)i.next();
if ( !fi.isFormField () ) {
// Get the uploaded file parameters
String fieldName = fi.getFieldName();
String fileName = fi.getName();
boolean isInMemory = fi.isInMemory();
long sizeInBytes = fi.getSize();
// Write the file
if( fileName.lastIndexOf("\\") >= 0 ) {
file = new File( filePath +
fileName.substring( fileName.lastIndexOf("\\"))) ;
} else {
file = new File( filePath +
fileName.substring(fileName.lastIndexOf("\\")+1)) ;
}
fi.write( file ) ;
out.println("Uploaded Filename: " + filePath +
fileName + "<br>");
}
}
out.println("</body>");
out.println("</html>");
} catch(Exception ex) {
System.out.println(ex);
}
} else {
out.println("<html>");
out.println("<head>");
out.println("<title>Servlet upload</title>");
out.println("</head>");
out.println("<body>");
out.println("<p>No file uploaded</p>");
out.println("</body>");
out.println("</html>");
}
%>
现在尝试使用您在上面创建的HTML表单上传文件。 当您尝试http://localhost:8080/UploadFile.htm ,它将显示以下结果。 这将帮助您从本地计算机上传任何文件。
<b class="notranslate">File Upload</b> −
<p>Select a file to upload −</p>
<input type="file" name="file" size="50">
<input type="button" value="Upload File">
如果您的JSP脚本正常工作,您的文件应该上传到c:\apache-tomcat5.5.29\webapps\data\目录。
JSP - Handling Date
在本章中,我们将讨论如何在JSP中处理数据。 使用JSP的一个最重要的优点是您可以使用核心Java中提供的所有方法。 我们将引导您完成java.util包中提供的Date类; 这个类封装了当前的日期和时间。
Date类支持两个构造函数。 第一个构造函数使用当前日期和时间初始化对象。
Date( )
以下构造函数接受一个参数,该参数等于自1970年1月1日午夜以来经过的毫秒数。
Date(long millisec)
一旦有了Date对象,就可以调用以下任何支持方法来使用日期 -
S.No. | 方法和描述 |
---|---|
1 | boolean after(Date date) 如果调用Date对象包含的日期晚于date指定的日期,则返回true,否则返回false。 |
2 | boolean before(Date date) 如果调用Date对象包含的日期早于date指定的日期,则返回true,否则返回false。 |
3 | Object clone( ) 复制调用Date对象。 |
4 | int compareTo(Date date) 将调用对象的值与date的值进行比较。 如果值相等则返回0。 如果调用对象早于date,则返回负值。 如果调用对象晚于date,则返回正值。 |
5 | int compareTo(Object obj) 如果obj是Date类,则与compareTo(Date)操作相同。 否则,它会抛出ClassCastException。 |
6 | boolean equals(Object date) 如果调用Date对象包含与date指定的时间和日期相同的时间和日期,则返回true,否则返回false。 |
7 | long getTime( ) 返回自1970年1月1日以来经过的毫秒数。 |
8 | int hashCode( ) 返回调用对象的哈希码。 |
9 | void setTime(long time) 设置时间指定的时间和日期,表示从1970年1月1日午夜开始的经过时间(以毫秒为单位) |
10 | String toString( ) 将调用Date对象转换为字符串并返回结果。 |
获取当前日期和时间
使用JSP程序,很容易获得当前的日期和时间。 您可以使用带有toString()方法的简单Date对象来打印当前日期和时间,如下所示 -
<%@ page import = "java.io.*,java.util.*, javax.servlet.*" %>
<html>
<head>
<title>Display Current Date & Time</title>
</head>
<body>
<center>
<h1>Display Current Date & Time</h1>
</center>
<%
Date date = new Date();
out.print( "<h2 align = \"center\">" +date.toString()+"</h2>");
%>
</body>
</html>
现在让我们将代码保存在CurrentDate.jsp ,然后使用URL http://localhost:8080/CurrentDate.jsp调用此JSP。 您将收到以下结果 -
<h1 align="center">Display Current Date & Time</h1>
<h2 align="center">Mon Jun 21 21:46:49 GMT+04:00 2010</h2>
使用URL http://localhost:8080/CurrentDate.jsp刷新页面。 每次刷新时,您都会发现秒数的差异。
日期比较
如前几节所述,您可以在JSP脚本中使用所有可用的Java方法。 如果您需要比较两个日期,请考虑以下方法 -
您可以使用getTime( )方法获取两个对象自1970年1月1日午夜以来经过的毫秒数,然后比较这两个值。
您可以使用before( ), after( )和equals( ) before( ), after( )的方法before( ), after( )因为该月的第12个月在18之前; 例如, new Date(99, 2, 12).before(new Date (99, 2, 18))返回true。
您可以使用compareTo( )方法; 此方法由Comparable interface定义,并由Date实现。
使用SimpleDateFormat格式化日期
SimpleDateFormat是一个具体的类,用于以区域设置敏感的方式格式化和解析日期。 SimpleDateFormat允许您从为日期时间格式选择任何用户定义的模式开始。
让我们修改上面的例子如下 -
<%@ page import = "java.io.*,java.util.*" %>
<%@ page import = "javax.servlet.*,java.text.*" %>
<html>
<head>
<title>Display Current Date & Time</title>
</head>
<body>
<center>
<h1>Display Current Date & Time</h1>
</center>
<%
Date dNow = new Date( );
SimpleDateFormat ft =
new SimpleDateFormat ("E yyyy.MM.dd 'at' hh:mm:ss a zzz");
out.print( "<h2 align=\"center\">" + ft.format(dNow) + "</h2>");
%>
</body>
</html>
再次编译上面的servlet,然后使用URL http://localhost:8080/CurrentDate调用此servlet。 您将收到以下结果 -
<h1 align="center">Display Current Date & Time</h1>
<h2 align="center">Mon 2010.06.21 at 10:06:44 PM GMT+04:00</h2>
简单的DateFormat格式代码
要指定时间格式,请使用时间模式字符串。 在此模式中,所有ASCII字母都保留为模式字母,其定义如下 -
字符 | 描述 | 例 |
---|---|---|
G | 时代指示符 | AD |
y | 四位数的年份 | 2001 |
M | 一年一个月 | 七月或七月 |
d | 一个月的日子 | 0 |
h | 上午/下午(1~12)小时 | 2 |
H | 一天中的小时(0~23) | 22 |
m | 一小时一分钟 | 30 |
s | 第二分钟 | 55 |
S | Millisecond | 234 |
E | 一周中的一天 | Tuesday |
D | 一年中的一天 | 360 |
F | 一个月中的某一天 | 2(7月第二个周三) |
w | 一周一周 | 40 |
W | 一周一个月 | |
a | AM/PM标记 | PM |
k | 一天中的小时(1~24) | 24 |
K | 上午/下午(0~11)小时 | 0 |
z | 时区 | 东部标准时间 |
' | 逃避文字 | Delimiter |
" | 单引号 | ` |
有关操作日期的常量可用方法的完整列表,可以参考标准Java文档。
JSP - Page Redirecting
在本章中,我们将讨论使用JSP重定向页面。 页面重定向通常在文档移动到新位置时使用,我们需要将客户端发送到此新位置。 这可能是因为负载平衡或简单的随机化。
将请求重定向到另一个页面的最简单方法是使用响应对象的sendRedirect()方法。 以下是此方法的签名 -
public void response.sendRedirect(String location)
throws IOException
此方法将响应以及状态代码和新页面位置发送回浏览器。 您还可以一起使用setStatus()和setHeader()方法来实现相同的重定向示例 -
....
String site = "http://www.newpage.com" ;
response.setStatus(response.SC_MOVED_TEMPORARILY);
response.setHeader("Location", site);
....
例子 (Example)
此示例显示JSP如何执行页面重定向到另一个位置 -
<%@ page import = "java.io.*,java.util.*" %>
<html>
<head>
<title>Page Redirection</title>
</head>
<body>
<center>
<h1>Page Redirection</h1>
</center>
<%
// New location to be redirected
String site = new String("http://www.photofuntoos.com");
response.setStatus(response.SC_MOVED_TEMPORARILY);
response.setHeader("Location", site);
%>
</body>
</html>
现在让我们将上面的代码放在PageRedirect.jsp中,并使用URL http://localhost:8080/PageRedirect.jsp调用此JSP。 这将带您到达给定的URL http://www.photofuntoos.com 。
JSP - Hits Counter
在本章中,我们将讨论JSP中的Hits Counter。 点击计数器会告诉您网站特定页面的访问次数。 通常你会在index.jsp页面附上一个点击计数器,假设人们首先登陆你的主页。
要实现命中计数器,您可以使用Application Implicit对象和相关方法getAttribute()和setAttribute() 。
该对象是JSP页面整个生命周期的表示。 初始化JSP页面时会创建此对象,并且在jspDestroy()方法删除JSP页面时将删除该对象。
以下是在应用程序级别设置变量的语法 -
application.setAttribute(String Key, Object Value);
您可以使用上述方法设置命中计数器变量并重置相同的变量。 以下是读取前一个方法设置的变量的方法 -
application.getAttribute(String Key);
每次用户访问您的页面时,您都可以读取命中计数器的当前值并将其增加1并再次设置以供将来使用。
例子 (Example)
此示例显示如何使用JSP计算特定页面上的总命中数。 如果要计算网站的总点击次数,则必须在所有JSP页面中包含相同的代码。
<%@ page import = "java.io.*,java.util.*" %>
<html>
<head>
<title>Application object in JSP</title>
</head>
<body>
<%
Integer hitsCount = (Integer)application.getAttribute("hitCounter");
if( hitsCount ==null || hitsCount == 0 ) {
/* First visit */
out.println("Welcome to my website!");
hitsCount = 1;
} else {
/* return visit */
out.println("Welcome back to my website!");
hitsCount += 1;
}
application.setAttribute("hitCounter", hitsCount);
%>
<center>
<p>Total number of visits: <%= hitsCount%></p>
</center>
</body>
</html>
现在让我们将上面的代码放在main.jsp并使用URL http://localhost:8080/main.jsp调用此JSP。 这将显示点击计数器值,该值在刷新页面时会增加。 您可以尝试使用不同的浏览器访问该页面,您会发现点击计数器会随着每次点击而不断增加,您将收到如下结果 -
<center>
<p>Welcome back to my website!</p>
<p>Total number of visits: 12</p>
</center>
命中计数器重置
当您重新启动应用程序(即Web服务器)时,这将重置您的应用程序变量,并且您的计数器将重置为零。 为避免这种损失,请考虑以下几点 -
使用单个计数定义数据库表,让我们说hitcount。 为其分配零值。
每次点击,读取表格以获得hitcount的值。
将hitcount的值增加1并使用新值更新表。
显示hitcount的新值作为总页数命中数。
如果要计算所有页面的命中数,请为所有页面实现上述逻辑。
JSP - Auto Refresh
在本章中,我们将讨论JSP中的Auto Refresh。 考虑一个显示实时游戏得分或股票市场状态或货币兑换率的网页。 对于所有此类类型的页面,您需要使用浏览器的刷新或重新加载按钮定期刷新网页。
JSP为您提供了一种机制,您可以通过这种机制创建一个网页,使其在给定的时间间隔后自动刷新。
刷新网页的最简单方法是使用响应对象的setIntHeader()方法。 以下是此方法的签名 -
public void setIntHeader(String header, int headerValue)
此方法将标题“Refresh”发送回浏览器以及一个整数值,该值表示以秒为单位的时间间隔。
自动页面刷新示例
在下面的示例中,我们将使用setIntHeader()方法设置Refresh标头。 这有助于模拟数字时钟 -
<%@ page import = "java.io.*,java.util.*" %>
<html>
<head>
<title>Auto Refresh Header Example</title>
</head>
<body>
<center>
<h2>Auto Refresh Header Example</h2>
<%
// Set refresh, autoload time as 5 seconds
response.setIntHeader("Refresh", 5);
// Get current time
Calendar calendar = new GregorianCalendar();
String am_pm;
int hour = calendar.get(Calendar.HOUR);
int minute = calendar.get(Calendar.MINUTE);
int second = calendar.get(Calendar.SECOND);
if(calendar.get(Calendar.AM_PM) == 0)
am_pm = "AM";
else
am_pm = "PM";
String CT = hour+":"+ minute +":"+ second +" "+ am_pm;
out.println("Crrent Time: " + CT + "\n");
%>
</center>
</body>
</html>
现在将上面的代码放在main.jsp并尝试访问它。 这将显示每5秒后的当前系统时间,如下所示。 只需运行JSP并等待查看结果 -
<h2 align="center">Auto Refresh Header Example</h2>
Current Time is: 9:44:50 PM
JSP - Sending Email
在本章中,我们将讨论如何使用JSP发送电子邮件。 要使用JSP发送电子邮件,您应该在计算机上安装JavaMail API和Java Activation Framework (JAF) 。
您可以从Java的标准网站下载最新版本的JavaMail (Version 1.2) 。
您可以从Java的标准网站下载最新版本的JavaBeans Activation Framework JAF (Version 1.0.2) 。
在新创建的顶级目录中下载并解压缩这些文件。 您将找到两个应用程序的jar文件。 您需要在CLASSPATH中添加mail.jar和activation.jar文件。
发送简单电子邮件
以下是从您的计算机发送简单电子邮件的示例。 假设您的localhost已连接到Internet,并且它足以发送电子邮件。 确保CLASSPATH中的Java Email API包和JAF包中的所有jar文件都可用。
<%@ page import = "java.io.*,java.util.*,javax.mail.*"%>
<%@ page import = "javax.mail.internet.*,javax.activation.*"%>
<%@ page import = "javax.servlet.http.*,javax.servlet.*" %>
<%
String result;
// Recipient's email ID needs to be mentioned.
String to = "abcd@gmail.com";
// Sender's email ID needs to be mentioned
String from = "mcmohd@gmail.com";
// Assuming you are sending email from localhost
String host = "localhost";
// Get system properties object
Properties properties = System.getProperties();
// Setup mail server
properties.setProperty("mail.smtp.host", host);
// Get the default Session object.
Session mailSession = Session.getDefaultInstance(properties);
try {
// Create a default MimeMessage object.
MimeMessage message = new MimeMessage(mailSession);
// Set From: header field of the header.
message.setFrom(new InternetAddress(from));
// Set To: header field of the header.
message.addRecipient(Message.RecipientType.TO,
new InternetAddress(to));
// Set Subject: header field
message.setSubject("This is the Subject Line!");
// Now set the actual message
message.setText("This is actual message");
// Send message
Transport.send(message);
result = "Sent message successfully....";
} catch (MessagingException mex) {
mex.printStackTrace();
result = "Error: unable to send message....";
}
%>
<html>
<head>
<title>Send Email using JSP</title>
</head>
<body>
<center>
<h1>Send Email using JSP</h1>
</center>
<p align = "center">
<%
out.println("Result: " + result + "\n");
%>
</p>
</body>
</html>
现在让我们将上面的代码放在SendEmail.jsp文件中,并使用URL http://localhost:8080/SendEmail.jsp调用此JSP。 这将有助于向给定的电子邮件ID abcd@gmail.com发送电子邮件。 您将收到以下回复 -
<h1 align="center">Send Email using JSP</h1>
<p align="center">Result: Sent message successfully....</p>
如果要向多个收件人发送电子邮件,请使用以下方法指定多个电子邮件ID -
void addRecipients(Message.RecipientType type, Address[] addresses)
throws MessagingException
以下是参数的说明 -
type - 将设置为TO,CC或BCC。 这里CC表示碳复制,BCC表示黑碳复制。 示例Message.RecipientType.TO
addresses - 这是电子邮件ID的数组。 在指定电子邮件ID时,您需要使用InternetAddress()方法
发送HTML电子邮件
以下是从您的计算机发送HTML电子邮件的示例。 假设您的localhost已连接到Internet,并且它足以发送电子邮件。 确保CLASSPATH中的Java Email API package和JAF package中的所有jar文件都可用。
此示例与前一个示例非常相似,不同之处在于我们使用setContent()方法设置第二个参数为"text/html"的内容,以指定HTML内容包含在消息中。
使用此示例,您可以根据需要发送大量HTML内容。
<%@ page import = "java.io.*,java.util.*,javax.mail.*"%>
<%@ page import = "javax.mail.internet.*,javax.activation.*"%>
<%@ page import = "javax.servlet.http.*,javax.servlet.*" %>
<%
String result;
// Recipient's email ID needs to be mentioned.
String to = "abcd@gmail.com";
// Sender's email ID needs to be mentioned
String from = "mcmohd@gmail.com";
// Assuming you are sending email from localhost
String host = "localhost";
// Get system properties object
Properties properties = System.getProperties();
// Setup mail server
properties.setProperty("mail.smtp.host", host);
// Get the default Session object.
Session mailSession = Session.getDefaultInstance(properties);
try {
// Create a default MimeMessage object.
MimeMessage message = new MimeMessage(mailSession);
// Set From: header field of the header.
message.setFrom(new InternetAddress(from));
// Set To: header field of the header.
message.addRecipient(Message.RecipientType.TO, new InternetAddress(to));
// Set Subject: header field
message.setSubject("This is the Subject Line!");
// Send the actual HTML message, as big as you like
message.setContent("<h1>This is actual message</h1>", "text/html" );
// Send message
Transport.send(message);
result = "Sent message successfully....";
} catch (MessagingException mex) {
mex.printStackTrace();
result = "Error: unable to send message....";
}
%>
<html>
<head>
<title>Send HTML Email using JSP</title>
</head>
<body>
<center>
<h1>Send Email using JSP</h1>
</center>
<p align = "center">
<%
out.println("Result: " + result + "\n");
%>
</p>
</body>
</html>
现在让我们使用上面的JSP在给定的电子邮件ID上发送HTML消息。
在电子邮件中发送附件
以下是从您的计算机发送带附件的电子邮件的示例 -
<%@ page import = "java.io.*,java.util.*,javax.mail.*"%>
<%@ page import = "javax.mail.internet.*,javax.activation.*"%>
<%@ page import = "javax.servlet.http.*,javax.servlet.*" %>
<%
String result;
// Recipient's email ID needs to be mentioned.
String to = "abcd@gmail.com";
// Sender's email ID needs to be mentioned
String from = "mcmohd@gmail.com";
// Assuming you are sending email from localhost
String host = "localhost";
// Get system properties object
Properties properties = System.getProperties();
// Setup mail server
properties.setProperty("mail.smtp.host", host);
// Get the default Session object.
Session mailSession = Session.getDefaultInstance(properties);
try {
// Create a default MimeMessage object.
MimeMessage message = new MimeMessage(mailSession);
// Set From: header field of the header.
message.setFrom(new InternetAddress(from));
// Set To: header field of the header.
message.addRecipient(Message.RecipientType.TO, new InternetAddress(to));
// Set Subject: header field
message.setSubject("This is the Subject Line!");
// Create the message part
BodyPart messageBodyPart = new MimeBodyPart();
// Fill the message
messageBodyPart.setText("This is message body");
// Create a multipart message
Multipart multipart = new MimeMultipart();
// Set text message part
multipart.addBodyPart(messageBodyPart);
// Part two is attachment
messageBodyPart = new MimeBodyPart();
String filename = "file.txt";
DataSource source = new FileDataSource(filename);
messageBodyPart.setDataHandler(new DataHandler(source));
messageBodyPart.setFileName(filename);
multipart.addBodyPart(messageBodyPart);
// Send the complete message parts
message.setContent(multipart );
// Send message
Transport.send(message);
String title = "Send Email";
result = "Sent message successfully....";
} catch (MessagingException mex) {
mex.printStackTrace();
result = "Error: unable to send message....";
}
%>
<html>
<head>
<title>Send Attachment Email using JSP</title>
</head>
<body>
<center>
<h1>Send Attachment Email using JSP</h1>
</center>
<p align = "center">
<%out.println("Result: " + result + "\n");%>
</p>
</body>
</html>
现在让我们运行上面的JSP,将文件作为附件发送,并在给定的电子邮件ID上发送消息。
用户认证部分
如果需要向电子邮件服务器提供用户ID和密码以进行身份验证,则可以按如下方式设置这些属性 -
props.setProperty("mail.user", "myuser");
props.setProperty("mail.password", "mypwd");
其余的电子邮件发送机制将保持如上所述。
使用表单发送电子邮件
您可以使用HTML表单接受电子邮件参数,然后您可以使用request对象获取以下所有信息 -
String to = request.getParameter("to");
String from = request.getParameter("from");
String subject = request.getParameter("subject");
String messageText = request.getParameter("body");
获得所有信息后,您可以使用上述程序发送电子邮件。
JSP - Standard Tag Library (JSTL) Tutorial
在本章中,我们将了解JSP中的不同标记。 JavaServer Pages标准标记库(JSTL)是有用的JSP标记的集合,它封装了许多JSP应用程序通用的核心功能。
JSTL支持常见的结构任务,例如迭代和条件,用于操作XML文档的标记,国际化标记和SQL标记。 它还提供了一个框架,用于将现有自定义标记与JSTL标记集成。
安装JSTL库
要开始使用JSP tages,首先需要安装JSTL库。 如果您使用的是Apache Tomcat容器,请按照以下两个步骤进行操作 -
Step 1 - 从Apache Standard Taglib下载二进制发行版并解压缩压缩文件。
Step 2 - 要从其Jakarta Taglibs distribution使用标准Taglib,只需将发行版'lib'目录中的JAR文件复制到应用程序的webapps\ROOT\WEB-INF\lib目录中。
要使用任何库,必须在使用该库的每个JSP的顶部包含
JSTL标签的分类
JSTL标记可以根据其功能分类到以下可在创建JSP页面时使用的JSTL标记库组中 -
Core Tags
Formatting tags
SQL tags
XML tags
JSTL Functions
核心标签
核心标签组是最常用的JSTL标签。 以下是在JSP中包含JSTL核心库的语法 -
<%@ taglib prefix = "c" uri = "http://java.sun.com/jsp/jstl/core" %>
下表列出了核心JSTL标签 -
S.No. | 标签和说明 |
---|---|
1 | <c:out> 像,但对于表达式。 |
2 | <c:设置> 在'scope'设置表达式求值的结果 |
3 | <c:删除> 删除scoped variable (来自特定范围,如果指定)。 |
4 | <c:catch> 捕获其体内发生的任何Throwable并可选择暴露它。 |
5 | <c:if> 简单条件标记,如果提供的条件为真,则评估其正文。 |
6 | <c:choose> 简单条件标记,用于为互斥条件操作建立上下文,标记为《when》和《otherwise》 。 |
7 | <c:when> 如果条件评估为'true' ,则《choose》标签包括其正文。 |
8 | <c:否则> 《choose》标签位于《when》标签之后,仅在所有先前条件评估为'false' 。 |
9 | <c:import> 检索绝对或相对URL,并将其内容公开给页面, 'var'的String或'varReader'的Reader。 |
10 | <c:forEach> 基本迭代标记,接受许多不同的集合类型并支持子集和其他功能。 |
11 | <c:forTokens> 迭代令牌,由提供的分隔符分隔。 |
12 | <c:param> 将参数添加到包含'import'标记的URL。 |
13 | <c:重定向> 重定向到新的URL。 |
14 | <c:url> 使用可选的查询参数创建URL |
格式化标签
JSTL格式标签用于格式化和显示国际化网站的文本,日期,时间和数字。 以下是在JSP中包含格式化库的语法 -
<%@ taglib prefix = "fmt" uri = "http://java.sun.com/jsp/jstl/fmt" %>
下表列出了格式化JSTL标签 -
S.No. | 标签和说明 |
---|---|
1 | <fmt:formatNumber> 以特定精度或格式呈现数值。 |
2 | <fmt:parseNumber> 解析数字,货币或百分比的字符串表示形式。 |
3 | <fmt:formatDate> 使用提供的样式和模式格式化日期和/或时间。 |
4 | <fmt:parseDate> 解析日期和/或时间的字符串表示 |
5 | <fmt:bundle> 加载要由其标记主体使用的资源包。 |
6 | <fmt:setLocale> 将给定的语言环境存储在语言环境配置变量中。 |
7 | <fmt:setBundle> 加载资源包并将其存储在指定的范围变量或包配置变量中。 |
8 | <fmt:timeZone> 指定嵌套在其正文中的任何时间格式化或解析操作的时区。 |
9 | <fmt:setTimeZone> 在时区配置变量中存储给定时区 |
10 | <fmt:message> 显示国际化消息。 |
11 | <fmt:requestEncoding> 设置请求字符编码 |
SQL Tags
JSTL SQL标记库提供用于与关系数据库(RDBMS)(如Oracle, mySQL或Microsoft SQL Server )交互的标记。
以下是在JSP中包含JSTL SQL库的语法 -
<%@ taglib prefix = "sql" uri = "http://java.sun.com/jsp/jstl/sql" %>
下表列出了SQL JSTL标签 -
S.No. | 标签和说明 |
---|---|
1 | <sql:setDataSource> 创建一个仅适用于原型设计的简单DataSource |
2 | <sql:query> 执行在其正文中或通过sql属性定义的SQL查询。 |
3 | <sql:update> 执行在其正文中或通过sql属性定义的SQL更新。 |
4 | <sql:param> 将SQL语句中的参数设置为指定的值。 |
5 | <sql:dateParam> 将SQL语句中的参数设置为指定的java.util.Date值。 |
6 | <sql:transaction> 提供具有共享Connection的嵌套数据库操作元素,设置为将所有语句作为一个事务执行。 |
XML标签
JSTL XML标记提供了一种以JSP为中心的方法来创建和操作XML文档。 以下是在JSP中包含JSTL XML库的语法。
JSTL XML标记库具有用于与XML数据交互的自定义标记。 这包括解析XML,转换XML数据以及基于XPath表达式的流控制。
<%@ taglib prefix = "x"
uri = "http://java.sun.com/jsp/jstl/xml" %>
在继续执行示例之前,您需要将以下两个与XML和XPath相关的库复制到《Tomcat Installation Directory》\lib -
XercesImpl.jar - 从https://www.apache.org/dist/xerces/j/下载
xalan.jar - 从https://xml.apache.org/xalan-j/index.html下载
以下是XML JSTL标签列表 -
S.No. | 标签和说明 |
---|---|
1 | <x:out> 像,但对于XPath表达式。 |
2 | <x:parse> 用于解析通过属性或标记正文中指定的XML数据。 |
3 | <x:set> 将变量设置为XPath表达式的值。 |
4 | <x:if> 计算测试XPath表达式,如果为true,则处理其正文。 如果测试条件为假,则忽略正文。 |
5 | <x:forEach> 循环遍历XML文档中的节点。 |
6 | <x:choose> 简单条件标记,用于为互斥条件操作建立上下文,标记为《when》和《otherwise》标记。 |
7 | <x:when> 《choose》标签,如果其表达式评估为《choose》 ,则包括其正文。 |
8 | <x:否则> 《choose》标签位于《when》标签之后,仅在所有先前条件评估为“false”时运行。 |
9 | <x:transform> 在XML文档上应用XSL转换 |
10 | <x:param> 与transform标记一起使用以在XSLT样式表中设置参数 |
JSTL 函数
JSTL包含许多标准函数,其中大多数是常见的字符串操作函数。 以下是在JSP中包含JSTL函数库的语法 -
<%@ taglib prefix = "fn"
uri = "http://java.sun.com/jsp/jstl/functions" %>
下表列出了各种JSTL函数 -
S.No. | 功能说明 |
---|---|
1 | fn:contains() 测试输入字符串是否包含指定的子字符串。 |
2 | fn:containsIgnoreCase() 测试输入字符串是否以不区分大小写的方式包含指定的子字符串。 |
3 | fn:endsWith() 测试输入字符串是否以指定的后缀结尾。 |
4 | fn:escapeXml() 转义可以解释为XML标记的字符。 |
5 | fn:indexOf() 返回带有第一次出现的指定子字符串的字符串的索引。 |
6 | fn:join() 将数组的所有元素连接成一个字符串。 |
7 | fn:length() 返回集合中的项目数或字符串中的字符数。 |
8 | fn:replace() 返回一个字符串,该字符串是在输入字符串中替换所有出现的字符串。 |
9 | fn:split() 将字符串拆分为子字符串数组。 |
10 | fn:startsWith() 测试输入字符串是否以指定的前缀开头。 |
11 | fn:substring() 返回字符串的子集。 |
12 | fn:substringAfter() 返回特定子字符串后面的字符串的子集。 |
13 | fn:substringBefore() 返回特定子字符串之前的字符串子集。 |
14 | fn:toLowerCase() 将字符串的所有字符转换为小写。 |
15 | fn:toUpperCase() 将字符串的所有字符转换为大写。 |
16 | fn:trim() 从字符串的两端删除空格。 |
JSP - Database Access
在本章中,我们将讨论如何使用JSP访问数据库。 我们假设您对JDBC应用程序的工作原理有很好的理解。 在通过JSP开始数据库访问之前,请确保您具有正确的JDBC环境设置以及数据库。
有关如何使用JDBC及其环境设置访问数据库的更多详细信息,您可以浏览我们的JDBC教程 。
从基本概念开始,让我们创建一个表并在该表中创建一些记录,如下所示 -
Create Table
要在EMP数据库中创建Employees表,请使用以下步骤 -
Step 1
打开Command Prompt并切换到安装目录,如下所示 -
C:\>
C:\>cd Program Files\MySQL\bin
C:\Program Files\MySQL\bin>
Step 2
登录数据库如下 -
C:\Program Files\MySQL\bin>mysql -u root -p
Enter password: ********
mysql>
Step 3
在TEST数据库中创建Employee表,如下所示 - -
mysql> use TEST;
mysql> create table Employees
(
id int not null,
age int not null,
first varchar (255),
last varchar (255)
);
Query OK, 0 rows affected (0.08 sec)
mysql>
创建数据记录 (Create Data Records)
现在让我们在Employee表中创建一些记录,如下所示 -
mysql> INSERT INTO Employees VALUES (100, 18, 'Zara', 'Ali');
Query OK, 1 row affected (0.05 sec)
mysql> INSERT INTO Employees VALUES (101, 25, 'Mahnaz', 'Fatma');
Query OK, 1 row affected (0.00 sec)
mysql> INSERT INTO Employees VALUES (102, 30, 'Zaid', 'Khan');
Query OK, 1 row affected (0.00 sec)
mysql> INSERT INTO Employees VALUES (103, 28, 'Sumit', 'Mittal');
Query OK, 1 row affected (0.00 sec)
mysql>
选择操作 (SELECT Operation)
以下示例显示了如何在JSP编程中使用JTSL执行SQL SELECT语句 -
<%@ page import = "java.io.*,java.util.*,java.sql.*"%>
<%@ page import = "javax.servlet.http.*,javax.servlet.*" %>
<%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix = "c"%>
<%@ taglib uri="http://java.sun.com/jsp/jstl/sql" prefix = "sql"%>
<html>
<head>
<title>SELECT Operation</title>
</head>
<body>
<sql:setDataSource var = "snapshot" driver = "com.mysql.jdbc.Driver"
url = "jdbc:mysql://localhost/TEST"
user = "root" password = "pass123"/>
<sql:query dataSource = "${snapshot}" var = "result">
SELECT * from Employees;
</sql:query>
<table border = "1" width = "100%">
<tr>
<th>Emp ID</th>
<th>First Name</th>
<th>Last Name</th>
<th>Age</th>
</tr>
<c:forEach var = "row" items = "${result.rows}">
<tr>
<td><c:out value = "${row.id}"/></td>
<td><c:out value = "${row.first}"/></td>
<td><c:out value = "${row.last}"/></td>
<td><c:out value = "${row.age}"/></td>
</tr>
</c:forEach>
</table>
</body>
</html>
访问上面的JSP,将显示以下结果 -
None
Emp ID | 名字 | 姓 | 年龄 |
---|---|---|---|
100 | Zara | Ali | 18 |
101 | Mahnaz | Fatma | 25 |
102 | Zaid | Khan | 30 |
103 | Sumit | Mittal | 28 |
插入操作
以下示例显示了如何在JSP编程中使用JTSL执行SQL INSERT语句 -
<%@ page import = "java.io.*,java.util.*,java.sql.*"%>
<%@ page import = "javax.servlet.http.*,javax.servlet.*" %>
<%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix = "c"%>
<%@ taglib uri="http://java.sun.com/jsp/jstl/sql" prefix = "sql"%>
<html>
<head>
<title>JINSERT Operation</title>
</head>
<body>
<sql:setDataSource var = "snapshot" driver = "com.mysql.jdbc.Driver"
url = "jdbc:mysql://localhost/TEST"
user = "root" password = "pass123"/>
<sql:update dataSource = "${snapshot}" var = "result">
INSERT INTO Employees VALUES (104, 2, 'Nuha', 'Ali');
</sql:update>
<sql:query dataSource = "${snapshot}" var = "result">
SELECT * from Employees;
</sql:query>
<table border = "1" width = "100%">
<tr>
<th>Emp ID</th>
<th>First Name</th>
<th>Last Name</th>
<th>Age</th>
</tr>
<c:forEach var = "row" items = "${result.rows}">
<tr>
<td><c:out value = "${row.id}"/></td>
<td><c:out value = "${row.first}"/></td>
<td><c:out value = "${row.last}"/></td>
<td><c:out value = "${row.age}"/></td>
</tr>
</c:forEach>
</table>
</body>
</html>
访问上面的JSP,将显示以下结果 -
None
Emp ID | 名字 | 姓 | 年龄 |
---|---|---|---|
100 | Zara | Ali | 18 |
101 | Mahnaz | Fatma | 25 |
102 | Zaid | Khan | 30 |
103 | Sumit | Mittal | 28 |
104 | Nuha | Ali | 2 |
删除操作
以下示例显示了如何在JSP编程中使用JTSL执行SQL DELETE语句 -
<%@ page import = "java.io.*,java.util.*,java.sql.*"%>
<%@ page import = "javax.servlet.http.*,javax.servlet.*" %>
<%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix = "c"%>
<%@ taglib uri="http://java.sun.com/jsp/jstl/sql" prefix = "sql"%>
<html>
<head>
<title>DELETE Operation</title>
</head>
<body>
<sql:setDataSource var = "snapshot" driver = "com.mysql.jdbc.Driver"
url = "jdbc:mysql://localhost/TEST"
user = "root" password = "pass123"/>
<c:set var = "empId" value = "103"/>
<sql:update dataSource = "${snapshot}" var = "count">
DELETE FROM Employees WHERE Id = ?
<sql:param value = "${empId}" />
</sql:update>
<sql:query dataSource = "${snapshot}" var = "result">
SELECT * from Employees;
</sql:query>
<table border = "1" width = "100%">
<tr>
<th>Emp ID</th>
<th>First Name</th>
<th>Last Name</th>
<th>Age</th>
</tr>
<c:forEach var = "row" items = "${result.rows}">
<tr>
<td><c:out value = "${row.id}"/></td>
<td><c:out value = "${row.first}"/></td>
<td><c:out value = "${row.last}"/></td>
<td><c:out value = "${row.age}"/></td>
</tr>
</c:forEach>
</table>
</body>
</html>
访问上面的JSP,将显示以下结果 -
None
Emp ID | 名字 | 姓 | 年龄 |
---|---|---|---|
100 | Zara | Ali | 18 |
101 | Mahnaz | Fatma | 25 |
102 | Zaid | Khan | 30 |
更新操作
以下示例显示了如何在JSP编程中使用JTSL执行SQL UPDATE语句 -
<%@ page import = "java.io.*,java.util.*,java.sql.*"%>
<%@ page import = "javax.servlet.http.*,javax.servlet.*" %>
<%@ taglib uri = "http://java.sun.com/jsp/jstl/core" prefix = "c"%>
<%@ taglib uri = "http://java.sun.com/jsp/jstl/sql" prefix = "sql"%>
<html>
<head>
<title>DELETE Operation</title>
</head>
<body>
<sql:setDataSource var = "snapshot" driver = "com.mysql.jdbc.Driver"
url = "jdbc:mysql://localhost/TEST"
user = "root" password = "pass123"/>
<c:set var = "empId" value = "102"/>
<sql:update dataSource = "${snapshot}" var = "count">
UPDATE Employees SET WHERE last = 'Ali'
<sql:param value = "${empId}" />
</sql:update>
<sql:query dataSource = "${snapshot}" var = "result">
SELECT * from Employees;
</sql:query>
<table border = "1" width = "100%">
<tr>
<th>Emp ID</th>
<th>First Name</th>
<th>Last Name</th>
<th>Age</th>
</tr>
<c:forEach var = "row" items = "${result.rows}">
<tr>
<td><c:out value = "${row.id}"/></td>
<td><c:out value = "${row.first}"/></td>
<td><c:out value = "${row.last}"/></td>
<td><c:out value = "${row.age}"/></td>
</tr>
</c:forEach>
</table>
</body>
</html>
访问上面的JSP,将显示以下结果 -
None
Emp ID | 名字 | 姓 | 年龄 |
---|---|---|---|
100 | Zara | Ali | 18 |
101 | Mahnaz | Fatma | 25 |
102 | Zaid | Ali | 30 |
JSP - XML Data
当您通过HTTP发送XML数据时,使用JSP处理传入和传出的XML文档是有意义的; 例如,RSS文档。 由于XML文档只是一堆文本,因此通过JSP创建一个文档比创建HTML文档容易得多。
从JSP发送XML
您可以使用JSP发送XML内容,就像发送HTML一样。 唯一的区别是您必须将页面的内容类型设置为text/xml。 要设置内容类型,请使用《%@page%》标记,如下所示 -
<%@ page contentType = "text/xml" %>
以下示例将说明如何将XML内容发送到浏览器 -
<%@ page contentType = "text/xml" %>
<books>
<book>
<name>Padam History</name>
<author>ZARA</author>
<price>100</price>
</book>
</books>
使用不同的浏览器访问上述XML,以查看上述XML的文档树表示。
在JSP中处理XML
在使用JSP继续进行XML处理之前,您需要将以下两个与XML和XPath相关的库复制到《Tomcat Installation Directory》\lib -
XercesImpl.jar - 从https://www.apache.org/dist/xerces/j/下载
xalan.jar - 从https://xml.apache.org/xalan-j/index.html下载
我们将以下内容放在books.xml文件中 -
<books>
<book>
<name>Padam History</name>
<author>ZARA</author>
<price>100</price>
</book>
<book>
<name>Great Mistry</name>
<author>NUHA</author>
<price>2000</price>
</book>
</books>
尝试以下main.jsp ,保持在同一目录中 -
<%@ taglib prefix = "c" uri="http://java.sun.com/jsp/jstl/core" %>
<%@ taglib prefix = "x" uri="http://java.sun.com/jsp/jstl/xml" %>
<html>
<head>
<title>JSTL x:parse Tags</title>
</head>
<body>
<h3>Books Info:</h3>
<c:import var = "bookInfo" url="http://localhost:8080/books.xml"/>
<x:parse xml = "${bookInfo}" var = "output"/>
<b>The title of the first book is</b>:
<x:out select = "$output/books/book[1]/name" />
<br>
<b>The price of the second book</b>:
<x:out select = "$output/books/book[2]/price" />
</body>
</html>
使用http://localhost:8080/main.jsp访问上面的JSP,将显示以下结果 -
<h3>Books Info:</h3>
<b class="notranslate">The title of the first book is</b>:Padam History
<b class="notranslate">The price of the second book</b>: 2000
使用JSP格式化XML
考虑以下XSLT样式表style.xsl -
<?xml version = "1.0"?>
<xsl:stylesheet xmlns:xsl = "http://www.w3.org/1999/XSL/Transform"
version = "1.0">
<xsl:output method = "html" indent = "yes"/>
<xsl:template match = "/">
<html>
<body>
<xsl:apply-templates/>
</body>
</html>
</xsl:template>
<xsl:template match = "books">
<table border = "1" width = "100%">
<xsl:for-each select = "book">
<tr>
<td>
<i><xsl:value-of select = "name"/></i>
</td>
<td>
<xsl:value-of select = "author"/>
</td>
<td>
<xsl:value-of select = "price"/>
</td>
</tr>
</xsl:for-each>
</table>
</xsl:template>
</xsl:stylesheet>
现在考虑以下JSP文件 -
<%@ taglib prefix = "c" uri = "http://java.sun.com/jsp/jstl/core" %>
<%@ taglib prefix = "x" uri = "http://java.sun.com/jsp/jstl/xml" %>
<html>
<head>
<title>JSTL x:transform Tags</title>
</head>
<body>
<h3>Books Info:</h3>
<c:set var = "xmltext">
<books>
<book>
<name>Padam History</name>
<author>ZARA</author>
<price>100</price>
</book>
<book>
<name>Great Mistry</name>
<author>NUHA</author>
<price>2000</price>
</book>
</books>
</c:set>
<c:import url = "http://localhost:8080/style.xsl" var = "xslt"/>
<x:transform xml = "${xmltext}" xslt = "${xslt}"/>
</body>
</html>
将显示以下结果 -
<h3>Books Info:</h3>
帕达姆历史 | ZARA | 100 |
伟大的Mistry | NUHA | 2000 |
要了解有关使用JSTL进行XML处理的更多信息,可以查看JSP标准标记库 。
JSP - JavaBeans
JavaBean是一个特殊构造的Java类,用Java编写并根据JavaBeans API规范进行编码。
以下是区分JavaBean与其他Java类的独特特征 -
它提供了一个默认的无参数构造函数。
它应该是可序列化的,并且可以实现Serializable接口。
它可能具有许多可以读取或写入的属性。
它可能具有许多属性的“ getter ”和“ setter ”方法。
JavaBeans属性
JavaBean属性是可由对象的用户访问的命名属性。 该属性可以是任何Java数据类型,包括您定义的类。
JavaBean属性可以是read, write, read only或write only 。 通过JavaBean的实现类中的两个方法访问JavaBean属性 -
S.No. | 方法和描述 |
---|---|
1 | 获取PropertyName () 例如,如果属性名称为firstName ,则您的方法名称将为getFirstName()以读取该属性。 此方法称为访问器。 |
2 | 设置PropertyName () 例如,如果属性名称为firstName ,则您的方法名称将为setFirstName()以写入该属性。 这种方法叫做mutator。 |
只读属性只有getPropertyName()方法,而只写属性只有setPropertyName()方法。
JavaBeans示例
考虑一个属性很少的学生班 -
package com.iowiki;
public class StudentsBean implements java.io.Serializable {
private String firstName = null;
private String lastName = null;
private int age = 0;
public StudentsBean() {
}
public String getFirstName(){
return firstName;
}
public String getLastName(){
return lastName;
}
public int getAge(){
return age;
}
public void setFirstName(String firstName){
this.firstName = firstName;
}
public void setLastName(String lastName){
this.lastName = lastName;
}
public void setAge(Integer age){
this.age = age;
}
}
访问JavaBeans
useBean操作声明了一个用于JSP的JavaBean。 声明之后,bean成为脚本变量,可以由JSP中使用的脚本元素和其他自定义标记访问。 useBean标记的完整语法如下 -
<jsp:useBean id = "bean's name" scope = "bean's scope" typeSpec/>
这里scope属性的值可以是application based您的要求的page, request, session或application based 。 id属性的值可以是任何值,只要它是同一JSP中其他useBean declarations中的唯一名称即可。
以下示例显示了如何使用useBean操作 -
<html>
<head>
<title>useBean Example</title>
</head>
<body>
<jsp:useBean id = "date" class = "java.util.Date" />
<p>The date/time is <%= date %>
</body>
</html>
您将收到以下结果 - -
The date/time is Thu Sep 30 11:18:11 GST 2010
访问JavaBeans属性
与《jsp:useBean...》操作一起,您可以使用《jsp:getProperty/》操作来访问get方法,使用《jsp:setProperty/》操作来访问set方法。 这是完整的语法 -
<jsp:useBean id = "id" class = "bean's class" scope = "bean's scope">
<jsp:setProperty name = "bean's id" property = "property name"
value = "value"/>
<jsp:getProperty name = "bean's id" property = "property name"/>
...........
</jsp:useBean>
name属性引用之前通过useBean操作引入JSP的JavaBean的id。 property属性是应该调用的get或set方法的名称。
以下示例显示了如何使用上述语法访问数据 -
<html>
<head>
<title>get and set properties Example</title>
</head>
<body>
<jsp:useBean id = "students" class = "com.iowiki.StudentsBean">
<jsp:setProperty name = "students" property = "firstName" value = "Zara"/>
<jsp:setProperty name = "students" property = "lastName" value = "Ali"/>
<jsp:setProperty name = "students" property = "age" value = "10"/>
</jsp:useBean>
<p>Student First Name:
<jsp:getProperty name = "students" property = "firstName"/>
</p>
<p>Student Last Name:
<jsp:getProperty name = "students" property = "lastName"/>
</p>
<p>Student Age:
<jsp:getProperty name = "students" property = "age"/>
</p>
</body>
</html>
让我们在CLASSPATH中使StudentsBean.class可用。 访问上面的JSP。 将显示以下结果 -
Student First Name: Zara
Student Last Name: Ali
Student Age: 10
JSP - Custom Tags
在本章中,我们将讨论JSP中的自定义标记。 自定义标记是用户定义的JSP语言元素。 当包含自定义标记的JSP页面被转换为servlet时,标记将转换为对称为标记处理程序的对象的操作。 然后Web容器在执行JSP页面的servlet时调用这些操作。
JSP标记扩展允许您创建可以直接插入JavaServer Page的新标记。 JSP 2.0规范引入了用于编写这些自定义标记的简单标记处理程序。
要编写自定义标记,只需扩展SimpleTagSupport类并覆盖doTag()方法,您可以在其中放置代码以生成标记的内容。
创建“Hello”标签
考虑您要定义名为
<ex:Hello />
要创建自定义JSP标记,必须首先创建充当标记处理程序的Java类。 现在让我们创建HelloTag类,如下所示 -
package com.iowiki;
import javax.servlet.jsp.tagext.*;
import javax.servlet.jsp.*;
import java.io.*;
public class HelloTag extends SimpleTagSupport {
public void doTag() throws JspException, IOException {
JspWriter out = getJspContext().getOut();
out.println("Hello Custom Tag!");
}
}
上面的代码有简单的编码,其中doTag()方法使用getJspContext()方法获取当前的JspContext对象,并使用它发送"Hello Custom Tag!" 到当前的JspWriter对象
让我们编译上面的类并将其复制到环境变量CLASSPATH中可用的目录中。 最后,创建以下标记库文件: 《Tomcat-Installation-Directory》webapps\ROOT\WEB-INF\custom.tld 。
<taglib>
<tlib-version>1.0</tlib-version>
<jsp-version>2.0</jsp-version>
<short-name>Example TLD</short-name>
<tag>
<name>Hello</name>
<tag-class>com.iowiki.HelloTag</tag-class>
<body-content>empty</body-content>
</tag>
</taglib>
现在让我们在JSP程序中使用上面定义的自定义标记Hello ,如下所示 -
<%@ taglib prefix = "ex" uri = "WEB-INF/custom.tld"%>
<html>
<head>
<title>A sample custom tag</title>
</head>
<body>
<ex:Hello/>
</body>
</html>
调用上面的JSP,这应该产生以下结果 -
Hello Custom Tag!
访问标记正文
您可以使用标准标记看到标记正文中的消息。 考虑您要定义名为《ex:Hello》的自定义标记,并且您希望以下列方式使用它 -
<ex:Hello>
This is message body
</ex:Hello>
让我们在上面的标记代码中进行以下更改以处理标记的正文 -
package com.iowiki;
import javax.servlet.jsp.tagext.*;
import javax.servlet.jsp.*;
import java.io.*;
public class HelloTag extends SimpleTagSupport {
StringWriter sw = new StringWriter();
public void doTag()
throws JspException, IOException {
getJspBody().invoke(sw);
getJspContext().getOut().println(sw.toString());
}
}
这里,调用产生的输出首先被捕获到StringWriter然后写入与标记关联的JspWriter。 我们需要更改TLD文件如下 -
<taglib>
<tlib-version>1.0</tlib-version>
<jsp-version>2.0</jsp-version>
<short-name>Example TLD with Body</short-name>
<tag>
<name>Hello</name>
<tag-class>com.iowiki.HelloTag</tag-class>
<body-content>scriptless</body-content>
</tag>
</taglib>
现在让我们用适当的身体调用上面的标签,如下所示 -
<%@ taglib prefix = "ex" uri = "WEB-INF/custom.tld"%>
<html>
<head>
<title>A sample custom tag</title>
</head>
<body>
<ex:Hello>
This is message body
</ex:Hello>
</body>
</html>
您将收到以下结果 -
This is message body
自定义标记属性
您可以将各种属性与自定义标记一起使用。 要接受属性值,自定义标记类需要实现setter方法,与JavaBean setter方法相同,如下所示 -
package com.iowiki;
import javax.servlet.jsp.tagext.*;
import javax.servlet.jsp.*;
import java.io.*;
public class HelloTag extends SimpleTagSupport {
private String message;
public void setMessage(String msg) {
this.message = msg;
}
StringWriter sw = new StringWriter();
public void doTag()
throws JspException, IOException {
if (message != null) {
/* Use message from attribute */
JspWriter out = getJspContext().getOut();
out.println( message );
} else {
/* use message from the body */
getJspBody().invoke(sw);
getJspContext().getOut().println(sw.toString());
}
}
}
属性的名称是"message" ,因此setter方法是setMessage() 。 现在让我们使用《attribute》元素在TLD文件中添加此属性,如下所示 -
<taglib>
<tlib-version>1.0</tlib-version>
<jsp-version>2.0</jsp-version>
<short-name>Example TLD with Body</short-name>
<tag>
<name>Hello</name>
<tag-class>com.iowiki.HelloTag</tag-class>
<body-content>scriptless</body-content>
<attribute>
<name>message</name>
</attribute>
</tag>
</taglib>
让我们按照下面的消息属性跟踪JSP -
<%@ taglib prefix = "ex" uri = "WEB-INF/custom.tld"%>
<html>
<head>
<title>A sample custom tag</title>
</head>
<body>
<ex:Hello message = "This is custom tag" />
</body>
</html>
这将产生以下结果 -
This is custom tag
考虑为属性包含以下属性 -
S.No. | 财产和目的 |
---|---|
1 | name name元素定义属性的名称。 每个属性名称对于特定标记必须是唯一的。 |
2 | required 这指定此属性是必需的还是可选的。 对于可选项,这将是错误的。 |
3 | rtexprvalue 声明标记属性的运行时表达式值是否有效 |
4 | type 定义此属性的Java类类型。 默认情况下,它被假定为String |
5 | description 可以提供信息描述。 |
6 | fragment 声明此属性值是否应被视为JspFragment 。 |
以下是指定与属性相关的属性的示例 -
.....
<attribute>
<name>attribute_name</name>
<required>false</required>
<type>java.util.Date</type>
<fragment>false</fragment>
</attribute>
.....
如果您使用两个属性,则可以按如下方式修改您的TLD -
.....
<attribute>
<name>attribute_name1</name>
<required>false</required>
<type>java.util.Boolean</type>
<fragment>false</fragment>
</attribute>
<attribute>
<name>attribute_name2</name>
<required>true</required>
<type>java.util.Date</type>
</attribute>
.....
JSP - Expression Language (EL)
JSP表达式语言(EL)使得可以轻松访问存储在JavaBeans组件中的应用程序数据。 JSP EL允许您创建表达式(a)算术和(b)逻辑。 在JSP EL表达式中,您可以使用integers, floating point numbers, strings, the built-in constants true and false表示布尔值,以及null。
简单的语法
通常,在JSP标记中指定属性值时,只需使用字符串即可。 例如 -
<jsp:setProperty name = "box" property = "perimeter" value = "100"/>
JSP EL允许您为任何这些属性值指定表达式。 JSP EL的简单语法如下 -
${expr}
这里expr指定表达式本身。 JSP EL中最常见的运算符是. 和[] 。 这两个运算符允许您访问Java Bean和内置JSP对象的各种属性。
例如,上面的语法《jsp:setProperty》标签可以用类似的表达式编写 -
<jsp:setProperty name = "box" property = "perimeter"
value = "${2*box.width+2*box.height}"/>
当JSP编译器在属性中看到${}表单时,它会生成用于计算表达式的代码并替代expresson的值。
您还可以在模板文本中使用JSP EL表达式作为标记。 例如, 《jsp:text》标记只是将其内容插入JSP的主体中。 以下《jsp:text》声明将《h1》Hello JSP!《/h1》插入到JSP输出中 -
<jsp:text>
<h1>Hello JSP!</h1>
</jsp:text>
现在,您可以在《jsp:text》标记(或任何其他标记)的主体中包含JSP EL表达式,并使用与属性相同的${}语法。 例如 -
<jsp:text>
Box Perimeter is: ${2*box.width + 2*box.height}
</jsp:text>
EL表达式可以使用括号对子表达式进行分组。 例如, ${(1 + 2) * 3} equals 9, but ${1 + (2 * 3)} equals 7 。
要停用EL表达式的评估,我们指定page指令的isELIgnored属性,如下所示 -
<%@ page isELIgnored = "true|false" %>
此属性的有效值为true和false。 如果为true,则EL表达式在静态文本或标记属性中出现时将被忽略。 如果为false,则由容器评估EL表达式。
EL中的基本操作符
JSP表达式语言(EL)支持Java支持的大多数算术和逻辑运算符。 下表列出了最常用的运算符 -
S.No. | 操作符和说明 |
---|---|
1 | . 访问bean属性或Map条目 |
2 | [] 访问数组或List元素 |
3 | ( ) 对子表达式进行分组以更改评估顺序 |
4 | + 加成 |
5 | - 减去或否定一个值 |
6 | * 乘法 |
7 | / or div 师 |
8 | % or mod Modulo(余数) |
9 | == or eq 测试平等 |
10 | != or ne 测试不平等 |
11 | 《 or lt 测试小于 |
12 | 》 or gt 测试大于 |
13 | 《= or le 测试小于或等于 |
14 | 》= or ge 测试大于或等于 |
15 | && or and 测试逻辑AND |
16 | || or or 测试逻辑OR |
17 | ! or not 一元布尔补 |
18 | empty 测试空变量值 |
JSP EL中的函数
JSP EL允许您在表达式中使用函数。 必须在自定义标记库中定义这些函数。 函数用法具有以下语法 -
${ns:func(param1, param2, ...)}
其中ns是函数的命名空间, func是func的名称, param1是第一个参数值。 例如,函数fn:length ,它是JSTL库的一部分。 此函数可用于获取字符串的长度,如下所示。
${fn:length("Get my length")}
要使用任何标记库(标准或自定义)中的函数,必须在服务器上安装该库,并且必须使用《taglib》指令将库包含在JSP中,如JSTL章节中所述。
JSP EL隐式对象
JSP表达式语言支持以下隐式对象 -
S.No | 隐含对象和描述 |
---|---|
1 | pageScope 来自页面范围的范围变量 |
2 | requestScope 来自请求范围的范围变量 |
3 | sessionScope 来自会话范围的范围变量 |
4 | applicationScope 来自应用范围的范围变量 |
5 | param 请求参数作为字符串 |
6 | paramValues 请求参数作为字符串的集合 |
7 | header HTTP请求标头为字符串 |
8 | headerValues HTTP请求标头作为字符串的集合 |
9 | initParam 上下文初始化参数 |
10 | cookie Cookie值 |
11 | pageContext 当前页面的JSP PageContext对象 |
您可以在表达式中使用这些对象,就好像它们是变量一样。 以下示例将帮助您理解概念 -
pageContext对象
pageContext对象使您可以访问pageContext JSP对象。 通过pageContext对象,您可以访问请求对象。 例如,要访问请求的传入查询字符串,可以使用以下表达式 -
${pageContext.request.queryString}
范围对象
pageScope, requestScope, sessionScope和applicationScope变量提供对存储在每个范围级别的变量的访问。
例如,如果需要在应用程序范围中显式访问box变量,则可以通过applicationScope变量作为applicationScope.box访问它。
param和paramValues对象
param和paramValues对象使您可以访问通常通过request.getParameter和request.getParameterValues方法获得的参数值。
例如,要访问名为order的参数,请使用表达式${param.order}或${param["order"]} 。
以下是访问名为username的请求参数的示例 -
<%@ page import = "java.io.*,java.util.*" %>
<%String title = "Accessing Request Param";%>
<html>
<head>
<title><% out.print(title); %></title>
</head>
<body>
<center>
<h1><% out.print(title); %></h1>
</center>
<div align = "center">
<p>${param["username"]}</p>
</div>
</body>
</html>
param对象返回单个字符串值,而paramValues对象返回字符串数组。
header和headerValues对象
header和headerValues对象使您可以访问通常通过request.getHeader和request.getHeaders方法获得的标头值。
例如,要访问名为user-agent的标头,请使用表达式${header.user-agent}或${header["user-agent"]} 。
以下是访问名为user-agent的头参数的示例 -
<%@ page import = "java.io.*,java.util.*" %>
<%String title = "User Agent Example";%>
<html>
<head>
<title><% out.print(title); %></title>
</head>
<body>
<center>
<h1><% out.print(title); %></h1>
</center>
<div align = "center">
<p>${header["user-agent"]}</p>
</div>
</body>
</html>
输出有点像以下 -
<h1>User Agent Example</h1>
<div align="center">
<p>Mozilla/4.0 (compatible; MSIE 8.0; Windows NT 6.1; WOW64; Trident/4.0;
SLCC2; .NET CLR 2.0.50727; .NET CLR 3.5.30729; .NET CLR 3.0.30729;
Media Center PC 6.0; HPNTDF; .NET4.0C; InfoPath.2)</p>
</div>
头对象返回单个字符串值,而headerValues对象返回字符串数组。
JSP - Exception Handling
在这一章当中。 我们将讨论如何在JSP中处理异常。 在编写JSP代码时,可能会在代码的任何部分发生编码错误。 您的JSP代码中可能会出现以下类型的错误 -
检查异常
已检查的异常是一个异常,通常是用户错误或程序员无法预见的问题。 例如,如果要打开文件,但找不到该文件,则会发生异常。 在编译时不能简单地忽略这些异常。
运行时异常
运行时异常是程序员可能已经避免的异常。 与已检查的异常相反,在编译时忽略运行时异常。
Errors
这些都不是例外,而是超出用户或程序员控制的问题。 代码中通常会忽略错误,因为您很少对错误做任何事情。 例如,如果发生堆栈溢出,则会出现错误。 它们在编译时也被忽略。
我们将进一步讨论在JSP代码中处理运行时异常/错误的方法。
使用异常对象
异常对象是Throwable的子类的实例(例如,java.lang。NullPointerException),并且仅在错误页面中可用。 下表列出了Throwable类中可用的重要方法。
S.No. | 方法和描述 |
---|---|
1 | public String getMessage() 返回有关已发生的异常的详细消息。 此消息在Throwable构造函数中初始化。 |
2 | public Throwable getCause() 返回由Throwable对象表示的异常的原因。 |
3 | public String toString() 返回与getMessage()结果连接的类的名称。 |
4 | public void printStackTrace() 将toString()的结果与堆栈跟踪一起打印到System.err (错误输出流)。 |
5 | public StackTraceElement [] getStackTrace() 返回包含堆栈跟踪上每个元素的数组。 索引0处的元素表示调用堆栈的顶部,而数组中的最后一个元素表示调用堆栈底部的方法。 |
6 | public Throwable fillInStackTrace() 使用当前堆栈跟踪填充此Throwable对象的堆栈跟踪,添加堆栈跟踪中的任何先前信息。 |
JSP为您提供了为每个JSP指定Error Page的选项。 每当页面抛出异常时,JSP容器都会自动调用错误页面。
以下是为main.jsp指定错误页面的示例。 要设置错误页面,请使用《%@ page errorPage = "xxx" %》指令。
<%@ page errorPage = "ShowError.jsp" %>
<html>
<head>
<title>Error Handling Example</title>
</head>
<body>
<%
// Throw an exception to invoke the error page
int x = 1;
if (x == 1) {
throw new RuntimeException("Error condition!!!");
}
%>
</body>
</html>
我们现在将编写一个错误处理JSP ShowError.jsp,如下所示。 请注意,错误处理页面包含指令《%@ page isErrorPage = "true" %》 。 该指令使JSP编译器生成异常实例变量。
<%@ page isErrorPage = "true" %>
<html>
<head>
<title>Show Error Page</title>
</head>
<body>
<h1>Opps...</h1>
<p>Sorry, an error occurred.</p>
<p>Here is the exception stack trace: </p>
<pre><% exception.printStackTrace(response.getWriter()); %></pre>
</body>
</html>
访问main.jsp ,您将收到类似以下的输出 -
java.lang.RuntimeException: Error condition!!!
......
Opps...
Sorry, an error occurred.
Here is the exception stack trace:
使用JSTL标记进行错误页面
您可以使用JSTL标记来编写错误页面ShowError.jsp 。 此页面具有与上例相同的逻辑,具有更好的结构和更多信息 -
<%@ taglib prefix = "c" uri = "http://java.sun.com/jsp/jstl/core" %>
<%@page isErrorPage = "true" %>
<html>
<head>
<title>Show Error Page</title>
</head>
<body>
<h1>Opps...</h1>
<table width = "100%" border = "1">
<tr valign = "top">
<td width = "40%"><b>Error:</b></td>
<td>${pageContext.exception}</td>
</tr>
<tr valign = "top">
<td><b>URI:</b></td>
<td>${pageContext.errorData.requestURI}</td>
</tr>
<tr valign = "top">
<td><b>Status code:</b></td>
<td>${pageContext.errorData.statusCode}</td>
</tr>
<tr valign = "top">
<td><b>Stack trace:</b></td>
<td>
<c:forEach var = "trace"
items = "${pageContext.exception.stackTrace}">
<p>${trace}</p>
</c:forEach>
</td>
</tr>
</table>
</body>
</html>
访问main.jsp,将生成以下内容 -
<h1>Opps...</h1>
Error: | java.lang.RuntimeException:错误条件!!! |
URI: | /main.jsp |
Status code: | 500 |
Stack trace: |
org.apache.jsp.main_jsp._jspService(main_jsp.java:65) org.apache.jasper.runtime.HttpJspBase.service(HttpJspBase.java:68) javax.servlet.http.HttpServlet.service(HttpServlet.java:722) org.apache.jasper.servlet.JspServlet.service(JspServlet.java:265) javax.servlet.http.HttpServlet.service(HttpServlet.java:722) |
使用Try ... Catch Block
如果您想在同一页面中处理错误并想要采取某些操作而不是触发错误页面,则可以使用try....catch块。
下面是一个简单的例子,展示了如何使用try ... catch块。 我们将以下代码放在main.jsp中 -
<html>
<head>
<title>Try...Catch Example</title>
</head>
<body>
<%
try {
int i = 1;
i = i/0;
out.println("The answer is " + i);
}
catch (Exception e) {
out.println("An exception occurred: " + e.getMessage());
}
%>
</body>
</html>
访问main.jsp,它应该生成一个类似于以下的输出 -
An exception occurred:/by zero
JSP - Debugging
在本章中,我们将讨论调试JSP。 测试/调试JSP和servlet总是很困难。 JSP和Servlet往往涉及大量的客户端/服务器交互,使得错误可能但很难重现。
以下是一些可能有助于您进行调试的提示和建议。
Using System.out.println()
System.out.println()很容易用作标记来测试某段代码是否正在执行。 我们也可以打印出变量值。 考虑以下附加点 -
由于System对象是核心Java对象的一部分,因此可以在任何地方使用它,而无需安装任何额外的类。 这包括Servlets, JSP, RMI, EJB's, ordinary Beans和classes以及standalone applications 。
与在断点处停止相比,写入System.out不会干扰应用程序的正常执行流程,这使得当iming至关重要时非常有价值。
以下是使用System.out.println()的语法 -
System.out.println("Debugging message");
以下示例显示如何使用System.out.print() -
<%@taglib prefix = "c" uri = "http://java.sun.com/jsp/jstl/core" %>
<html>
<head><title>System.out.println</title></head>
<body>
<c:forEach var = "counter" begin = "1" end = "10" step = "1" >
<c:out value = "${counter-5}"/></br>
<% System.out.println( "counter = " + pageContext.findAttribute("counter") ); %>
</c:forEach>
</body>
</html>
访问上面的JSP,浏览器将显示以下结果 -
-4
-3
-2
-1
0
1
2
3
4
5
如果您使用的是Tomcat,则还会在logs目录中的stdout.log末尾添加这些行。
counter = 1
counter = 2
counter = 3
counter = 4
counter = 5
counter = 6
counter = 7
counter = 8
counter = 9
counter = 10
这样,您可以将变量和其他信息放入系统日志中,可以对其进行分析以找出问题的根本原因或出于各种其他原因。
使用JDB记录器
J2SE日志记录框架旨在为在JVM中运行的任何类提供日志记录服务。 我们可以利用这个框架来记录任何信息。
让我们使用JDK logger API重写上面的例子 -
<%@taglib prefix = "c" uri = "http://java.sun.com/jsp/jstl/core" %>
<%@page import = "java.util.logging.Logger" %>
<html>
<head><title>Logger.info</title></head>
<body>
<% Logger logger = Logger.getLogger(this.getClass().getName());%>
<c:forEach var = "counter" begin = "1" end = "10" step = "1" >
<c:set var = "myCount" value = "${counter-5}" />
<c:out value = "${myCount}"/></br>
<% String message = "counter = "
+ pageContext.findAttribute("counter") + "myCount = "
+ pageContext.findAttribute("myCount");
logger.info( message );
%>
</c:forEach>
</body>
</html>
上面的代码将在浏览器和stdout.log中生成类似的结果,但您将在stdout.log获得其他信息。 我们将使用记录器的info方法,因为记录消息只是为了提供信息。 以下是stdout.log文件的快照 -
24-Sep-2010 23:31:31 org.apache.jsp.main_jsp _jspService
INFO: counter = 1 myCount = -4
24-Sep-2010 23:31:31 org.apache.jsp.main_jsp _jspService
INFO: counter = 2 myCount = -3
24-Sep-2010 23:31:31 org.apache.jsp.main_jsp _jspService
INFO: counter = 3 myCount = -2
24-Sep-2010 23:31:31 org.apache.jsp.main_jsp _jspService
INFO: counter = 4 myCount = -1
24-Sep-2010 23:31:31 org.apache.jsp.main_jsp _jspService
INFO: counter = 5 myCount = 0
24-Sep-2010 23:31:31 org.apache.jsp.main_jsp _jspService
INFO: counter = 6 myCount = 1
24-Sep-2010 23:31:31 org.apache.jsp.main_jsp _jspService
INFO: counter = 7 myCount = 2
24-Sep-2010 23:31:31 org.apache.jsp.main_jsp _jspService
INFO: counter = 8 myCount = 3
24-Sep-2010 23:31:31 org.apache.jsp.main_jsp _jspService
INFO: counter = 9 myCount = 4
24-Sep-2010 23:31:31 org.apache.jsp.main_jsp _jspService
INFO: counter = 10 myCount = 5
可以使用便捷函数severe(), warning(), info(), config(), fine(), finer(),和finest()在各个级别发送消息。 这里finest()方法可用于记录最精细的信息,而severe()方法可用于记录严重信息。
您可以使用Log4J Framework根据其严重性级别和重要性在不同文件中记录消息。
调试工具
NetBeans是一个免费的开源Java集成开发环境,支持开发支持JSP和servlet规范的独立Java应用程序和Web应用程序,并且还包括JSP调试器。
NetBeans支持以下基本调试功能 -
- Breakpoints
- 单步执行代码
- Watchpoints
您可以参考NetBeans documentation以了解上述调试功能。
使用JDB调试器
您可以使用用于调试applet或应用程序的相同jdb命令来调试JSP和servlet。
要调试JSP或servlet,可以调试sun.servlet.http.HttpServer ,然后观察HttpServer执行JSP/servlet以响应我们从浏览器发出的HTTP请求。 这与applet的调试方式非常相似。 不同之处在于,对于applet,正在调试的实际程序是sun.applet.AppletViewer 。
大多数调试器通过自动知道如何调试applet来隐藏这个细节。 在他们对JSP执行相同操作之前,您必须通过考虑以下内容来帮助您的调试器 -
设置调试器的类路径。 这有助于您找到sun.servlet.http.Http-Server和相关的类。
设置调试器的类路径。 这有助于您找到JSP和支持类,通常是ROOT\WEB-INF\classes 。
设置正确的类路径后,开始调试sun.servlet.http.HttpServer 。 您可以在您想要调试的任何JSP中设置断点,然后使用Web浏览器向HttpServer请求给定的JSP (http://localhost:8080/JSPToDebug) 。 此处的执行在断点处停止。
使用评论
代码中的注释可以通过各种方式帮助调试过程。 在调试过程中,可以通过许多其他方式使用注释。
JSP使用Java注释, single line (// ...)和multiple line (/* ... */)注释可用于临时删除部分Java代码。 如果错误消失,请仔细查看您刚评论的代码并找出问题所在。
客户端和服务器标头
有时,当JSP没有按预期运行时,查看原始HTTP请求和响应很有用。 如果您熟悉HTTP的结构,则可以阅读请求和响应,并了解这些标头的确切内容。
重要的调试技巧
以下列出了一些关于JSP调试的更多调试技巧 -
请求浏览器显示其正在显示的页面的原始内容。 这有助于识别格式问题。 它通常是“视图”菜单下的一个选项。
通过强制完全重新加载页面,确保浏览器不缓存先前请求的输出。 使用Netscape Navigator ,使用Shift-Reload ; 使用Internet Explorer Shift-Refresh使用Shift-Refresh 。
JSP - Security
JavaServer Pages和servlet为Web开发人员提供了几种机制来保护应用程序。 通过在应用程序部署描述符中标识资源并为其分配角色,以声明方式保护资源。
提供多种级别的身份验证,从使用标识符和密码的基本身份验证到使用证书的复杂身份验证。
角色认证
servlet规范中的身份验证机制使用称为role-based security的技术。 我们的想法是,不是在用户级别限制资源,而是创建角色并按角色限制资源。
您可以在文件tomcat-users.xml定义不同的角色,该文件位于conf的Tomcat主目录之外。 此文件的示例如下所示 -
<?xml version = '1.0' encoding = 'utf-8'?>
<tomcat-users>
<role rolename = "tomcat"/>
<role rolename = "role1"/>
<role rolename = "manager"/>
<role rolename = "admin"/>
<user username = "tomcat" password = "tomcat" roles = "tomcat"/>
<user username = "role1" password = "tomcat" roles = "role1"/>
<user username = "both" password = "tomcat" roles = "tomcat,role1"/>
<user username = "admin" password = "secret" roles = "admin,manager"/>
</tomcat-users>
此文件定义username, password和role之间的简单映射。 请注意,给定用户可能有多个角色; 例如, username = "both"是“tomcat”角色和“role1”角色。
一旦确定并定义了不同的角色,就可以使用WEB-INF目录中提供的web.xml文件中的《security-constraint》元素,将基于角色的安全性限制放在不同的Web应用程序资源上。
以下是web.xml中的示例条目 -
<web-app>
...
<security-constraint>
<web-resource-collection>
<web-resource-name>SecuredBookSite</web-resource-name>
<url-pattern>/secured/*</url-pattern>
<http-method>GET</http-method>
<http-method>POST</http-method>
</web-resource-collection>
<auth-constraint>
<description>
Let only managers use this app
</description>
<role-name>manager</role-name>
</auth-constraint>
</security-constraint>
<security-role>
<role-name>manager</role-name>
</security-role>
<login-config>
<auth-method>BASIC</auth-method>
</login-config>
...
</web-app>
以上条目意味着 -
对/ secured/*匹配的URL的任何HTTP GET或POST请求都受安全限制的约束。
具有经理角色的人员可以访问受保护的资源。
login-config元素用于描述BASIC形式的身份验证。
如果您尝试浏览任何URL(包括/security目录),将显示以下对话框,询问用户名和密码。 如果您向用户提供"admin"和密码"secrer" ,那么您将访问与/secured/*匹配的URL,因为我们已将用户admin定义为允许访问此资源的manager角色。
基于表单的认证
使用FORM身份验证方法时,必须提供登录表单以提示用户输入用户名和密码。 以下是login.jsp的简单代码。 这有助于为同一目的创建表单 -
<html>
<body bgcolor = "#ffffff">
<form method = "POST" action ="j_security_check">
<table border = "0">
<tr>
<td>Login</td>
<td><input type = "text" name="j_username"></td>
</tr>
<tr>
<td>Password</td>
<td><input type = "password" name="j_password"></td>
</tr>
</table>
<input type = "submit" value = "Login!">
</form>
</body>
</html>
在这里,您必须确保登录表单必须包含名为j_username和j_password的表单元素。 《form》标记中的操作必须是j_security_check 。 POST必须用作表单方法。 同时,您必须修改《login-config》标记以将auth-method指定为FORM -
<web-app>
...
<security-constraint>
<web-resource-collection>
<web-resource-name>SecuredBookSite</web-resource-name>
<url-pattern>/secured/*</url-pattern>
<http-method>GET</http-method>
<http-method>POST</http-method>
</web-resource-collection>
<auth-constraint>
<description>Let only managers use this app</description>
<role-name>manager</role-name>
</auth-constraint>
</security-constraint>
<security-role>
<role-name>manager</role-name>
</security-role>
<login-config>
<auth-method>FORM</auth-method>
<form-login-config>
<form-login-page>/login.jsp</form-login-page>
<form-error-page>/error.jsp</form-error-page>
</form-login-config>
</login-config>
...
</web-app>
现在,当您尝试使用URL /secured/*访问任何资源时,它将显示上述表单,询问用户ID和密码。 当容器看到“ j_security_check ”操作时,它使用一些内部机制来验证调用者。
如果登录成功并且调用者被授权访问安全资源,则容器使用session-id从该点开始为调用者标识登录会话。 容器使用包含session-id的cookie维护登录会话。 服务器将cookie发送回客户端,只要调用者将此cookie与后续请求一起呈现,容器就会知道调用者是谁。
如果登录失败,则服务器将返回由form-error-page设置标识的页面
这里, j_security_check是使用基于表单的登录的应用程序必须为登录表单指定的操作。 在相同的表单中,您还应该有一个名为j_username的文本输入控件和一个名为j_username的password input control 。 当您看到这一点时,表示表单中包含的信息将提交给服务器,服务器将检查名称和密码。 如何做到这一点是服务器特定的。
检查标准领域实现以了解j_security_check如何为Tomcat容器工作。
Servlet/JSP中的编程安全性
HttpServletRequest对象提供以下方法,可用于在运行时挖掘安全信息 -
S.No. | 方法和描述 |
---|---|
1 | String getAuthType() getAuthType()方法返回一个String对象,该对象表示用于保护Servlet的身份验证方案的名称。 |
2 | boolean isUserInRole(java.lang.String role) isUserInRole()方法返回一个布尔值:如果用户处于给定角色,则返回true;否则返回false。 |
3 | String getProtocol() getProtocol()方法返回一个String对象,表示用于发送请求的协议。 可以检查该值以确定是否使用了安全协议。 |
4 | boolean isSecure() isSecure()方法返回一个布尔值,表示请求是否是使用HTTPS生成的。 值为true表示它是,并且连接是安全的。 值false表示请求不是。 |
5 | Principle getUserPrinciple() getUserPrinciple()方法返回一个java.security.Principle对象,该对象包含当前经过身份验证的用户的名称。 |
例如,对于链接到管理器页面的JavaServer Page,您可能具有以下代码 -
<% if (request.isUserInRole("manager")) { %>
<a href = "managers/mgrreport.jsp">Manager Report</a>
<a href = "managers/personnel.jsp">Personnel Records</a>
<% } %>
通过检查用户在JSP或servlet中的角色,您可以自定义网页以仅向用户显示她可以访问的项目。 如果您需要在身份验证表单中输入的用户名,则可以在请求对象中调用getRemoteUser方法。
JSP - Internationalization| i18n| l10n
在本章中,我们将讨论JSP中的国际化概念。 在我们开始之前,让我们了解以下三个重要术语 -
Internationalization (i18n) - 这意味着使网站能够提供翻译成访问者语言或国籍的不同版本的内容。
Localization (l10n) - 这意味着向网站添加资源以使其适应特定的地理或文化区域,例如印地语翻译到网站。
locale - 这是一个特定的文化或地理区域。 它通常被称为语言符号,后跟国家符号,由下划线分隔。 例如,“ en_US ”表示美国的英语语言环境。
在建立全球网站时,应该注意许多项目。 本教程不会向您提供有关此内容的完整详细信息,但它将为您提供一个很好的示例,说明如何通过区分其位置(即区域设置)将您的网页以不同语言提供给Internet社区。
JSP可以根据请求者的语言环境选择适当的站点版本,并根据本地语言,文化和要求提供适当的站点版本。 以下是返回Locale对象的请求对象的方法。
java.util.Locale request.getLocale()
检测区域设置
以下是重要的区域设置方法,您可以使用它们来检测requester's location, language和当前locale 。 以下所有方法都显示请求者浏览器中设置的国家名称和语言名称。
S.No. | 方法和描述 |
---|---|
1 | String getCountry() 此方法以ISO 3166 2字母格式为此区域设置返回大写的国家/地区代码。 |
2 | String getDisplayCountry() 此方法返回适合显示给用户的区域设置国家/地区的名称。 |
3 | String getLanguage() 此方法以ISO 639格式为此语言环境返回小写的语言代码。 |
4 | String getDisplayLanguage() 此方法返回适合显示给用户的语言环境语言的名称。 |
5 | String getISO3Country() 此方法返回此区域设置国家/地区的三个字母缩写。 |
6 | String getISO3Language() 此方法返回此语言环境语言的三个字母缩写。 |
例子 (Example)
以下示例显示如何在JSP中显示请求的语言和关联国家/地区 -
<%@ page import = "java.io.*,java.util.Locale" %>
<%@ page import = "javax.servlet.*,javax.servlet.http.* "%>
<%
//Get the client's Locale
Locale locale = request.getLocale();
String language = locale.getLanguage();
String country = locale.getCountry();
%>
<html>
<head>
<title>Detecting Locale</title>
</head>
<body>
<center>
<h1>Detecting Locale</h1>
</center>
<p align = "center">
<%
out.println("Language : " + language + "<br />");
out.println("Country : " + country + "<br />");
%>
</p>
</body>
</html>
语言设置
JSP可以输出用西欧语言编写的页面,如英语,西班牙语,德语,法语,意大利语,荷兰语等。这里设置Content-Language标题以正确显示所有字符非常重要。
另一个重点是使用HTML实体显示所有特殊字符; 例如, "ñ" 代表"ñ"和"¡" 代表"¡"如下 -
<%@ page import = "java.io.*,java.util.Locale" %>
<%@ page import = "javax.servlet.*,javax.servlet.http.* "%>
<%
// Set response content type
response.setContentType("text/html");
// Set spanish language code.
response.setHeader("Content-Language", "es");
String title = "En Español";
%>
<html>
<head>
<title><% out.print(title); %></title>
</head>
<body>
<center>
<h1><% out.print(title); %></h1>
</center>
<div align = "center">
<p>En Español</p>
<p>¡Hola Mundo!</p>
</div>
</body>
</html>
区域特定日期
您可以使用java.text.DateFormat类及其静态getDateTimeInstance( )方法来格式化特定于语言环境的日期和时间。 以下示例显示了如何格式化特定于给定语言环境的日期 -
<%@ page import = "java.io.*,java.util.Locale" %>
<%@ page import = "javax.servlet.*,javax.servlet.http.* "%>
<%@ page import = "java.text.DateFormat,java.util.Date" %>
<%
String title = "Locale Specific Dates";
//Get the client's Locale
Locale locale = request.getLocale( );
String date = DateFormat.getDateTimeInstance(
DateFormat.FULL,
DateFormat.SHORT,
locale).format(new Date( ));
%>
<html>
<head>
<title><% out.print(title); %></title>
</head>
<body>
<center>
<h1><% out.print(title); %></h1>
</center>
<div align = "center">
<p>Local Date: <% out.print(date); %></p>
</div>
</body>
</html>
区域特定货币
您可以使用java.txt.NumberFormat类及其静态getCurrencyInstance( )方法在特定于语言环境的curreny中格式化数字,例如long或double类型。 以下是显示如何格式化给定区域设置的货币的示例 -
<%@ page import = "java.io.*,java.util.Locale" %>
<%@ page import = "javax.servlet.*,javax.servlet.http.* "%>
<%@ page import = "java.text.NumberFormat,java.util.Date" %>
<%
String title = "Locale Specific Currency";
//Get the client's Locale
Locale locale = request.getLocale( );
NumberFormat nft = NumberFormat.getCurrencyInstance(locale);
String formattedCurr = nft.format(1000000);
%>
<html>
<head>
<title><% out.print(title); %></title>
</head>
<body>
<center>
<h1><% out.print(title); %></h1>
</center>
<div align = "center">
<p>Formatted Currency: <% out.print(formattedCurr); %></p>
</div>
</body>
</html>
区域特定百分比
您可以使用java.txt.NumberFormat类及其静态getPercentInstance( )方法来获取特定于语言环境的百分比。 以下示例显示如何格式化特定于给定语言环境的百分比 -
<%@ page import = "java.io.*,java.util.Locale" %>
<%@ page import = "javax.servlet.*,javax.servlet.http.* "%>
<%@ page import = "java.text.NumberFormat,java.util.Date" %>
<%
String title = "Locale Specific Percentage";
//Get the client's Locale
Locale locale = request.getLocale( );
NumberFormat nft = NumberFormat.getPercentInstance(locale);
String formattedPerc = nft.format(0.51);
%>
<html>
<head>
<title><% out.print(title); %></title>
</head>
<body>
<center>
<h1><% out.print(title); %></h1>
</center>
<div align = "center">
<p>Formatted Percentage: <% out.print(formattedPerc); %></p>
</div>
</body>
</html>