JavaWeb之Jsp技术

JSP技术

JSP(Java Server Page)是web开发中一个重要组成部分。可以接收客户端的请求,并对请求作出响应,在MVC开发模式中,通常用做展示层。

JSP组成

指令

以<%@开始%>结束的就是指令。在JSP中常用的指令有三个page指令、taglib指令、import指令

page指令

属性 属性值
language 开发JSP所使用的语言
contentType 设置JSP向客户端浏览器响应的内容以及字符编码
pageEncoding JSP页面的编码格式
isErrorPage 设置该页面是否是异常信息页面,当值为true时,即可在页面中使用exception内置对象
errorPage 用于指定错误页面,当页面中发生异常时则web容器自动跳转到该属性指定的页面
buffer 设置out对象缓冲区大小,默认8kb

taglib指令

taglib指令允许页面使用JSTL和用户定制的标签。taglib指令的语法如下:

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

注释

注释以“<%–”以“–%>”结束,中间则是注释的内容,在JSP中注释有两种,一种是JSP注释,一种是HTML注释,其中JSP注释不会响应的浏览器,但是HTML注释会响应到客户端浏览器。

1
<%--这是JSP注释--%>

脚本

以<%开始,以%>结束,中间则是我们要书写的Java代码或者业务逻辑。

1
2
3
4
5
//Java代码都可以编写在<% %>中
<%
String name = request.getServerName();
response.getWriter().write(name);
%>

声明

以“<%!”开始,以“%>”结束,中间则可以定义方法、类等内容

1
2
3
4
5
6
7
8
9
10
11
12
13
14
<%!
//声明一个方法
public void sayHello(){
System.out.println("Hello");
}
//声明一个类
public class Student{
private String name;
private int age;
public void test(){
System.out.println("Hello");
}
}
%>

表达式

<%=%>则是向页面中输出变量,等价于out对象的write()方法。

1
2
3
4
5
<%
String name = request.getServerName();
response.getWriter().write(name);
%>
<%=name%>

模板

模板其实就是在JSP中的HTML

动作元素

动作元素为请求处理阶段提供信息。动作元素遵循XML元素的语法,有一个包含元素名的开始标签,可以有属性、可选的内容、与开始标签匹配的结束标签。动作元素也可以是一个空标签,可以有属性。与XML和XHTML一样,JSP的标签也是区分大小写的。但是在现行软件开发过程中,动作元素几乎不使用。

JSP 2.0规范中定义了20个标准的动作元素:

  1. <jsp:useBean>、<jsp:setProperty>和<jsp:getProperty>:这三个动作元素用于访问JavaBean
  2. <jsp:param>:这个动作元素被用来以“名-值对”的形式为其他标签提供附加信息。
  3. <jsp:include>:这个动作元素用于在当前页面中包含静态和动态的资源,一旦被包含的页面执行完毕,请求处理将在调用页面中继续进行。
  4. <jsp:forward>:这个动作允许在运行时将当前的请求转发给一个静态的资源、JSP页面或者Servlet,请求被转向到的资源必须位于同JSP发送请求相同的上下文环境中。
  5. <jsp:plugin>、<jsp:params>和<jsp:fallback>:<jsp:plugin>动作用于产生与客户端浏览器相关的HTML标签(<OBJECT>或<EMBED>),从而导致在需要时下载Java插件(Plug-in)软件,并在插件中执行指定的JavaBean。
  6. <jsp:element>:这个动作用于动态定义一个XML元素的标签。在<jsp:element>中,可以包含<jsp:attribute>和<jsp:body>。
  7. <jsp:attribute>:<jsp:attribute>动作主要有两个用途:一是用于在XML元素的内容中定义一个动作属性的值。二是在<jsp:element>动作中使用,指定输出元素的属性。
  8. <jsp:body>:这个动作用于定义元素的内容
  9. <jsp:text>:这个动作用于封装模板数据,它可以在模板数据允许出现的任何地方使用。<jsp:text>元素的作用和在JSP页面中直接书写模板数据一样。
  10. <jsp:output>:<jsp:output>动作只能在JSP文档和以XML语法编写的标签文件中使用,主要用于输出XML声明和文档类型声明
  11. <jsp:invoke>和<jsp:doBody>:<js:invoke>和<jsp:doBody>动作元素只能在标签文件中使用

JSP生命周期

JSP容器管理JSP页面生命周期的两个阶段:转换阶段(translation phase)和执行阶段(execution phase)。当有一个对JSP页面的客户请求到来时,JSP容器将JSP页面转换为Servlet源文件,然后编译Servlet源文件生成字节码文件,这一阶段是转换阶段。接下来,加载转换后的Servlet类,实例化一个对象处理客户端的请求,在请求处理完成后,响应对象被JSP容器接收,容器将HTML格式的响应信息发送到客户端,这一阶段是执行阶段。

当第一次加载JSP页面时,因为要将JSP文件转换为Servlet类,所以响应速度较慢。当再次请求时,JSP容器就会直接执行第一次请求时产生的Servlet,而不会再重新转换JSP文件,所以其执行速度和原始的Servlet执行速度几乎相同。在JSP执行期间,JSP容器会检查JSP文件,看是否有更新或修改。如果有更新或修改,JSP容器会再次编译JSP或Servlet;如果没有更新或修改,就直接执行前面产生的Servlet,这也是JSP相对于Servlet的好处之一。

JSP内置对象

JSP内置对象是指在JSP中不需要实例化即可直接使用的对象。

内置对象 描述
application ServletContext的实例
config ServletConfig的实例
exception 获取出现异常时的信息
out jsp的输出流对象
page 指向当前jsp的对象
pageContext jsp的上下文路径
request HttpServletRequest的实例,请求对象
response HttpServletResponse的实例,响应对象
session HttpSession的实例,会话

application

JSP application 对象是 javax.servlet.ServletContext 类的实例,这有助于查找有关 Servlet 引擎和 Servlet 环境的信息。它的生命周期从服务器启动到关闭。在此期间,对象将一直存在。这样,在用户的前后连接或不同用户之间的连接中,可以对此对象的同一属性进行操作。在任何地方 对此对象属性的操作,都会影响到其他用户的访问。

config

config 对象是 javax.servlet.ServletConfig 类的实例,表示 Servlet 的配置信息。
当一个 Servlet 初始化时,容器把某些信息通过此对象传递给这个 Servlet,这些信息包括 Servlet 初始化时所要用到的参数(通过属性名和属性值构成)以及服务器的有关信息(通过传递一个 ServletContext 对象),config 对象的应用范围是本页。

exception

该内置对象的作用主要是为了获取程序运行过程中的发生异常的信息。并且只有当JSP中page指令设置isErrorPage=”true”时,才可以使用该对象,并且表明该页面是异常处理页面,JSP中可以设置page指令errorPage属性的值来指定异常信息页面,也就是说当指定了异常信息页面后,如果JSP中发生了异常,则跳转到指定的异常信息页面

异常的处理有以下两种方式:

方式一:

  1. 编写异常页面,并且设置page执行的属性isErrorPage=”true”
1
<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8" isErrorPage="true"%>
  1. 为页面指定异常页面
1
<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8" errorPage="error.jsp"%>

方式二:

web.xml中配置全局异常信息:

1
2
3
4
5
6
7
8
9
10
11
12
13
<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://java.sun.com/xml/ns/javaee" xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd" id="WebApp_ID" version="3.0">
<!-- 根据异常种类指定错误页面 -->
<error-page>
<exception-type>java.lang.ArithmeticException</exception-type>
<location>/error.jsp</location>
</error-page>
<!-- 根据响应状态码指定错误页面 -->
<error-page>
<error-code>404</error-code>
<location>/notFound.jsp</location>
</error-page>
</web-app>

以上两种方式都可以处理在web开发中发生异常的情形,区别在于,方式一只能处理JSP中发生异常的情况,如果Servlet中发生异常则不会自动跳转到错误页面,方式二则是全局异常处理的方式,不管是JSP还是Servlet中发生异常,只有符合配置条件,则都会跳转到错误页面,并且JSP中无需指定errorPage.

out

out 对象是一个输出流,用来向客户端输出数据,可以是各种数据类型的内容,同时,它还可以管理应用服务器上的输出缓冲区,缓冲区的默认值是 8KB,可以通过页面指令 page 来改变默认大小。
out 对象是一个继承自抽象类 javax.servlet.jsp.JspWriter 的实例,在实际应用中,out 对象会通过 JSP容器变换为 java.io.PrintWriter 类的对象。
在使用 out 对象输出数据时,可以对数据缓冲区进行操作,及时清除缓冲区中的残余数据,为其他的输出让出缓冲空间。数据输出完毕后要及时关闭输出流。

方法 描述
public abstract void clear() throws java.io.IOException 清除缓冲区中的内容。如果缓冲区已经被刷新,clear()方法将抛出IOException异常。
public abstract void clearBuffer() throws java.io.IOException 清除缓冲区中的当前内容。这个方法和clear()方法的区别是,如果缓冲区已经被刷新,这个方法不会抛出IOException异常。
public abstract void close() throws java.io.IOException 刷新缓冲区,关闭输出流。注意,我们在编写JSP页面时,不需要显式地去调用这个方法,因为在JSP容器所生成的代码中会自动包含对close()方法的调用。
public abstract void flush() throws java.io.IOException 刷新缓冲区。
public int getBufferSize() 获得out对象使用的缓冲区的大小。
public boolean isAutoFlush() 判断out对象是否是自动刷新。

out对象针对不同的数据类型,提供了多个重载的print()和println()方法,用于输出数据。要注意的是,虽然println()方法会输出一个换行,但是客户端的浏览器在显示页面时会忽略输出的换行。

page

page对象是当前页面转换后的Servlet类的实例。从转换后的Servlet类的代码中,可以看到这种关系。也可以把对象理解为this。

pageContext

获取页面上下文的pageContext对象,是一个比较特殊的对象,通过它可以获取JSP页面的request、response、session、out、exception等对象。pageContext对象的创建和初始化都是由容器来完成的,JSP页面中可以直接使用pageContext对象。

  • public abstract javax.servlet.ServletRequest getRequest()
  • public abstract javax.servlet.ServletResponse getResponse()
  • public abstract javax.servlet.http.HttpSession getSession()
  • public abstract javax.servlet.ServletContext getServletContext()
  • public abstract JspWriter getOut()
  • public abstract javax.servlet.ServletConfig getServletConfig()
  • public abstract java.lang.Object getPage()
  • public abstract java.lang.Exception getException()

在pageContext对象中,可以使用下面两个方法来保存和获取属性。

  • public abstract void setAttribute(java.lang.String name,java.lang.Object value)
  • public abstract java.lang.Object getAttribute(java.lang.String name)

删除指定范围内名字为name的属性。

  • public abstract void removeAttribute(java.lang.String name)

在pageContext对象中保存的属性,只能在当前页面中去获取,也就是说,在pageContext中保存的数据库相当于保存在了page中。

request

客户端可通过 HTML 表单或在网页地址后面提供参数的方法提交数据,然后通过 request 对象的相关方法来获取这些数据。request 对象封装了客户端的请求信息,包括用户提交的信息以及客户端的一些信息,服务端通过 request 对象可以了解到客户端的需求,然后做出响应。
request 对象是 HttpServletRequest(接口)的实例。请求信息的内容包括请求的标题头(Header)信息(如浏览器的版本信息语言和编码方式等),请求的方式(如 HTTP 的 GET 方法、POST 方法等),请求的参数名称、参数值和客户端的主机名称等。

response

response对象和 request 对象相对应,用于响应客户请求,向客户端输出信息。response 是 HttpServletResponse 的实例,封装了 JSP产生的响应客户端请求的有关信息,如回应的 Header,回应本体(HTML 的内容)以及服务器端的状态码等信息,提供给客户端。请求的信 息可以是各种数据类型的,甚至是文件。

session

客户与服务器之间的通信是通过 HTTP 协议完成的。HTTP 是一种无状态的协议,当客户向服务器发出请求,服务器接收请求并返回响应后,该连接就被关闭了。此时,服务器端不保留连接的有关信息,要想记住客户的连接信息,可以使用 JSP提供的 session 对象。
用户登录网站时,系统将为其生成一个独一无二的 session 对象,用以记录该用户的个人信息。一旦用户退出网站,那么,所对应的 session 对象将被注销。session 对象可以绑定若干个用户信息或者 JSP 对象,不同的 session 对象的同名变量是不会相互干扰的。
当用户首次访问服务器上的一个 JSP 页面时,JSP 引擎便产生一个 session 对象,同时分配一个 String 类型的 ID 号,JSP 引擎同时将这个 ID 号发送到客户端,存放在 Cookie 中,这样,session 对象和客户端之间就建立了一一对应的关系。
当用户再次访问该服务器的其他页面时,不再分配给用户新的 session 对象,直到用户关闭浏览器,或者在一定时间(系统默认在 30 分钟内,但可在编写程序时,修改这个时间限定值或者显式地结束一个会话)客户端不向服务器发出应答请求,服务器端就会取消该用户的 session 对象,与用户的会话对应关系消失。当用户重新打开浏览器,再次连接到该服务器时,服务器为该用户再创建一个新的 session 对象。

关于Session的内容,将在会话跟踪中详细讲解。

JSP作用域

在JSP页面中的对象,包括用户创建的对象(例如,JavaBean对象)和JSP的隐含对象,都有一个范围属性。范围定义了在什么时间内,在哪一个JSP页面中可以访问这些对象。在JSP中,有4种范围,如下所示。

  1. page:具有page范围的对象被绑定到javax.servlet.jsp.PageContext对象中。在这个范围内的对象,只能在创建对象的页面中访问。可以调用pageContext这个隐含对象的getAttribute()方法来访问具有这种范围类型的对象(pageContext对象还提供了访问其他范围对象的getAttribute方法),可以调用pageContext对象的setAttribute()方法将对象保存到page范围中,pageContext对象本身也属于page范围。当Servlet类的_jspService()方法执行完毕,属于page范围的对象的引用将被丢弃。page范围内的对象,在客户端每次请求JSP页面时创建,在页面向客户端发送回响应或请求被转发(forward)到其他的资源后被删除。
  2. request:具有request范围的对象被绑定到javax.servlet.http.HttpServletRequest对象中,可以调用request这个隐含对象的getAttribute()方法来访问具有这种范围类型的对象,可以调用request对象的setAttribute()方法将对象保存到request范围中。在调用forward()方法转向的页面或者调用include()方法包含的页面中,都可以访问这个范围内的对象。要注意的是,因为请求对象对于每一个客户请求都是不同的,所以对于每一个新的请求,都要重新创建和删除这个范围内的对象。
  3. session:具有session范围的对象被绑定到javax.servlet.http.HttpSession对象中,可以调用session这个隐含对象的getAttribute()方法来访问具有这种范围类型的对象,可以调用session对象的setAttribute()方法将对象保存到session范围中。JSP容器为每一次会话,创建一个HttpSession对象,在会话期间,可以访问session范围内的对象。
  4. 具有application范围的对象被绑定到javax.servlet.ServletContext中,可以调用application这个隐含对象的getAttribute()方法来访问具有这种范围类型的对象,可以调用application对象的setAttribute()方法将对象保存到application范围中。在Web应用程序运行期间,所有的页面都可以访问在这个范围内的对象。

这4个作用域的范围从大到小,依次如下:

名称 作用域
application 在所有应用程序中有效
session 在当前会话中有效
request 在当前请求中有效
page 在当前页面有效

请求转发和重定向

请求转发和重定向的作用都是用于跳转web资源,但是二者是存在区别的。

下面的两个示例分别演示的用请求转发和重定向跳转资源:

1
2
3
4
5
6
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
//请求转发
request.getRequestDispatcher("index.jsp").forward(request, response);
//重定向
response.sendRedirect("index.jsp");
}

在请求转发中,客户端浏览器请求JSP或者Servlet,当JSP或者Servlet接收到请求后,将请求转发给其他的JSP或者Servlet,最终由转发后的资源对客户端进行响应。在整个过程中只有1次请求。

在重定向中,客户端浏览器请求JSP或者Servlet,当JSP或者·Servlet接收到请求后会先向客户端响应302状态码及重定向地址,当客户端浏览器接收到该302响应码以后,重新发起一次请求,请求的地址就是服务端伴随这302响应的地址,因此在整个过程中发生了2次请求。

接下来我们学习两者的区别:

  1. 请求转发时浏览器地址栏不会发生变化,重定向时浏览器地址会发生
  2. 请求转发是服务器内部行为,而重定向则是客户端行为,当客户端接收到302响应状态码后,会发出新的请求,去请求目标页面。因此请求转发的效率要高于重定向。
  3. 请求转发只能跳转当前应用内的资源,重定向则可以跳转外部资源。
  4. 请求转发过程是1次请求,而重定向过程中有2次请求, 因此在请求转发的过程中可以使用request对象传递数据,重定向则不行。

EL表达式

EL的语法简单,使用方便。所有的EL表达式都是以“${”开始,以“}”结束,在JSP开发中有着大量的使用,通常情况下和JSTL搭配使用。关于JSTL的内容会在下一章节中讲解。

基本运算

操作符 描述
. 访问一个Bean属性
[] 访问一个数组元素
( ) 组织一个子表达式以改变优先级
+
- 减或负
*
/ or div
% or mod 取模
== or eq 测试是否相等
!= or ne 测试是否不等
< or lt 测试是否小于
> or gt 测试是否大于
<= or l 测试是否小于等于
>= or ge 测试是否大于等于
&& or and 测试逻辑与
|| or or 测试逻辑或
! or not 测试取反
empty 测试是否空值

下面,通过示例学习EL表达式的用法:

1
2
3
4
5
6
7
8
${5+2}		//结果:7
${5/2} //结果:2
${5%2} //结果:1
${6==6} 或 ${6 eq 6} //结果:true
${"A"=="a"} 或 ${"A" eq "a"} //结果:false
${3<=8} 或 ${3 le 8} //结果:true
${"A"<="a"} 或 ${"A" le "a"} //结果:true
${2>1&&3<4 } 或 ${2>1and3<4 } //结果:true

EL内置对象

内置对象 描述
pageScope page 作用域
requestScope request 作用域
sessionScope session 作用域
applicationScope application 作用域
param Request 对象的参数,字符串
paramValues Request对象的参数,字符串集合
header HTTP 信息头,字符串
headerValues HTTP 信息头,字符串集合
initParam 上下文初始化参数
cookie Cookie值
pageContext 当前页面的pageContext

下面,通过示例来学习EL表达式内置对象的用法:

1
2
3
4
5
6
7
8
9
10
11
<%
pageContext.setAttribute("info", "page属性范围");
request.setAttribute("info", "request属性范围");
session.setAttribute("info", "session属性范围");
application.setAttribute("info", "application属性范围");
%>

page 属性内容:${pageScope.info}
request 属性内容:${requestScope.info}
session 属性内容:${sessionScope.info}
application 属性内容:${applicationScope.info}
1
2
3
4
5
6
7
//例如我们要取得用户请求参数时,可以用下面方法:
request.getParameter(String name);
request.getParameterValues(String name);

//在EL表达式中则可以使用param和paramValues两者来取得数据
${param.name}
${paramValues.name}
1
2
3
//例如我们要获取用户浏览器的版本
${header["User-Agent"]}
//另外少有机会下,有可能同一标头名称拥有不同的值,此时必须改为使用headerValues来获取
1
2
3
4
//获取设定web站点的环境参数,一般的方法:
String userid = (String) application.getInitParameter("userid");
//也可以使用EL表达式
${initParameter.userid}
1
2
//要获取cookie中有一个设定名称为userCountry的值,
${cookie.userCountry}
1
2
3
4
5
//pageContext获取其他有关用户要求或页面的详细信息
${pageContext.request.queryString} //获取请求的参数字符串
${pageContext.request.requestURL} //获取请求的URL,但不包括请求参数字符串
${pageContext.request.method} //获取HTTP的方法(get、post)
${pageContext.session.id} //获取session的id

JSTL

JSTL(JSP Standard Tag Library),规范由Sun公司制定,Apache的Jakoarta小组负责实现,JSTL的目标是为了简化JSP页面的设计。JTSL包括了5个不同作用的标签库,除了核心标签库以为其他4个标签库在开发中很少使用。接下来,详细学习JSTL核心标签库。

核心标签

set标签

属性 描述
var 存储在作用域中的键名称
value 存在作用域中的值或者被修改对象的值
scope 保存的作用域,默认保存在page中
target 被修改属性的所属对象
property 被修改属性的名称

示例:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
<%@page import="cn.bytecollege.model.Student"%>
<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>Insert title here</title>
</head>
<body>
<%
Student s = new Student("紫衫龙王",18);
pageContext.setAttribute("student", s);
%>
<c:set var="name" value="白眉鹰王" ></c:set>
<c:set target="${student}" property="name" value="白眉鹰王" ></c:set>
${student }
${name }
</body>
</html>

out标签

属性 描述
value 要输出的内容
default 输出的默认值
escapeXml 是否忽略特殊字符

示例:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>Insert title here</title>
</head>
<body>
<!-- 直接输出内容 -->
<c:out value="唧唧复唧唧"></c:out>
<!-- 输出作用域中的数据 -->
<c:set var="name" value="admin"></c:set>
<c:out value="${name }"></c:out>
<!-- 输出默认值,当value中的值为null时,输出默认值 -->
<c:out value="${name}" default="UNKNOW"></c:out>
<!-- 是否忽略特殊字符 -->
<c:out value="&lt;今天是个好日子&gt;" escapeXml="false"></c:out>
</body>
</html>

remove标签

<c:remove>标签用于移除一个变量,可以指定这个变量的作用域,若未指定,则默认为变量第一次出现的作用域。

这个标签不是特别有用,不过可以用来确保JSP完成清理工作。

属性 描述
var 要移除的变量名
scope 变量所属作用域

示例:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>Insert title here</title>
</head>
<body>
<c:set var="name" value="admin" scope="session"></c:set>
<c:remove var="name" scope="session"></c:remove>
name===${name }
</body>
</html>

foreach标签

属性 描述
items 被遍历的对象
begin 开始的元素索引
end 结束的元素索引
step 每一次迭代的步长
var 当前元素的变量名称
varStatus 循环变量的变量名称
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
我们常会用c标签来遍历需要的数据,为了方便使用,varStatus属性可以方便我们实现一些与行数相关的功能,如:奇数行、偶数行差异;最后一行特殊处理等等。先就varStatus属性常用参数总结下:

${status.index} 输出行号,从0开始。
${status.count} 输出行号,从1开始。
${status.current} 当前这次迭代的(集合中的)项
${status.first} 判断当前项是否为集合中的第一项,返回值为true或false
${status.last} 判断当前项是否为集合中的最后一项,返回值为true或false
begin、end、step 分别表示:起始序号,结束序号,跳跃步伐。

<c:forEach begin='1' end='5'step='2' items='${list}'var='item'>
<%@page import="java.util.Map"%>
<%@page import="java.util.HashMap"%>
<%@page import="java.util.HashSet"%>
<%@page import="java.util.Set"%>
<%@page import="java.util.ArrayList"%>
<%@page import="java.util.List"%>
<%@page import="javax.servlet.jsp.jstl.core.LoopTagStatus"%>
<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>foreach</title>
</head>
<body>
<!-- foreach遍历整数 -->
<c:forEach begin="0" end="10" varStatus="status">
${status.index }
</c:forEach>
<br>
<!-- foreach遍历数组 -->
<%
String[] names = {"白眉鹰王——殷天正","金毛狮王——谢逊","青翼蝠王——韦一笑","紫衫龙王——黛绮丝","杨左使","范右使"};
pageContext.setAttribute("names", names);
%>
<c:forEach items="${names}" var="item" begin="0" end="8" step="2">
${item}
</c:forEach>
<br>
<!-- foreach遍历List -->
<%
List<String> list = new ArrayList();
list.add("李寻欢");
list.add("林诗音");
list.add("龙啸云");
list.add("阿飞");
pageContext.setAttribute("list", list);
%>
<c:forEach items="${list}" var="item">
${item}
</c:forEach>
<br>
<%
Set<String> set = new HashSet();
set.add("李寻欢");
set.add("林诗音");
set.add("龙啸云");
set.add("阿飞");
pageContext.setAttribute("set", set);
%>
<!-- foreach遍历Set -->
<c:forEach items="${set }" var="item">
${item}
</c:forEach>
<br>
<!-- foreach遍历Map -->
<%
Map<Integer,String> map = new HashMap<>();
map.put(1,"黄药师");
map.put(2, "黄蓉");
pageContext.setAttribute("map", map);
%>
<c:forEach items="${map }" var="item">
${item.key }======${item.value}
</c:forEach>
<br>
</body>
</html>

if choose when标签

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>choose</title>
</head>
<body>
<c:set var="name" value="admin"></c:set>
<c:if test="${name eq 'admin' }">
您具有登录的权限
</c:if>
<c:choose>
<c:when test="${name == 'admin1' }">
admin1
</c:when>
<c:when test="${name eq 'admin2' }">
admin2
</c:when>
<c:otherwise>
user
</c:otherwise>
</c:choose>
</body>
</html>