常见指令与功能介绍-java之JSP学习第二天(非原创)

文章大纲

一、JSP 指令
二、JSP 动作元素
三、JSP 隐式对象
四、JSP 客户端请求
五、JSP 服务器响应
六、JSP HTTP 状态码
七、JSP 表单处理
八、JSP 过滤器
九、JSP Cookie 处理
十、JSP Session
十一、JSP 日期处理
十二、JSP 页面重定向
十三、JSP 点击量统计
十四、JSP 自动刷新
十五、学习资料下载
十六、参考文章

一、JSP 指令

JSP指令用来设置整个JSP页面相关的属性,如网页的编码方式和脚本语言。
语法格式如下:

<%@ directive attribute="value" %>

指令可以有很多个属性,它们以键值对的形式存在,并用逗号隔开。
JSP中的三种指令标签:

1. Page指令

Page指令为容器提供当前页面的使用说明。一个JSP页面可以包含多个page指令。
Page指令的语法格式:

<%@ page attribute="value" %>

等价的XML格式:

<jsp:directive.page attribute="value" />

属性
下表列出与Page指令相关的属性:

2. Include指令

JSP可以通过include指令来包含其他文件。被包含的文件可以是JSP文件、HTML文件或文本文件。包含的文件就好像是该JSP文件的一部分,会被同时编译执行。
Include指令的语法格式如下:

<%@ include file="文件相对 url 地址" %>

include 指令中的文件名实际上是一个相对的 URL 地址。
如果您没有给文件关联一个路径,JSP编译器默认在当前路径下寻找。
等价的XML语法:

<jsp:directive.include file="文件相对 url 地址" />

3. Taglib指令

JSP API允许用户自定义标签,一个自定义标签库就是自定义标签的集合。
Taglib指令引入一个自定义标签集合的定义,包括库路径、自定义标签。
Taglib指令的语法:

<%@ taglib uri="uri" prefix="prefixOfTag" %>

uri属性确定标签库的位置,prefix属性指定标签库的前缀。
等价的XML语法:

<jsp:directive.taglib uri="uri" prefix="prefixOfTag" />

二、JSP 动作元素

与JSP指令元素不同的是,JSP动作元素在请求处理阶段起作用。JSP动作元素是用XML语法写成的。
利用JSP动作可以动态地插入文件、重用JavaBean组件、把用户重定向到另外的页面、为Java插件生成HTML代码。
动作元素只有一种语法,它符合XML标准:

<jsp:action_name attribute="value" />

动作元素基本上都是预定义的函数,JSP规范定义了一系列的标准动作,它用JSP作为前缀,可用的标准动作元素如下:

常见的属性
所有的动作要素都有两个属性:id属性和scope属性。
id属性:
id属性是动作元素的唯一标识,可以在JSP页面中引用。动作元素创建的id值可以通过PageContext来调用。
scope属性:
该属性用于识别动作元素的生命周期。 id属性和scope属性有直接关系,scope属性定义了相关联id对象的寿命。 scope属性有四个可能的值: (a) page, (b)request, (c)session, 和 (d) application。

1. <jsp:include>动作元素

<jsp:include>动作元素用来包含静态和动态的文件。该动作把指定文件插入正在生成的页面。语法格式如下:

<jsp:include page="相对 URL 地址" flush="true" />

前面已经介绍过include指令,它是在JSP文件被转换成Servlet的时候引入文件,而这里的jsp:include动作不同,插入文件的时间是在页面被请求的时候。
以下是include动作相关的属性列表。

1.1 实例
以下我们定义了两个文件 date.jsp 和 main.jsp,代码如下所示:
date.jsp文件代码:

<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<p>
   今天的日期是: <%= (new java.util.Date()).toLocaleString()%>
</p>

main.jsp文件代码:

<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>菜鸟教程(runoob.com)</title>
</head>
<body>

<h2>include 动作实例</h2>
<jsp:include page="date.jsp" flush="true" />

</body>
</html>

现在将以上两个文件放在服务器的根目录下,访问main.jsp文件。显示结果如下:
include 动作实例

今天的日期是: 2016-6-25 14:08:17

2. <jsp:useBean>动作元素

jsp:useBean 动作用来加载一个将在JSP页面中使用的JavaBean。
这个功能非常有用,因为它使得我们可以发挥 Java 组件复用的优势。
jsp:useBean动作最简单的语法为:

<jsp:useBean id="name" class="package.class" />

在类载入后,我们既可以通过 jsp:setProperty 和 jsp:getProperty 动作来修改和检索bean的属性。
以下是useBean动作相关的属性列表。

3. <jsp:setProperty>动作元素

jsp:setProperty用来设置已经实例化的Bean对象的属性,有两种用法。首先,你可以在jsp:useBean元素的外面(后面)使用jsp:setProperty,如下所示:

<jsp:useBean id="myName" />
<jsp:setProperty name="myName" property="someProperty" />

此时,不管jsp:useBean是找到了一个现有的Bean,还是新创建了一个Bean实例,jsp:setProperty都会执行。第二种用法是把jsp:setProperty放入jsp:useBean元素的内部,如下所示:

<jsp:useBean id="myName" >
   <jsp:setProperty name="myName" property="someProperty"/>
</jsp:useBean>

此时,jsp:setProperty只有在新建Bean实例时才会执行,如果是使用现有实例则不执行jsp:setProperty。
jsp:setProperty动作有下面四个属性,如下表:

4. <jsp:getProperty>动作元素

jsp:getProperty动作提取指定Bean属性的值,转换成字符串,然后输出。语法格式如下:

<jsp:useBean id="myName"  />
<jsp:getProperty name="myName" property="someProperty" />

下表是与getProperty相关联的属性:

实例
以下实例我们使用了Bean:

package com.runoob.main;

public class TestBean {
   private String message = "菜鸟教程";
 
   public String getMessage() {
      return(message);
   }
   public void setMessage(String message) {
      this.message = message;
   }
}

编译以上实例文件 TestBean.java :

$ javac TestBean.java

编译完成后会在当前目录下生成一个 TestBean.class 文件, 将该文件拷贝至当前 JSP 项目的 WebContent/WEB-INF/classes/com/runoob/main 下( com/runoob/main 包路径,没有需要手动创建)。
下面是一个 Eclipse 中目录结构图:

下面是一个很简单的例子,它的功能是装载一个Bean,然后设置/读取它的message属性。
现在让我们在main.jsp文件中调用该Bean:

<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>菜鸟教程(runoob.com)</title>
</head>
<body>

<h2>Jsp 使用 JavaBean 实例</h2>
<jsp:useBean id="test" class="com.runoob.main.TestBean" />
 
<jsp:setProperty name="test" 
                    property="message" 
                    value="菜鸟教程..." />
 
<p>输出信息....</p>
 
<jsp:getProperty name="test" property="message" />

</body>
</html>

浏览器访问,执行以上文件,输出如下所示:

5. <jsp:forward> 动作元素

jsp:forward动作把请求转到另外的页面。jsp:forward标记只有一个属性page。语法格式如下所示:

<jsp:forward page="相对 URL 地址" />

以下是forward相关联的属性:

实例
以下实例我们使用了两个文件,分别是: date.jsp 和 main.jsp。
date.jsp 文件代码如下:

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

<h2>forward 动作实例</h2>
<jsp:forward page="date.jsp" />
</body>
</html>

现在将以上两个文件放在服务器的根目录下,访问main.jsp文件。显示结果如下:

今天的日期是: 2016-6-25 14:37:25

6. <jsp:plugin>动作元素

jsp:plugin动作用来根据浏览器的类型,插入通过Java插件 运行Java Applet所必需的OBJECT或EMBED元素。
如果需要的插件不存在,它会下载插件,然后执行Java组件。 Java组件可以是一个applet或一个JavaBean。
plugin动作有多个对应HTML元素的属性用于格式化Java 组件。param元素可用于向Applet 或 Bean 传递参数。
以下是使用plugin 动作元素的典型实例:

<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>

如果你有兴趣可以尝试使用applet来测试jsp:plugin动作元素,<fallback>元素是一个新元素,在组件出现故障的错误时发送给用户错误信息。

7. <jsp:element> 、 <jsp:attribute>、 <jsp:body>动作元素

<jsp:element> 、 <jsp:attribute>、 <jsp:body>动作元素动态定义XML元素。动态是非常重要的,这就意味着XML元素在编译时是动态生成的而非静态。
以下实例动态定义了XML元素:

<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>菜鸟教程(runoob.com)</title>
</head>
<body>
<jsp:element name="xmlElement">
<jsp:attribute name="xmlElementAttr">
   属性值
</jsp:attribute>
<jsp:body>
   XML 元素的主体
</jsp:body>
</jsp:element>
</body>
</html>

浏览器访问以下页面,输出结果如下所示:

三、JSP 隐式对象

JSP隐式对象是JSP容器为每个页面提供的Java对象,开发者可以直接使用它们而不用显式声明。JSP隐式对象也被称为预定义变量。
JSP所支持的九大隐式对象:

1. request对象

request对象是javax.servlet.http.HttpServletRequest 类的实例。每当客户端请求一个JSP页面时,JSP引擎就会制造一个新的request对象来代表这个请求。
request对象提供了一系列方法来获取HTTP头信息,cookies,HTTP方法等等。

2. response对象

response对象是javax.servlet.http.HttpServletResponse类的实例。当服务器创建request对象时会同时创建用于响应这个客户端的response对象。
response对象也定义了处理HTTP头模块的接口。通过这个对象,开发者们可以添加新的cookies,时间戳,HTTP状态码等等。

3. out对象

out对象是 javax.servlet.jsp.JspWriter 类的实例,用来在response对象中写入内容。
最初的JspWriter类对象根据页面是否有缓存来进行不同的实例化操作。可以在page指令中使用buffered='false'属性来轻松关闭缓存。
JspWriter类包含了大部分java.io.PrintWriter类中的方法。不过,JspWriter新增了一些专为处理缓存而设计的方法。还有就是,JspWriter类会抛出IOExceptions异常,而PrintWriter不会。
下表列出了我们将会用来输出boolean,char,int,double,String,object等类型数据的重要方法:

4. session对象

session对象是 javax.servlet.http.HttpSession 类的实例。和Java Servlets中的session对象有一样的行为。
session对象用来跟踪在各个客户端请求间的会话。

5. application对象

application对象直接包装了servlet的ServletContext类的对象,是javax.servlet.ServletContext 类的实例。
这个对象在JSP页面的整个生命周期中都代表着这个JSP页面。这个对象在JSP页面初始化时被创建,随着jspDestroy()方法的调用而被移除。
通过向application中添加属性,则所有组成您web应用的JSP文件都能访问到这些属性。

6. config对象

config对象是 javax.servlet.ServletConfig 类的实例,直接包装了servlet的ServletConfig类的对象。
这个对象允许开发者访问Servlet或者JSP引擎的初始化参数,比如文件路径等。
以下是config对象的使用方法,不是很重要,所以不常用:

config.getServletName();

它返回包含在<servlet-name>元素中的servlet名字,注意,<servlet-name>元素在 WEB-INF\web.xml 文件中定义。

7. pageContext 对象

pageContext对象是javax.servlet.jsp.PageContext 类的实例,用来代表整个JSP页面。
这个对象主要用来访问页面信息,同时过滤掉大部分实现细节。
这个对象存储了request对象和response对象的引用。application对象,config对象,session对象,out对象可以通过访问这个对象的属性来导出。
pageContext对象也包含了传给JSP页面的指令信息,包括缓存信息,ErrorPage URL,页面scope等。
PageContext类定义了一些字段,包括PAGE_SCOPE,REQUEST_SCOPE,SESSION_SCOPE, APPLICATION_SCOPE。它也提供了40余种方法,有一半继承自javax.servlet.jsp.JspContext 类。
其中一个重要的方法就是removeArribute(),它可接受一个或两个参数。比如,pageContext.removeArribute("attrName")移除四个scope中相关属性,但是下面这种方法只移除特定scope中的相关属性:
pageContext.removeAttribute("attrName", PAGE_SCOPE);

8. page 对象

这个对象就是页面实例的引用。它可以被看做是整个JSP页面的代表。
page 对象就是this对象的同义词。

9. exception 对象

exception 对象包装了从先前页面中抛出的异常信息。它通常被用来产生对出错条件的适当响应。

四、JSP 客户端请求

当浏览器请求一个网页时,它会向网络服务器发送一系列不能被直接读取的信息,因为这些信息是作为HTTP信息头的一部分来传送的。您可以查阅HTTP协议来获得更多的信息。
下表列出了浏览器端信息头的一些重要内容,在以后的网络编程中将会经常见到这些信息:

1. HttpServletRequest类

request对象是javax.servlet.http.HttpServletRequest类的实例。每当客户端请求一个页面时,JSP引擎就会产生一个新的对象来代表这个请求。
request对象提供了一系列方法来获取HTTP信息头,包括表单数据,cookies,HTTP方法等等。
接下来将会介绍一些在JSP编程中常用的获取HTTP信息头的方法。详细内容请见下表:

2. HTTP信息头示例

在这个例子中,我们会使用HttpServletRequest类的getHeaderNames()方法来读取HTTP信息头。这个方法以枚举的形式返回当前HTTP请求的头信息。
获取Enumeration对象后,用标准的方式来遍历Enumeration对象,用hasMoreElements()方法来确定什么时候停止,用nextElement()方法来获得每个参数的名字。

<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<%@ page import="java.io.*,java.util.*" %>
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>菜鸟教程(runoob.com)</title>
</head>
<body>
<h2>HTTP 头部请求实例</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>
</body>
</html>

访问main.jsp,将会得到以下结果:

五、JSP 服务器响应

Response响应对象主要将JSP容器处理后的结果传回到客户端。可以通过response变量设置HTTP的状态和向客户端发送数据,如Cookie、HTTP文件头信息等。
一个典型的响应看起来就像下面这样:


HTTP/1.1 200 OK
Content-Type: text/html
Header2: 
HeaderN: 
  (空行)
<!doctype >
<html>
<head></head>
<body>
</body>
</html>

状态行包含HTTP版本信息,比如HTTP/1.1,一个状态码,比如200,还有一个非常短的信息对应着状态码,比如OK。
下表摘要出了HTTP1.1响应头中最有用的部分,在网络编程中您将会经常见到它们:

1. HttpServletResponse类

response 对象是 javax.servlet.http.HttpServletResponse 类的一个实例。就像服务器会创建request对象一样,它也会创建一个客户端响应。
response对象定义了处理创建HTTP信息头的接口。通过使用这个对象,开发者们可以添加新的cookie或时间戳,还有HTTP状态码等等。
下表列出了用来设置HTTP响应头的方法,这些方法由HttpServletResponse 类提供:

2. HTTP响应头程序示例

接下来的例子使用setIntHeader()方法和setRefreshHeader()方法来模拟一个数字时钟:

<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<%@ page import="java.io.*,java.util.*" %>
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>菜鸟教程(runoob.com)</title>
</head>
<body>
<h2>自动刷新实例</h2>
<%
   // 设置每隔5秒自动刷新
   response.setIntHeader("Refresh", 5);
   // 获取当前时间
   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("当前时间: " + CT + "\n");
%>
</body>
</html>

将以上代码保存为main.jsp,然后通过浏览器访问它。它将会每隔5秒显示一下系统当前时间。
我们可以看下以下 Gif 演示图:

六、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版本,一个状态码,和状态码相对应的短消息。
下表列出了可能会从服务器返回的HTTP状态码和与之关联的消息:

1. 设置HTTP状态码的方法

下表列出了HttpServletResponse 类中用来设置状态码的方法:

2. HTTP状态码程序示例

接下来的例子将会发送407错误码给浏览器,然后浏览器将会告诉您"Need authentication!!!"。

<html>
<head>
<title>Setting HTTP Status Code</title>
</head>
<body>
<%
   // 设置错误代码,并说明原因
   response.sendError(407, "Need authentication!!!" );
%>
</body>
</html>

访问以上JSP页面,将会得到以下结果:

七、JSP 表单处理

我们在浏览网页的时候,经常需要向服务器提交信息,并让后台程序处理。浏览器中使用 GET 和 POST 方法向服务器提交数据。

1. GET 方法

GET方法将请求的编码信息添加在网址后面,网址与编码信息通过"?"号分隔。如下所示:

http://www.runoob.com/hello?key1=value1&key2=value2

GET方法是浏览器默认传递参数的方法,一些敏感信息,如密码等建议不使用GET方法。
用get时,传输数据的大小有限制 (注意不是参数的个数有限制),最大为1024字节。

2. POST 方法

一些敏感信息,如密码等我们可以通过POST方法传递,POST提交数据是隐式的。
POST提交数据是不可见的,GET是通过在url里面传递的(可以看一下你浏览器的地址栏)。
JSP使用getParameter()来获得传递的参数,getInputStream()方法用来处理客户端的二进制数据流的请求。

3. JSP 读取表单数据

getParameter(): 使用 request.getParameter() 方法来获取表单参数的值。
getParameterValues(): 获得如checkbox类(名字相同,但值有多个)的数据。 接收数组变量 ,如checkbox类型
getParameterNames():该方法可以取得所有变量的名称,该方法返回一个Emumeration。
getInputStream():调用此方法来读取来自客户端的二进制数据流。

4. 使用URL的 GET 方法实例

以下是一个简单的URL,并使用GET方法来传递URL中的参数:
http://localhost:8080/testjsp/main.jsp?name=菜鸟教程&url=http://ww.runoob.com
testjsp 为项目地址。
以下是 main.jsp 文件的JSP程序用于处理客户端提交的表单数据,我们使用getParameter()方法来获取提交的数据:

<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<%@ page import="java.io.*,java.util.*" %>
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>菜鸟教程(runoob.com)</title>
</head>
<body>
<h1>使用 GET 方法读取数据</h1>
<ul>
<li><p><b>站点名:</b>
   <%= request.getParameter("name")%>
</p></li>
<li><p><b>网址:</b>
   <%= request.getParameter("url")%>
</p></li>
</ul>
</body>
</html>

接下来我们通过浏览器访问 http://localhost:8080/testjsp/main.jsp?name=菜鸟教程&url=http://ww.runoob.com 输出结果如下所示:

5. 使用表单的 GET 方法实例

以下是一个简单的 HTML 表单,该表单通过GET方法将客户端数据提交 到 main.jsp 文件中:

<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>菜鸟教程(runoob.com)</title>
</head>
<body>

<form action="main.jsp" method="GET">
站点名: <input type="text" name="name">
<br />
网址: <input type="text" name="url" />
<input type="submit" value="提交" />
</form>

</body>
</html>

将以上HTML代码保存到test.htm文件中。 将该文件放置于当前jsp项目的 WebContent 目录下(与 main.jsp 同一个目录)。
通过访问 http://localhost:8080/testjsp/test.html 提交表单数据到 main.jsp 文件,演示 Gif 图如下所示:

6. 使用表单的 POST 方法实例

接下来让我们使用POST方法来传递表单数据,修改main.jsp与Hello.htm文件代码,如下所示:
main.jsp文件代码:

<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<%@ page import="java.io.*,java.util.*" %>
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>菜鸟教程(runoob.com)</title>
</head>
<body>
<h1>使用 POST 方法读取数据</h1>
<ul>
<li><p><b>站点名:</b>
<%
// 解决中文乱码的问题
String name = new String((request.getParameter("name")).getBytes("ISO-8859-1"),"UTF-8");
%>
   <%=name%>
</p></li>
<li><p><b>网址:</b>
   <%= request.getParameter("url")%>
</p></li>
</ul>
</body>
</html>
代码中我们使用 new String((request.getParameter("name")).getBytes("ISO-8859-1"),"UTF-8")来转换编码,防止中文乱码的发生。
以下是test.htm修改后的代码:
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>菜鸟教程(runoob.com)</title>
</head>
<body>

<form action="main.jsp" method="POST">
站点名: <input type="text" name="name">
<br />
网址: <input type="text" name="url" />
<input type="submit" value="提交" />
</form>

</body>
</html>

通过访问 http://localhost:8080/testjsp/test.html 提交表单数据到 main.jsp 文件,演示 Gif 图如下所示:

7. 传递 Checkbox 数据到JSP程序

复选框 checkbox 可以传递一个甚至多个数据。
以下是一个简单的HTML代码,并将代码保存在test.htm文件中:

<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>菜鸟教程(runoob.com)</title>
</head>
<body>

<form action="main.jsp" method="POST" target="_blank">
<input type="checkbox" name="google" checked="checked" /> Google
<input type="checkbox" name="runoob"  /> 菜鸟教程
<input type="checkbox" name="taobao" checked="checked" /> 
                                                淘宝
<input type="submit" value="选择网站" />
</form>

</body>
</html>
以上代码在浏览器访问如下所示:
以下为main.jsp文件代码,用于处理复选框数据:
<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<%@ page import="java.io.*,java.util.*" %>
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>菜鸟教程(runoob.com)</title>
</head>
<body>
<h1>从复选框中读取数据</h1>
<ul>
<li><p><b>Google 是否选中:</b>
   <%= request.getParameter("google")%>
</p></li>
<li><p><b>菜鸟教程是否选中:</b>
   <%= request.getParameter("runoob")%>
</p></li>
<li><p><b>淘宝是否选中:</b>
   <%= request.getParameter("taobao")%>
</p></li>
</ul>
</body>
</html>

通过访问 http://localhost:8080/testjsp/test.html 提交表单数据到 main.jsp 文件,演示 Gif 图如下所示:

8. 读取所有表单参数

以下我们将使用 HttpServletRequest 的 getParameterNames() 来读取所有表单参数,该方法可以取得所有变量的名称,该方法返回一个枚举。
一旦我们有了一个 Enumeration(枚举),我们就可以调用 hasMoreElements() 方法来确定是否还有元素,以及使用nextElement()方法来获得每个参数的名称。

<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<%@ page import="java.io.*,java.util.*" %>
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>菜鸟教程(runoob.com)</title>
</head>
<body>
<h1>读取所有表单参数</h1>
<table width="100%" border="1" align="center">
<tr bgcolor="#949494">
<th>参数名</th><th>参数值</th>
</tr>
<%
   Enumeration paramNames = request.getParameterNames();

   while(paramNames.hasMoreElements()) {
      String paramName = (String)paramNames.nextElement();
      out.print("<tr><td>" + paramName + "</td>\n");
      String paramValue = request.getParameter(paramName);
      out.println("<td> " + paramValue + "</td></tr>\n");
   }
%>
</table>
</body>
</html>

以下是test.htm文件的内容:

<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>菜鸟教程(runoob.com)</title>
</head>
<body>

<form action="main.jsp" method="POST" target="_blank">
<input type="checkbox" name="google" checked="checked" /> Google
<input type="checkbox" name="runoob"  /> 菜鸟教程
<input type="checkbox" name="taobao" checked="checked" /> 
                                                淘宝
<input type="submit" value="选择网站" />
</form>

</body>
</html>

现在我们通过浏览器访问 test.htm 文件提交数据,输出结果如下:
通过访问 http://localhost:8080/testjsp/test.html 提交表单数据到 main.jsp 文件,演示 Gif 图如下所示:

八、JSP 过滤器

JSP 和 Servlet 中的过滤器都是 Java 类。
过滤器可以动态地拦截请求和响应,以变换或使用包含在请求或响应中的信息。
可以将一个或多个过滤器附加到一个 Servlet 或一组 Servlet。过滤器也可以附加到 JavaServer Pages (JSP) 文件和 HTML 页面。
过滤器是可用于 Servlet 编程的 Java 类,可以实现以下目的:
在客户端的请求访问后端资源之前,拦截这些请求。
在服务器的响应发送回客户端之前,处理这些响应。
根据规范建议的各种类型的过滤器:
身份验证过滤器(Authentication Filters)。
数据压缩过滤器(Data compression Filters)。
加密过滤器(Encryption Filters)。
触发资源访问事件过滤器。
图像转换过滤器(Image Conversion Filters)。
日志记录和审核过滤器(Logging and Auditing Filters)。
MIME-TYPE 链过滤器(MIME-TYPE Chain Filters)。
标记化过滤器(Tokenizing Filters)。
XSL/T 过滤器(XSL/T Filters),转换 XML 内容。
过滤器通过 Web 部署描述符(web.xml)中的 XML 标签来声明,然后映射到您的应用程序的部署描述符中的 Servlet 名称或 URL 模式。
当 Web 容器启动 Web 应用程序时,它会为您在部署描述符中声明的每一个过滤器创建一个实例。
Filter的执行顺序与在web.xml配置文件中的配置顺序一致,一般把Filter配置在所有的Servlet之前。

1. Servlet 过滤器方法

过滤器是一个实现了 javax.servlet.Filter 接口的 Java 类。javax.servlet.Filter 接口定义了三个方法:

2. FilterConfig 使用

Filter 的 init 方法中提供了一个 FilterConfig 对象。
如 web.xml 文件配置如下:

<filter>
    <filter-name>LoginFilter</filter-name>
    <filter-class>com.runoob.test.LogFilter</filter-class>
    <init-param>
        <param-name>Site</param-name>
        <param-value>菜鸟教程</param-value>
    </init-param>
    </filter>

在 init 方法使用 FilterConfig 对象获取参数:

public void  init(FilterConfig config) throws ServletException {
    // 获取初始化参数
    String site = config.getInitParameter("Site"); 
    // 输出初始化参数
    System.out.println("网站名称: " + site); 
}

3. web.xml配置各节点说明

<filter>指定一个过滤器。
<filter-name>用于为过滤器指定一个名字,该元素的内容不能为空。
<filter-class>元素用于指定过滤器的完整的限定类名。
<init-param>元素用于为过滤器指定初始化参数,它的子元素<param-name>指定参数的名字,<param-value>指定参数的值。
在过滤器中,可以使用FilterConfig接口对象来访问初始化参数。
<filter-mapping>元素用于设置一个 Filter 所负责拦截的资源。一个Filter拦截的资源可通过两种方式来指定:Servlet 名称和资源访问的请求路径
<filter-name>子元素用于设置filter的注册名称。该值必须是在<filter>元素中声明过的过滤器的名字
<url-pattern>设置 filter 所拦截的请求路径(过滤器关联的URL样式)
<servlet-name>指定过滤器所拦截的Servlet名称。
<dispatcher>指定过滤器所拦截的资源被 Servlet 容器调用的方式,可以是REQUEST,INCLUDE,FORWARD和ERROR之一,默认REQUEST。用户可以设置多个<dispatcher>子元素用来指定 Filter 对资源的多种调用方式进行拦截。
<dispatcher>子元素可以设置的值及其意义
REQUEST:当用户直接访问页面时,Web容器将会调用过滤器。如果目标资源是通过RequestDispatcher的include()或forward()方法访问时,那么该过滤器就不会被调用。
INCLUDE:如果目标资源是通过RequestDispatcher的include()方法访问时,那么该过滤器将被调用。除此之外,该过滤器不会被调用。
FORWARD:如果目标资源是通过RequestDispatcher的forward()方法访问时,那么该过滤器将被调用,除此之外,该过滤器不会被调用。
ERROR:如果目标资源是通过声明式异常处理机制调用时,那么该过滤器将被调用。除此之外,过滤器不会被调用。

九、JSP Cookie 处理

Cookie是存储在客户机的文本文件,它们保存了大量轨迹信息。在servlet技术基础上,JSP显然能够提供对HTTP cookie的支持。
通常有三个步骤来识别回头客:
服务器脚本发送一系列cookie至浏览器。比如名字,年龄,ID号码等等。
浏览器在本地机中存储这些信息,以备不时之需。
当下一次浏览器发送任何请求至服务器时,它会同时将这些cookie信息发送给服务器,然后服务器使用这些信息来识别用户或者干些其它事情。
本章节将会传授您如何去设置或重设cookie的方法,还有如何访问它们及如何删除它们。
JSP Cookie 处理需要对中文进行编码与解码,方法如下:

String   str   =   java.net.URLEncoder.encode("中文","UTF-8");            //编码
String   str   =   java.net.URLDecoder.decode("编码后的字符串","UTF-8");   // 解码

1. Cookie 剖析

Cookie通常在HTTP信息头中设置(虽然JavaScript能够直接在浏览器中设置cookie)。在JSP中,设置一个cookie需要发送如下的信息头给服务器:
HTTP/1.1 200 OK
Date: Fri, 04 Feb 2015 21:03:38 GMT
Server: Apache/1.3.9 (UNIX) PHP/4.0b3
Set-Cookie: name=runoob; expires=Friday, 04-Feb-07 22:03:38 GMT;
path=/; domain=runoob.com
Connection: close
Content-Type: text/html
正如您所见,Set-Cookie信息头包含一个键值对,一个GMT(格林尼治标准)时间,一个路径,一个域名。键值对会被编码为URL。有效期域是个指令,告诉浏览器在什么时候之后就可以清除这个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对象的数组。

2. Servlet Cookie 方法

下表列出了Cookie对象中常用的方法:

3. 使用JSP设置Cookie

使用JSP设置cookie包含三个步骤:
(1)创建一个Cookie对象: 调用Cookie的构造函数,使用一个cookie名称和值做参数,它们都是字符串。

Cookie cookie = new Cookie("key","value");

请务必牢记,名称和值中都不能包含空格或者如下的字符:

[ ] ( ) = , " / ? @ : ;

(2) 设置有效期:调用setMaxAge()函数表明cookie在多长时间(以秒为单位)内有效。下面的操作将有效期设为了24小时。

cookie.setMaxAge(60*60*24); 

(3) 将cookie发送至HTTP响应头中:调用response.addCookie()函数来向HTTP响应头中添加cookie。

response.addCookie(cookie);

4. 实例演示

main.jsp 文件代码如下所示:

<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<%@ page import="java.net.*" %>
<%
   // 编码,解决中文乱码   
   String str = URLEncoder.encode(request.getParameter("name"),"utf-8");  
   // 设置 name 和 url cookie 
   Cookie name = new Cookie("name",
           str);
   Cookie url = new Cookie("url",
              request.getParameter("url"));

   // 设置cookie过期时间为24小时。
   name.setMaxAge(60*60*24); 
   url.setMaxAge(60*60*24); 

   // 在响应头部添加cookie
   response.addCookie( name );
   response.addCookie( url );
%>
<html>
<head>
<title>设置 Cookie</title>
</head>
<body>

<h1>设置 Cookie</h1>
`
<ul>
<li><p><b>网站名:</b>
   <%= request.getParameter("name")%>
</p></li>
<li><p><b>网址:</b>
   <%= request.getParameter("url")%>
</p></li>
</ul>
</body>
</html>
以下是一个简单的 HTML 表单通过GET方法将客户端数据提交到 main.jsp 文件中,并设置 cookie:
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>菜鸟教程(runoob.com)</title>
</head>
<body>

<form action="main.jsp" method=GET>
站点名: <input type="text" name="name">
<br />
网址: <input type="text" name="url" />
<input type="submit" value="提交" />
</form>

</body>
</html>

将以上HTML代码保存到test.htm文件中。
将该文件放置于当前jsp项目的 WebContent 目录下(与 main.jsp 同一个目录)。
通过访问 http://localhost:8080/testjsp/test.html 提交表单数据到 main.jsp 文件,演示 Gif 图如下所示:

5. 使用 JSP 读取 Cookie

想要读取cookie,您就需要调用request.getCookies()方法来获得一个javax.servlet.http.Cookie对象的数组,然后遍历这个数组,使用getName()方法和getValue()方法来获取每一个cookie的名称和值。
<h3实例演示< h3="" style="color: rgb(51, 51, 51); font-family: "Helvetica Neue", Helvetica, "PingFang SC", "Hiragino Sans GB", "Microsoft YaHei", "Noto Sans CJK SC", "WenQuanYi Micro Hei", Arial, sans-serif; font-size: 12px; font-style: normal; font-variant-ligatures: normal; font-variant-caps: normal; font-weight: normal; letter-spacing: normal; orphans: 2; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; widows: 2; word-spacing: 0px; -webkit-text-stroke-width: 0px; background-color: rgb(255, 255, 255);">
让我们来读取上个例子中的cookie, 以下为 cookie.jsp 文件代码:

<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<%@ page import="java.net.*" %>
<!DOCTYPE html>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>获取 Cookie</title>
</head>
<body>
<%
   Cookie cookie = null;
   Cookie[] cookies = null;
   // 获取cookies的数据,是一个数组
   cookies = request.getCookies();
   if( cookies != null ){
      out.println("<h2> 查找 Cookie 名与值</h2>");
      for (int i = 0; i < cookies.length; i++){
         cookie = cookies[i];
        
         out.print("参数名 : " + cookie.getName());
         out.print("<br>");
         out.print("参数值: " + URLDecoder.decode(cookie.getValue(), "utf-8") +" <br>");
         out.print("------------------------------------<br>");
      }
  }else{
      out.println("<h2>没有发现 Cookie</h2>");
  }
%>
</body>
</html>

浏览器访问后,输出结果为:

6. 使用JSP删除Cookie

删除cookie非常简单。如果您想要删除一个cookie,按照下面给的步骤来做就行了:
获取一个已经存在的cookie然后存储在Cookie对象中。
将cookie的有效期设置为0。
将这个cookie重新添加进响应头中。

实例演示
下面的程序删除一个名为"name"的cookie,当您第二次运行cookie.jsp时,name 将会为 null。

<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<%@ page import="java.net.*" %>
<!DOCTYPE html>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>获取 Cookie</title>
</head>
<body>
<%
   Cookie cookie = null;
   Cookie[] cookies = null;
   // 获取当前域名下的cookies,是一个数组
   cookies = request.getCookies();
   if( cookies != null ){
      out.println("<h2> 查找 Cookie 名与值</h2>");
      for (int i = 0; i < cookies.length; i++){
         cookie = cookies[i];
         if((cookie.getName( )).compareTo("name") == 0 ){
            cookie.setMaxAge(0);
            response.addCookie(cookie);
            out.print("删除 Cookie: " + 
            cookie.getName( ) + "<br/>");
         }
         out.print("参数名 : " + cookie.getName());
         out.print("<br>");
         out.print("参数值: " + URLDecoder.decode(cookie.getValue(), "utf-8") +" <br>");
         out.print("------------------------------------<br>");
      }
  }else{
      out.println("<h2>没有发现 Cookie</h2>");
  }
%>
</body>
</html>

通过浏览器访问,输出结果为:

再次访问 http://localhost:8080/testjsp/cookie.jsp,将会得到如下结果:

可以看到名为"name" 的 cookie 已经不见了。
您也可以手动在浏览器中删除 cookie。IE 浏览器通过点击Tools菜单项,然后选择Internet Options,点击 Delete Cookies,就能删除所有 cookie 。

十、JSP Session

HTTP是无状态协议,这意味着每次客户端检索网页时,都要单独打开一个服务器连接,因此服务器不会记录下先前客户端请求的任何信息。
有三种方法来维持客户端与服务器的会话:

1. Cookies

网络服务器可以指定一个唯一的session ID作为cookie来代表每个客户端,用来识别这个客户端接下来的请求。
这可能不是一种有效的方式,因为很多时候浏览器并不一定支持cookie,所以我们不建议使用这种方法来维持会话。

2. 隐藏表单域

一个网络服务器可以发送一个隐藏的HTML表单域和一个唯一的session ID,就像下面这样:

<input type="hidden" name="sessionid" value="12345">

这个条目意味着,当表单被提交时,指定的名称和值将会自动包含在GET或POST数据中。每当浏览器发送一个请求,session_id的值就可以用来保存不同浏览器的轨迹。
这种方式可能是一种有效的方式,但点击<A HREF>标签中的超链接时不会产生表单提交事件,因此隐藏表单域也不支持通用会话跟踪。

3. 重写URL

您可以在每个URL后面添加一些额外的数据来区分会话,服务器能够根据这些数据来关联session标识符。
举例来说,http://w3cschool.cc/file.htm;sessionid=12345, session标识符为sessionid=12345,服务器可以用这个数据来识别客户端。
相比而言,重写URL是更好的方式来,就算浏览器不支持cookies也能工作,但缺点是您必须为每个URL动态指定session ID,就算这是个简单的HTML页面。

4. session对象

除了以上几种方法外,JSP利用servlet提供的HttpSession接口来识别一个用户,存储这个用户的所有访问信息。
默认情况下,JSP允许会话跟踪,一个新的HttpSession对象将会自动地为新的客户端实例化。禁止会话跟踪需要显式地关掉它,通过将page指令中session属性值设为false来实现,就像下面这样:

<%@ page session="false" %>

JSP引擎将隐含的session对象暴露给开发者。由于提供了session对象,开发者就可以方便地存储或检索数据。
下表列出了session对象的一些重要方法:

5. JSP Session应用

这个例子描述了如何使用HttpSession对象来获取创建时间和最后一次访问时间。我们将会为request对象关联一个新的session对象,如果这个对象尚未存在的话。

<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<%@ page import="java.io.*,java.util.*" %>
<%
   // 获取session创建时间
   Date createTime = new Date(session.getCreationTime());
   // 获取最后访问页面的时间
   Date lastAccessTime = new Date(session.getLastAccessedTime());

   String title = "再次访问菜鸟教程实例";
   Integer visitCount = new Integer(0);
   String visitCountKey = new String("visitCount");
   String userIDKey = new String("userID");
   String userID = new String("ABCD");

   // 检测网页是否由新的访问用户
   if (session.isNew()){
      title = "访问菜鸟教程实例";
      session.setAttribute(userIDKey, userID);
      session.setAttribute(visitCountKey,  visitCount);
   } else {
       visitCount = (Integer)session.getAttribute(visitCountKey);
       visitCount += 1;
       userID = (String)session.getAttribute(userIDKey);
       session.setAttribute(visitCountKey,  visitCount);
   }
%>
<html>
<head>
<title>Session 跟踪</title>
</head>
<body>

<h1>Session 跟踪</h1>

<table border="1" align="center"> 
<tr bgcolor="#949494">
   <th>Session 信息</th>
   <th>值</th>
</tr> 
<tr>
   <td>id</td>
   <td><% out.print( session.getId()); %></td>
</tr> 
<tr>
   <td>创建时间</td>
   <td><% out.print(createTime); %></td>
</tr> 
<tr>
   <td>最后访问时间</td>
   <td><% out.print(lastAccessTime); %></td>
</tr> 
<tr>
   <td>用户 ID</td>
   <td><% out.print(userID); %></td>
</tr> 
<tr>
   <td>访问次数</td>
   <td><% out.print(visitCount); %></td>
</tr> 
</table> 
</body>
</html>

试着访问 http://localhost:8080/testjsp/main.jsp ,第一次运行时将会得到如下结果:

再次访问,将会得到如下结果:

6. 删除Session数据

当处理完一个用户的会话数据后,您可以有如下选择:
移除一个特定的属性:
调用public void removeAttribute(String name) 方法来移除指定的属性。
删除整个会话:
调用public void invalidate() 方法来使整个session无效。
设置会话有效期:
调用 public void setMaxInactiveInterval(int interval) 方法来设置session超时。
登出用户:
支持servlet2.4版本的服务器,可以调用 logout()方法来登出用户,并且使所有相关的session无效。
配置web.xml文件:
如果使用的是Tomcat,可以向下面这样配置web.xml文件:

  <session-config>
    <session-timeout>15</session-timeout>
  </session-config>

超时以分钟为单位,Tomcat中的默认的超时时间是30分钟。
Servlet中的getMaxInactiveInterval( ) 方法以秒为单位返回超时时间。如果在web.xml中配置的是15分钟,则getMaxInactiveInterval( ) 方法将会返回900。

十一、JSP 日期处理

使用JSP最重要的优势之一,就是可以使用所有Java API。本章将会详细地讲述Java中的Date类,它在java.util包下,封装了当前日期和时间。
Date类有两个构造函数。第一个构造函数使用当前日期和时间来初始化对象。
Date( )
第二个构造函数接受一个参数,这个参数表示从1970年1月1日凌晨至所要表示时间的毫秒数。
Date(long millisec)
获取Date对象后,您就能够使用下表列出的所有方法:

1. 获取当前日期和时间

使用JSP编程可以很容易的获取当前日期和时间,只要使用Date对象的toString()方法就行了,就像下面这样:

<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<%@ page import="java.io.*,java.util.*, javax.servlet.*" %>
<html>
<head>
<title>显示当前时间与日期</title>
</head>
<body>

<h1>显示当前时间与日期</h1>

<%
   Date date = new Date();
   out.print( "<h2 align=\"center\">" +date.toString()+"</h2>");
%>
</body>
</html>

将上面的代码保存在 main.jsp 文件中,然后访问 http://localhost:8080/testjsp/main.jsp,运行结果如下:
显示当前时间与日期

Sat Jun 25 17:54:34 CST 2016

刷新 http://localhost:8080/testjsp/main.jsp,就可以发现每次刷新所得到的秒数都不相同。

2. 日期比较

就像我在开头所提到的,您可以在JSP脚本中使用任何Java方法。如果您想要比较两个日期,
可以参照下面的方法来做:
使用getTime()方法得到毫秒数,然后比较毫秒数就行了。
使用before(),after(),equals()方法。比如,new Date(99,2,12).before(new Date(99,2,18))返回true。
使用compareTo()方法,这个方法在Comparable接口中定义,在Date中实现。

3. 使用SimpleDateFormat格式化日期

SimpleDateFormat使用一种地区敏感的方式来格式化和解析日期,它允许您使用自定义的模式来格式化日期和时间。
对CurrentDate.jsp稍作修改,得到如下修改后的代码:

<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<%@ page import="java.io.*,java.util.*" %>
<%@ page import="javax.servlet.*,java.text.*" %>
<html>
<head>
<title>显示当前时间与日期</title>
</head>
<body>

<h1>显示当前时间与日期</h1>

<%
   Date dNow = new Date( );
   SimpleDateFormat ft = 
   new SimpleDateFormat ("yyyy-MM-dd HH:mm:ss");
   out.print( "<h2 align=\"center\">" + ft.format(dNow) + "</h2>");
%>

</body>
</html>

再次编译 main.jsp,然后访问 http://localhost:8080/testjsp/main.jsp,就可以得到如下结果:
显示当前时间与日期

2016-06-25 17:57:53

4. SimpleDateFormat格式码

要指定模式字符串,需要使用下表列出的格式码:

十二、JSP 页面重定向

当需要将文档移动到一个新的位置时,就需要使用JSP重定向了。
最简单的重定向方式就是使用response对象的sendRedirect()方法。这个方法的签名如下:
public void response.sendRedirect(String location)
throws IOException
这个方法将状态码和新的页面位置作为响应发回给浏览器。您也可以使用setStatus()和setHeader()方法来得到同样的效果:

....
String site = "http://www.runoob.com" ;
response.setStatus(response.SC_MOVED_TEMPORARILY);
response.setHeader("Location", site); 
....

实例演示
这个例子表明了JSP如何进行页面重定向:

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

    pageEncoding="UTF-8"%>

<%@page import="java.io.*,java.util.*" %>

<html>

<html>

<head>

<title>页面重定向</title>

</head>

<body>

<h1>页面重定向</h1>

<%

   // 重定向到新地址

   Stringsite = new String("http://www.runoob.com");

   response.setStatus(response.SC_MOVED_TEMPORARILY);

   response.setHeader("Location", site); 

%>

</body>

</html>

将以上代码保存在PageRedirecting.jsp文件中,然后访问http://localhost:8080/PageRedirect.jsp,它将会把您带至http://www.runoob.com/

十三、JSP 点击量统计

有时候我们需要知道某个页面被访问的次数,这时我们就需要在页面上添加页面统计器,页面访问的统计一般在用户第一次载入时累加该页面的访问数上。
要实现一个计数器,您可以利用应用程序隐式对象和相关方法getAttribute()和setAttribute()来实现。
这个对象表示JSP页面的整个生命周期中。当JSP页面初始化时创建此对象,当JSP页面调用jspDestroy()时删除该对象。
以下是在应用中创建变量的语法:

application.setAttribute(String Key, Object Value);

您可以使用上述方法来设置一个计数器变量及更新该变量的值。读取该变量的方法如下:

application.getAttribute(String Key);

在页面每次被访问时,你可以读取计数器的当前值,并递增1,然后重新设置,在下一个用户访问时就将新的值显示在页面上。

1. 实例演示

该实例将介绍如何使用JSP来计算特定页面访问的总人数。如果你要计算你网站使用页面的总点击量,那么你就必须将该代码放在所有的JSP页面上。

<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<%@ page import="java.io.*,java.util.*" %>
<html>
<html>
<head>
<title>访问量统计</title>
</head>
<body>
<%
    Integer hitsCount = 
      (Integer)application.getAttribute("hitCounter");
    if( hitsCount ==null || hitsCount == 0 ){
       /* 第一次访问 */
       out.println("欢迎访问菜鸟教程!");
       hitsCount = 1;
    }else{
       /* 返回访问值 */
       out.println("欢迎再次访问菜鸟教程!");
       hitsCount += 1;
    }
    application.setAttribute("hitCounter", hitsCount);
%>

<p>页面访问量为: <%= hitsCount%></p>

</body>
</html>

现在我们将上面的代码放置于main.jsp文件上,并访问http://localhost:8080/testjsp/main.jsp文件。你会看到页面会生成个计数器,在我们每次刷新页面时,计数器都会发生变化(每次刷新增加1)。
你也可以通过不同的浏览器访问,计数器会在每次访问后增加1。如下所示:

2. 复位计数器

使用以上方法,在 web 服务器重启后,计数器会被复位为 0,即前面保留的数据都会消失,你可以使用以下几种方式解决该问题:
在数据库中定义一个用于统计网页访问量的数据表 count,字段为 hitcount,hitcount 默认值为0,将统计数据写入到数据表中。
在每次访问时我们读取表中 hitcount 字段。
每次访问时让 hitcount 自增 1。
在页面上显示新的 hitcount 值作为页面的访问量。
如果你需要统计每个页面的访问量,你可以使用以上逻辑将代码添加到所有页面上。

十四、JSP 自动刷新

想象一下,如果要直播比赛的比分,或股票市场的实时状态,或当前的外汇配给,该怎么实现呢?显然,要实现这种实时功能,您就不得不规律性地刷新页面。
JSP提供了一种机制来使这种工作变得简单,它能够定时地自动刷新页面。
刷新一个页面最简单的方式就是使用response对象的setIntHeader()方法。这个方法的签名如下:

public void setIntHeader(String header, int headerValue)

这个方法通知浏览器在给定的时间后刷新,时间以秒为单位。

页面自动刷新程序示例
这个例子使用了setIntHeader()方法来设置刷新头,模拟一个数字时钟:

<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<%@ page import="java.io.*,java.util.*" %>
<html>
<head>
<title>自动刷新实例</title>
</head>
<body>

<h2>自动刷新实</h2>
<%
   // 设置每隔5秒刷新一次
   response.setIntHeader("Refresh", 5);
   // 获取当前时间
   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("当前时间为: " + CT + "\n");
%>

</body>
</html>

把以上代码保存在main.jsp文件中,访问它。它会每隔5秒钟刷新一次页面并获取系统当前时间。运行结果如下:

当前时间为: 6:5:36 PM

十五、学习资料下载

链接:https://pan.baidu.com/s/1V8XEMVn37cLmWjx12qzxzA
提取码:xmas

十六、参考文章

https://www.runoob.com/jsp/jsp-internationalization.html

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 211,948评论 6 492
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 90,371评论 3 385
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 157,490评论 0 348
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 56,521评论 1 284
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 65,627评论 6 386
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 49,842评论 1 290
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 38,997评论 3 408
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 37,741评论 0 268
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 44,203评论 1 303
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 36,534评论 2 327
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 38,673评论 1 341
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 34,339评论 4 330
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 39,955评论 3 313
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 30,770评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,000评论 1 266
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 46,394评论 2 360
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 43,562评论 2 349

推荐阅读更多精彩内容