jsp
JSP简介
JSP全称是Java Server Pages,是一种动态网页技术,JSP其实就是在html中插入了java代码和JSP标签之后形成的文件,文件名以.jsp结尾。其实JSP就是一个servlet。
在servlet中编写html比较痛苦,而写JSP就像在写html,但它相比html而言,html只能为用户提供静态数据即静态页面,而Jsp技术允许在页面中嵌套java代码,为用户提供动态数据,从而形成动态页面。需要注意的是最好只在JSP中编写动态输出的java代码。
第一个JSP:
在WebContent目录下点击右键—>new—>JSP file,创建一个名为first.jsp的文件,然后在文件中编写下面代码:
1 <%@ page language="java" contentType="text/html; charset=utf-8" 2 pageEncoding="utf-8"%> 3 <%@ page import="java.util.*" %> 4 <!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd"> 5 <html> 6 <head> 7 <meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1"> 8 <title>第一个JSP</title> 9 </head> 10 <body> 11 <% 12 Date d = new Date(); 13 out.write(d.toLocaleString()); 14 %> 15 </body> 16 </html>
之后将项目部署到tomcat中并启动,访问localhost:8080/07-04-jsp/first.jsp即可在页面中看到当前时间了。
JSP就是一个servlet
到eclipse工作空间中的.metadata.plugins\org.eclipse.wst.server.core\tmp0\work\Catalina\localhost\07-04-jsp\org\apache\jsp目录下,可以看到first_jsp.java和first_jsp.class两个文件,打开java源码后可以看到该类继承了 org.apache.jasper.runtime.HttpJspBase类,通过HttpJspBase的源码可以看到是继承了HttpServlet,因此JSP就是一个servlet。
JSP的工作流程
将JSP文件转换为.java文件并将其编译为.class文件的过程都是由tomcat完成的,在tomcat内部有一个翻译引擎,当JSP页面第一次被访问时由翻译引擎转换为.java文件并编译出.class文件。之后再运行该class文件。
在JSP中的html代码都会翻译到servlet中的out.write()中。
JSP中的注释
在JSP中可以使用下面两种注释:
- html注释:
<!-- -->
- JSP注释:
<%-- --%>
两者之间的区别是html注释可以在客户端浏览器中以查看源代码的方式看到,而JSP注释则不会被看到。
JSP中Java相关的标签
- <% %>
在JSP中使用该标签嵌入Java代码,在一个JSP中可以有多个<% %>并且可以出现JSP文件中的任意位置,JSP引擎会将这部分Java代码按照从上到下的顺序放到_jspService方法中,因此在<% %>中只能出现以分号结尾的Java语句,不能出现下面内容:- 声明变量添加访问权限修饰符的;
- 不能定义方法;
- 不能定义静态语句块;
- <%! %>
如果想要在JSP中声明方法或静态代码块等内容的话可以使用该标签,在该标签中不能直接编写普通的Java语句,一般情况下不建议使用这个标签,因为JSP是在单线程环境下运行的,所以在这部分中的变量可能会有线程安全问题。例:
<%! private int a = 10; %>
<%!
public void m1(){
System.out.println("m1方法");
}
%>
<% m1();//调用m1方法 %>
- <%= %>
该标签中的内容可以直接在JSP中输出变量、常量等,里面的内容是不用分号结尾的,会被JSP引擎直接翻译到_jspService方法中的out.write()方法中输出,例如:<% int a = 1024;%> <%= a %> <%= "monkey1024" %>
JSP的9个内置对象
为了便于开发者的使用,在JSP引擎将JSP翻译为.java文件时,会提供9个与web开发相关的对象被称为JSP中9个内置对象,开发者在JSP中可以直接使用这些对象调用的方法,这九个内置对象的引用名分别是:pageContext,request,session,application,response,config,out,page,exception。
通过查看源码可以看到这些对象的定义。
- pageContext
页面上下文,通过该对象中的setAttribute和getAttribute方法设置访问范围只在当前页面中有效的数据,不过在当前页面范围中,数据都是可以直接使用的,所以该对象不常用 - out
该类型继承了IO流中的Writer,所以out是一个输出流对象,使用方法上跟PrintWriter类似。 - page
通过源码中可以看到,将this赋值给page,所以该对象就是servlet自己,在实际应用中不常使用 - exception
该对象通常配合page指令使用,后面再详解 - application
该对象和下面的对象的使用方法跟servlet中的一样 - request
- response
- session
- config
在开发或学习中,如果需要使用上面的这些java对象时,无需自己创建,直接拿来使用就是了。这九个JSP的内置对象一定要记住,有时面试的时候会问到。
JSP指令
JSP 指令的作用是为当前页面做一些基本的属性设置,为当前的页面的运行提供基本的环境。
在JSP中包含三类指令:
- page,页面指令
- include,包含指令
- taglib,标签库指令
这些指令的使用的语法格式均为如下形式:
1 <%@ 指令名称 属性名=属性值 ... %>
page指令
page指令用于设置当前JSP页面的相关信息, 一个 JSP中可以包含多个 page 指令,有以下几个常用的属性:
pageEncoding
pageEncoding属性用于设置当前JSP页面的字符编码格式。
1 <%@ page pageEncoding="UTF-8" %>
该属性被翻译到java源码里面的_jspService()方法中的 response.setContentType(“text/html;charset=UTF-8”)
在eclipse中新建JSP时默认的使用ISO8859-1的编码,此时可以通过下列步骤修改创建JSP文件的默认编码:
windows–>preference–>Web–>JSP files,将encoding修改为utf-8即可。
contentType
contentType属性用于设置当前 JSP 页面在浏览器中的内容类型,通常为”text/html”,若在 JSP 页面中设置如下:
1 <%@ page contentType="text/html" %>
该属性被翻译到java源码里面的_jspService()方法中的 response.setContentType(“text/html)。
当内容类型为”text/html”时,使用 pageEncoding 属性与 contentType 属性效果是相同的。只有当内容类型不为”text/html”时,才专门使用 contentType 属性指定。在指定字符编码时,这两个属性一般不同时使用。
import
该属性主要用于在JSP中导入java包
1 <%@ page import="java.util.*" %>
在java源码中被翻译为:
import java.util.*;
若要导入多个类,则在 import 属性值中可使用逗号将这些类分隔。
1 <%@ page import="java.util.*,java.sql.*" %>
errorPage
该属性主要用于指定当前页面运行过程中发生异常时所要跳转到的页面。
1 <%@ page errorPage="/error.jsp" %>
该属性会被翻译到 Servlet 的_jspService()方法中。
isErrorPage
如果一个页面中指定了发生异常后所要跳转的页面,这时将会出现一个问题:异常信息被隐藏。在控制台看不到异常信息,在所跳转的页面中也看不到异常信息,这样不利于开发者定位错误的原因。此时可以在发生异常后所要跳转的页面中将isErrorPage属性设置为true,将其声明为错误处理页面:
1 <%@ page isErrorPage="true" pageEncoding="UTF-8"%>
系统出现问题,请联系管理员
1 <% 2 //在控制台中打印异常信息 3 exception.printStackTrace(); 4 5 %>
一个页面中的isErrorPage属性被设置为true之后,在_jspService()方法中,多出了一个变量 exception。这就是内置对象exception,可以通过该对象在控制台打印异常信息。
session
session属性用于指定当前页面中是否可以直接使用内置对象session,默认为 true。
include指令
包含指令,用于将某个文件包含到当前的 JSP 文件中。该指令只有一个属性 file,用于指定要包含的文件。
被包含的文件可以是 JSP 文件,也可以是 HTML文件。
这里定义一个名为 left.jsp 的文件,其中定义了一个变量 sum。
<%
int sum = 10;
%>
再定义一个index.jsp文件,将left.jsp文件包含进来:
1 <%@ include file="/left.jsp" %> 2 <br> 3 <!-- 访问sum变量 --> 4 <%= sum%>
找到生成java文件的目录,里面只生成了一个 index_jsp.java 的文件,并没有生成left_jsp.java 文件。那是因为 JSP 翻译引擎在翻译时,会将 include 指令所指定的文件内容直接翻译到当前 JSP 的java源码中,形成一个.java 文件。这个包含操作是在编译之前由 JSP 翻译引擎完成的,不是在程序运行期完成的。这种包含通常被称为静态包含,与之相对的还有动态包含(后面会讲到)。
由于在编译期就将这些文件合并为了一个 java文件,所以,整个过程就一个_jspService()方法。也就是说,这些文件之间是可以相互访问局部变量的,只要满足变量声明与使用的先后顺序即可。
为什么使用 include 指令
在一个web系统中,往往很多页面的头部、底部等内容是相同的,为了减少重复性的工作和便于修改,可以将这些内容相同的内容单独定义为一个jsp文件,在需要的时候直接使用include指令将其引入进来即可,这样不仅大大减少了工作量,还做到了对于页面修改的”一改全改”效果。
什么是JSP标签
JSP标签,有的地方也叫做JSP动作,在JSP中编写大量的java代码会使JSP页面显得杂乱无章,看起来非常不舒服,因此JSP提供了一些类似html的标签,通过这些标签能够替代部分java代码实现功能。
语法格式如下:
<jsp:标签名称 属性名=属性值 ... ></jsp:标签名称>
或
<jsp:标签名称 属性名=属性值 ... />
常用JSP标签
在JSP中有很多JSP标签,但是常用的主要有下面两个:
< jsp:forward>
该标签的作用是把请求转发给另外一个资源,页面中使用该指令之后,当前页面中的所有要显示的内容都将无法显示,因为会直接转发到了另一个页面。
创建一个index.jsp文件
1 index.jsp页面,因为使用了forward标签,所以该页面中的内容不会显示 2 3 <% 4 request.setAttribute("name", "monkey1024"); 5 %> 6 7 <jsp:forward page="/next.jsp"></jsp:forward>
创建next.jsp文件
1 next.jsp页面 2 <br> 3 <%=request.getAttribute("name") %>
注意:在jsp标签中没有用于重定向的标签
< jsp:include>
该标签用于把另外一个文件引入到当前JSP里面,这种引入方式叫做动态引入。
创建一个left.jsp
1 <% 2 int sum = 50 3 %> 4 <br> 5 left sum=<%= sum %>
创建一个index.jsp
1 <% 2 int sum = 100 3 %> 4 <br> 5 <jsp:include page="/left.jsp"/> 6 <br> 7 index sum=<%= sum %>
打开生成java文件的目录可以看到,生成了两个jsp文件,分别是index_jsp.java和left_jsp.java
可以得出结论,该指令的引入是在运行期完成的,而非在编译期。这个引入指令,是在程序运行过程中,由 index_jsp 文件中的_jspService()方法通过 JspRuntimeLibrary 类的 include()方法调用了 left_jsp 文件中的_jspService()方法。在运行期所执行的这种引入,称为动态引入。
动态引入和静态引入的区别
静态引入:
1 <%@ include file="/xxx.jsp" %>
静态引入会生成一个java文件,两个jsp文件中可以共享同一个变量,但不能定义重名的变量。
动态引入:
1 <jsp:include page="/xxx.jsp"/>
动态引入会生成两个java文件,两个jsp文件中不可以共享同一个变量,可以定义重名的变量。
在静态引入与动态引入均可使用时,一般使用静态引入。因为在程序运行时只存在一个Servlet,对资源的消耗较少,且不存在调用问题,执行效率较高。
什么是EL表达式
EL,Expression Language,表达式语言,是一种在JSP页面中获取数据的简单方式,通过${变量名}的方式可以获取到值,需要注意的是EL只能从 pageConext、request、session、application 四大域属性空间中获取数据。
使用EL表达式获取数据
下面不能成功取值
1 <% int sum = 88; %> 2 <!-- 该值取不出来,因为没有放在四大域属性空间中 --> 3 ${sum }
可以将这个值存放到四大域属性空间中的任意一个中。然后访问其存放时的 key即可。
1 <% 2 pageContext.setAttribute("name", "monkey1024"); 3 request.setAttribute("name", "monkey1024"); 4 session.setAttribute("name", "monkey1024"); 5 application.setAttribute("name", "monkey1024"); 6 %> 7 <!-- 可以取出来,因为放进了四大域属性空间中 --> 8 ${name }
EL底层是从最小范围的pageContext依次查找,直到查找到最大范围 application。这期间,只要查找到了,则直接获取,不再去后面的范围中查找了,若最终没有查找到,则什么也不输出。
从指定域中获取数据
从 pageContext 依次查找到 application 域空间,会降低执行效率。若属性确定存放在某个域空间时,则可指定直接从该空间中查找。此时需要借助 EL 的四个域属性空间相关的内置对象。
1 <% 2 pageContext.setAttribute("name", "page"); 3 request.setAttribute("name", "request"); 4 session.setAttribute("name", "session"); 5 application.setAttribute("name", "application"); 6 %> 7 <!-- 使用域属性空间相关的内置对象获取数据 --> 8 ${pageScope.name } 9 ${requestScope.name } 10 ${sessionScope.name } 11 ${applicationScope.name }
访问 Bean 的属性
EL 可以通过 ${key .属性}的方式获取到指定对象的属性值。其底层实际调用的是该对象的相应属性的 get 方法。也可以使用${key[“属性”]的方式获取。该方式不常用。
1 <% 2 Student stu = new Student("张三", 22); 3 request.setAttribute("stu", stu); 4 %> 5 <!-- 访问 student对象中的属性 --> 6 ${requestScope.stu.name } 7 ${requestScope.stu["name"] }
若要访问一个对象的域属性的值,则可多次使用点号运算符,依次取出相应的属性值。
1 <% 2 Student stu = new Student("张三", 22); 3 School s = new School("小猴子",stu); 4 request.setAttribute("s", s); 5 %> 6 <!-- 访问 school对象中的student对象中的属性 --> 7 ${requestScope.s.stu.name }
获取数组中的元素
EL 可以通过 ${key[索引]} 的方式获取到指定索引的元素。不过,需要注意的是,若数组中不存在该指定索引的元素,系统并不会抛出数组越界异常。
1 <% 2 String[] names = {"刘德华","黎明","郭富城","张学友"}; 3 request.setAttribute("names", names); 4 %> 5 <!-- 输出黎明 --> 6 ${names[1] } 7 <!-- 没有输出也不会报错 --> 8 ${names[50] }
获取 List 中的元素
与获取数组中的元素相同,通过 ${key[索引]} 的方式可以获取 List 中指定索引的元素。若 List 中不存在该指定索引的元素,系统并不会抛出越界异常。
1 <% 2 Student stu1 = new Student("张三", 22); 3 Student stu2 = new Student("李四", 23); 4 Student stu3 = new Student("王五", 24); 5 List<Student> list = new ArrayList<Student>(); 6 list.add(stu1); 7 list.add(stu2); 8 list.add(stu3); 9 request.setAttribute("list", list); 10 %> 11 <!-- 输出李四 --> 12 ${list[1].name } 13 <!-- 没有输出也不会报错 --> 14 ${list[50].name }
EL 无法输出 Set 集合中的元素。因为 Set 集合中的元素是无序的,即没有索引的概念,所以无法通过索引获取元素。
获取 Map 中的元素
EL 通过 ${attributeName.mapKey} 的方式可以获取指定 Map 的指定 key 的值。
1 <% 2 Map<String,String> map = new HashMap<String,String>(); 3 map.put("name","monkey1024"); 4 map.put("password","123456"); 5 request.setAttribute("map", map); 6 %> 7 ${map.name } 8 <br> 9 ${map.password }
运算符
EL 表达式可以进行各种运算,其中常用的运算符有:
- 算术运算符 + – * / % (不支持++、–)
- 关系运算符 == != > >= < <=
- 逻辑运算符 ! && || not and or
- 三目运算符 ? :
- 特殊运算符 empty
&& 或者 and, 例如:${false && false} 或者 ${false and false }
|| 或者 or, 例如:${true || false} 或者 ${true or false }
! 或者 not,例如:${!true} 或者 ${not true }
empty的法为${empty 变量},结果为布尔值。
- 若变量未定义,则返回值为 true
- 若变量为 String 类型,且其值为空串,则返回值为 true。
- 若变量为引用类型,且其值为 null,则返回值为 true。
- 若变量为集合类型,且其不包含任何元素,则返回值为 true。
1 <% 2 request.setAttribute("name", ""); 3 request.setAttribute("student", null); 4 request.setAttribute("list", new ArrayList()); 5 %> 6 <!-- 下面输出结果均为true --> 7 变量未定义:${empty no }<br> 8 空字符串:${empty name }<br> 9 对象是null:${empty student }<br> 10 集合中没有元素:${empty list }<br>
EL表达式内置对象
同JSP类似,在EL表达式中也有一些内置对象,共11个:
- pageContext
- pageScope
- requestScope
- sessionScope
- applicationScope
- cookie
- param
- paramValues
- header
- headerValues
- initParam
上面除了pageContext是javax.servlet.jsp.PageContext类型,其他的都是java.util.Map类型。四个域属性相关的对象之前用过了,下面主要介绍一些其他常用的。
pageContext
EL表达式中的pageContext与JSP内置对象中的 pageContext 是同一个对象。通过该对象,可以获取
到 request、response、session、servletContext、servletConfig 等对象。注意,这些对象在 EL中不是内置对象,只能通过EL中的pageContext 获取。
在 EL 中直接
`${pageContext.request}`
即可获取 request 对象。其底层实际调用的是
pageContext.getRequest()方法。同理,也可以通过类似方式获取到其它对象。
在这些获取的对象中,有一个是实际工程中最常用的:
1 ${pageContext.request.contextPath}
用于获取当前项目的发布到服务器的名称。一般会用在路径中。
1 <form action="${pageContext.request.contextPath }/login.do"></form>
param
在 EL 中通过${param.参数名}可获取到请求中指定参数名的值。例如,提交的请求为:
localhost:8080/07-04-jsp/index.jsp?name=monkey1024
在 JSP 页面中通过如下方式,可获取到 name 参数的值:
1 ${param.name}
paramValues
若提交的请求中同一参数具有多个值,则可通过 ${paramValues.参数名[索引]} 获取到指定索引号的该参数值。例如,提交的请求为:
localhost:8080/07-04-jsp/index.jsp?hobby=basketball&hobby=football
在JSP中获取方式如下:
1 ${paramValues.hobby[0]} 2 ${paramValues.hobby[1]}
initParam
在 EL 中通过使用 ${initParam.初始化参数名} 可以获取到初始化参数的值。 例如在 web.xml 中定义了初始化参数如下:
<context-param>
<param-name>admin</param-name>
<param-value>1024</param-value>
</context-param>
在JSP中的获取方式如下:
1 ${initParam.admin}
其他对象在开发中基本不常使用,这里就不介绍了
自定义EL函数
EL函数不支持字符串连接的操作,即${“ab”+”cd”}这样的都不支持,可以通过自定义函数来解决这个问题。
下面以实现“将一个字符串转全部换为大写”的功能为例,来讲解自定义 EL 函数的过程。
1.定义Java方法
自定义一个类名为StringFunction的类,创建一个静态方法:
1 package com.monkey1024.el; 2 3 /** 4 * 自定义EL函数 5 * 6 */ 7 public class StringFunction { 8 9 public static String toUpper(String str){ 10 return str.toUpperCase(); 11 } 12 }
2.创建标签
在 Web 项目的/WEB-INF 目录下,新建一个扩展名为.tld 的 XML 文件,例如 monkeyfn.tld。 tld的全称是Tag Library Definition,标签库定义,之后将定义好的函数,在这个文件中进行注册。
1 <taglib xmlns="http://java.sun.com/xml/ns/j2ee" 2 xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 3 xsi:schemaLocation="http://java.sun.com/xml/ns/j2ee http://java.sun.com/xml/ns/j2ee/web-jsptaglibrary_2_0.xsd" 4 version="2.0"> 5 6 <!-- 指定定义的当前函数库版本号。随意指定。 --> 7 <tlib-version>1.0</tlib-version> 8 <!-- 指定该函数库的名称,一个函数库一个名称,随意命名,通常与文件名相同,这个名称在后面 JSP 中要使用。 --> 9 <short-name>monkeyfn</short-name> 10 <!-- 指定该函数库所对应的 URL,一个函数库一个 URL, URL 随意,在后面 JSP 中要使用该 URL --> 11 <uri>http://www.monkey1024.com/jsp/monkeyTld</uri> 12 13 <function> 14 <!-- 指定将来在 JSP 的 EL 中使用该函数的名称。一般与类中静态方法同名。 --> 15 <name>toUpper</name> 16 <!-- 指定该函数定义在哪个类中 --> 17 <function-class>com.monkey1024.el.StringFunction</function-class> 18 <!-- 指定类中的方法 --> 19 <function-signature>java.lang.String toUpper( java.lang.String )</function-signature> 20 </function> 21 </taglib>
3.使用自定义函数
首先在JSP中引入自定义函数库:
1 <!-- 引入自定义标签库 --> 2 <%@ taglib uri="http://www.monkey1024.com/jsp/monkeyTld" prefix="monkeyfn"%>
之后可以通过下面方式使用自定义函数:
1 ${monkeyfn:toUpper("monkey1024") }
EL总结
- 不能出现在 Java 代码块、表达式块等 JSP 的动态代码部分。
- 只能从 pageConext、request、session、application 四大域属性空间中获取数据。
- 不会抛出空指针异常。若访问一个 null 对象的属性,则什么也不显示。
- 不会抛出数组访问越界异常。若访问一个数组中的不存在的元素,则什么也不显示。
JSTL标签简介
JSTL是JavaServerPages Standard Tag Library的缩写,即JSP标准标签库。开发者可以使用JSTL实现JSP页面中逻辑处理。如判断、循环等,在JSTL中已经定义好了一套对于字符串进行处理的函数标签库,这样就不用我们自己去编写相关逻辑了。
使用JSTL前的准备
首先需要下载相关jar包。
目前最新版本是1.2.5,如果使用该版本的话,需要添加下面这些jar包:
- taglibs-standard-spec-1.2.5.jar
- taglibs-standard-impl-1.2.5.jar
- taglibs-standard-jstlel-1.2.5.jar
- xalan-2.7.1.jar
- serializer-2.7.1.jar
如果使用1.2.x之前版本的话(不包括1.2),只添加下面这些jar包即可:
- jstl.jar
- standard.jar
本章代码基于1.2.5的版本。
下载地址:
JSTL:http://pan.baidu.com/s/1dESNmDj
xalan:https://pan.baidu.com/s/1T4KHIv0yiy0p6meU8e3kfw
使用JSTL处理字符串
在JSTL中有对字符串的处理,使用时需要将相关函数库引入,示例如下:
1 <%@ page language="java" contentType="text/html; charset=UTF-8"%> 2 <!-- 引入JSTL函数标签库 --> 3 <%@ taglib uri="http://java.sun.com/jsp/jstl/functions" prefix="fn"%> 4 <!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd"> 5 <html> 6 <head> 7 <meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1"> 8 <title>Insert title here</title> 9 </head> 10 <body> 11 12 <br> 13 14 ${fn:toUpperCase("monkey1024") } 15 16 </body> 17 </html>
JSTL核心标签库简介
JSTL中的核心标签库主要用于完成基本的逻辑运算,在开发中使用较多。
在开发前导入相关jar包之后,还需要在页面中通过 taglib 指令将标签库导入:
1 <%@taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c"%>
c:out标签
用于在页面上输出 EL 表达式的值,该标签不常使用,因为不使用该标签也能够在页面上输出EL表达式。
1 <% 2 pageContext.setAttribute("user", "admin"); 3 %> 4 5 el表达式:${user } 6 <br/> 7 jstl中的out标签:<c:out value="${user }"></c:out>
c:catch标签
当有异常发生时,用于捕获异常。相当于 try-catch 中的 catch 代码块,该标签中只有一个属性 var,是捕获到的异常对象,名称可以自定义。该标签不常用,一般不会在页面中显示异常信息。
1 <c:catch var="e"> 2 ${pageContext.name}; 3 </c:catch> 4 message = ${e.message }
c:if标签
该标签主要用于条件判断。
1 <% 2 pageContext.setAttribute("user", "admin"); 3 %> 4 <c:if test="${user == 'admin' }" var="flag" scope="request"> 5 欢迎登陆 6 </c:if>
- test:判断的条件。若为 true,则执行标签体中的内容,否则不执行。
- var:存储 test 的判断结果。不常用。
- scope:存储 test 判断结果的变量的存放范围。不常用。
c:choose标签
实现多分支判断。类似于 switch-case 语句。一个 标签中可以包含多个与一个。
1 <% 2 pageContext.setAttribute("hobby", "basketball"); 3 %> 4 <c:choose> 5 <c:when test="${hobby == 'basketball'}"> 6 我喜欢打篮球 7 </c:when> 8 <c:when test="${hobby == 'football'}"> 9 我喜欢踢足球 10 </c:when> 11 <c:when test="${hobby == 'volleyball'}"> 12 我喜欢打排球 13 </c:when> 14 <c:otherwise> 15 我没什么爱好 16 </c:otherwise> 17 </c:choose>
c:forEach标签
该标签用于循环遍历数组、集合(List、Set、Map),实际开发中使用较多。
1 <br>---------------------遍历数组--------------------------<br> 2 <% 3 Object[] city = {"北京","上海","广州","天津"}; 4 pageContext.setAttribute("city", city); 5 %> 6 <c:forEach items="${city }" var="c"> 7 ${c } 8 <br> 9 </c:forEach> 10 11 <br>---------------------遍历List--------------------------<br> 12 <% 13 List<String> name = new ArrayList<>(); 14 name.add("刘德华"); 15 name.add("张学友"); 16 name.add("黎明"); 17 name.add("郭富城"); 18 pageContext.setAttribute("name", name); 19 %> 20 21 <c:forEach items="${name }" var="n"> 22 ${n } 23 <br> 24 </c:forEach> 25 <br>---------------------遍历set--------------------------<br> 26 <% 27 Set<String> program = new HashSet<>(); 28 program.add("java"); 29 program.add("c"); 30 program.add("python"); 31 program.add("php"); 32 pageContext.setAttribute("program", program); 33 %> 34 35 <c:forEach items="${program }" var="p"> 36 ${p } 37 <br> 38 </c:forEach> 39 40 <br>---------------------遍历map--------------------------<br> 41 <% 42 Map<String,String> map = new HashMap<>(); 43 map.put("第一名", "中国"); 44 map.put("第二名", "美国"); 45 map.put("第三名", "德国"); 46 pageContext.setAttribute("map", map); 47 %> 48 49 <c:forEach items="${map }" var="m"> 50 ${m.key } : ${m.value } 51 <br> 52 </c:forEach>
指定遍历的起始索引及步长
对于数组及 List,可以指定遍历的起始索引及步长。
1 <br>---------------------指定遍历起始及步长--------------------------<br> 2 <% 3 Object[] country = {"0中国","1美国","2德国","3法国","4英国","5瑞士","6瑞典","7意大利"}; 4 pageContext.setAttribute("country", country); 5 %> 6 7 <c:forEach items="${country }" var="c" begin="1" end="4"> 8 ${c } 9 <br> 10 </c:forEach>
- begin:指定遍历开始索引,从 0 开始计数。
- end:指定遍历结束索引,遍历结果包含这个索引。
1 <br>---------------------指定遍历起始及步长--------------------------<br> 2 <% 3 Object[] country = {"0中国","1美国","2德国","3法国","4英国","5瑞士","6瑞典","7意大利"}; 4 pageContext.setAttribute("country", country); 5 %> 6 7 <c:forEach items="${country }" var="c" begin="1" end="7" step="2"> 8 ${c } 9 <br> 10 </c:forEach>
step:指定遍历时的步长。
标签中有一个属性 varStatus,该属性指定的变量是一个引用型变量。该引用
中记录了当前遍历对象的相关信息。该引用常用的方法如下:
- int getIndex():获取当前对象的索引。从 0 开始计数。
- int getCount():获取当前对象的序号。从 1 开始计数。
- boolean isFirst():判断当前对象是否是第一个对象。
- boolean isLast():判断当前对象是否是最后一个对象。
1 <% 2 List<Student> student = new ArrayList<>(); 3 student.add(new Student("马云",22)); 4 student.add(new Student("马化腾",26)); 5 student.add(new Student("李彦宏",21)); 6 student.add(new Student("周鸿祎",20)); 7 student.add(new Student("雷军",28)); 8 student.add(new Student("陈一舟",25)); 9 student.add(new Student("柳传志",30)); 10 pageContext.setAttribute("student", student); 11 %> 12 <table border="1"> 13 <tr> 14 <td>序号</td> 15 <td>姓名</td> 16 <td>年龄</td> 17 </tr> 18 19 <c:forEach items="${student }" var="s" varStatus="obj"> 20 <tr> 21 <td>${obj.count }</td> 22 <td>${s.name }</td> 23 <td>${s.age }</td> 24 </tr> 25 </c:forEach> 26 27 </table>
隔行着色
通过varStatus中的index控制隔行着色
1 <table border="1"> 2 <tr> 3 <td>序号</td> 4 <td>姓名</td> 5 <td>年龄</td> 6 </tr> 7 8 <c:forEach items="${student }" var="s" varStatus="obj"> 9 <tr style="background-color: ${obj.index % 2 == 0? 'orange':'red'}"> 10 <td>${obj.count }</td> 11 <td>${s.name }</td> 12 <td>${s.age }</td> 13 </tr> 14 </c:forEach> 15 16 </table>
JSTL格式化标签
要使用格式化标签库需要先引入标签库
1 <%@taglib uri="http://java.sun.com/jsp/jstl/fmt" prefix="fmt"%>
fmt:formatDate标签
该标签用于使用不同的模式格式化日期。其常用属性有:
- value:将要被格式化的数据
- pattern:格式化的模式。其与 SimpleDateFormat 的参数设置方式相同。
- var:格式化后的字符串所要存放的变量。若不指定 var,则会将格式化过的结果直接显示在页面
- scope:变量存放的域属性空间,取值为 page、request、session、application。默认为page 范围
- type:其取值为 date、time,或 both,表示给出的 value 是日期、时间,还是两者都包含。默认为 date
1 <% 2 Date date = new Date(); 3 pageContext.setAttribute("date", date); 4 %> 5 6 <form action=""> 7 <!-- 在页面中直接显示 --> 8 <fmt:formatDate value="${date }" pattern="yyyy-MM-dd"/> 9 <br> 10 <!-- 将格式化后的日期显示在表格中 --> 11 <fmt:formatDate value="${date }" var="birth" pattern="yyyy-MM-dd"/> 12 <input type="text" name="birthdat" value="${birth }"> 13 </form>
fmt:parseDate标签
该标签用于将指定字符串转换为日期类型。常用的属性有:
- value:将要被转换的数据
- pattern:将要被转换的数据的模式。其与 SimpleDateFormat 的参数设置方式相同。
- var:转换后的日期类型数据所要存放的变量。若不指定 var,则会将转换过的结果直接显示在页面
- scope:变量存放的域属性空间,取值为 page、request、session、application。默认为page 范围。
1 <% 2 String date = "2017-10-03"; 3 pageContext.setAttribute("date", date); 4 %> 5 <!-- 将转换后的日期直接输出在页面中 --> 6 <fmt:parseDate value="${date }" pattern="yyyy-MM-dd"></fmt:parseDate> 7 <br> 8 9 <!-- 将转换后的日期存放在指定变量中 --> 10 <fmt:parseDate value="${date }" var="birth" pattern="yyyy-MM-dd"></fmt:parseDate> 11 ${birth }