JSTL概念
JSTL是apache对EL表达式的扩展(也就是说JSTL依赖EL),JSTL是标签语言!JSTL标签使用以来非常方便,它不是JSP内置的标签,需要我们自己导包,以及指定标签库。
如果你使用MyEclipse开发JavaWeb,那么在把项目发布到Tomcat时,你会发现,MyEclipse会在lib目录下存放jstl的Jar包!如果你没有使用MyEclipse开发那么需要自己来导入这个JSTL的Jar包:jstl-1.2.jar。
四大库:
> core:核心库,重点
> fmt:格式化:日期、数字
> sql:过时
> xml:过时
导入标签库
第一步导入jar 包
第二步在jsp页面中<%@ taglib prefix=”前缀” uri=”路径”%>
core库
out和set输出
- <c:out>:输出
> value:可以是字符串常量,也可以是EL表达式
> default:当要输出的内容为null时,会输出default指定的值
> escapeXml:默认值为true,表示转义!
<body>
<%
request.setAttribute("a","<script> alert('hello')</script>");
%>
<c:out value="${a }" default="默认值" escapeXml="false"></c:out>
</body>
<c:set>:设置(创建域的属性)
> var:变量名
> value:变量值,可以是EL表达式
> scope:域,默认为page,可选值:page、request、session、application
<c:set var="x" value="X" scope="page"/>
<c:out value="${pageScope.x }"/>
remove
- <remove>:删除域变量
> var:变量名
> scope:如果不给出scope,表示删除所有域中的该名称的变量;如果指定了域,那么只删除该域的变量。
<c:set var="x" value="X" scope="page"/>
<c:out value="${pageScope.x }"/><br/>
****************<br/>
<c:remove var="x"/>
<c:out value="${pageScope.x }"/>
url
- value:指定一个路径!它会在路径前面自动添加项目名。
<c:url value="/index.jsp"/>,它会输出/day13_1/index.jsp
- 子标签:<c:param>,用来给url后面添加参数,例如:
<c:url value="/index.jsp">
<c:param name="username" value="张三"/> <!--可以对参数进行url编码!!-->
</c:url>
结果为:/day13_1/index.jsp?username=%ED%2C%3F%ED%2C%3F
var:指定变量名,一旦添加了这个属性,那么url标签就不会再输出到页面,而是把生成url保存到域中。
scope:它与var一起使用,用来保存url。
<c:url value="/index.jsp">
<c:param name="username" value="张三"/>
</c:url>
if:对应java中的if语句
- <c:if test="布尔类型">...</c:if>,当test为值时,执行标签体内容!
<c:if test="${empty x }">
x为空
</c:if>
choose:它对应java中的if/else if/ ... /else
* 例如:
<c:choose>
<c:when test="">...</c:when>
<c:when test="">...</c:when>
<c:when test="">...</c:when>
...
<c:otherwise> ...</c:otherwise>
</c:choose>
等同与
if(...) {
} else if( ....) {
} else if( ....) {
} else if( ....) {
} ...
else { ...}
<body>
<%
request.setAttribute("number", 10);
%>
<c:choose>
<c:when test="${number >10 }">
number 大于10
</c:when>
<c:when test="${number==10 }">
number 等于10
</c:when>
<c:otherwise>
number 小于10
</c:otherwise>
</c:choose>
</body>
forEach
它用来循环遍历数组、集合!
它还可以用来计数方式来循环!
计数方式:
for(int i = 1; i <= 10; i++) {
...
}
<c:forEach var="i" begin="1" end="10">
${i}
</c:forEach>
属性:
* var:循环变量
* begin:设置循环变量从几开始。
* end:设置循环变量到几结束。
* step:设置步长!等同与java中的i++,或i+=2。step默认为1
<body>
<c:forEach var="i" begin="0" end="10" step="2">
${i }
</c:forEach>
</body>
用来输出数组、集合!
<c:forEach items="${strs }" var="str">
${str }<br/>
</c:forEach>
等同于
for(String str : strs) {
...
}
属性:
* items:指定要循环谁,它可以是一个数组或一个集合(注意:items=""不能有多余的空格)
* var:把数组或集合中的每个元素赋值给var指定的变量。
<body>
<%
String [] strs={"张三","李四","王五"};
pageContext.setAttribute("strs", strs);
%>
<c:forEach items="${strs }" var="str">
${str }<br/>
</c:forEach>
</body>
循环状态
可以使用varStatus来创建循环状态变量!
循环状态变量有如下属性:
* count:循环元素的个数
* index:循环元素的下标
* first:是否为第一个元素
* last:是否为最后一个元素
* current:当前元素
<body>
<%
String [] strs={"张三","李四","王五"};
pageContext.setAttribute("strs", strs);
%>
<c:forEach items="${strs }" var="str" varStatus="vs">
${vs.current } ${vs.index } ${vs.count } ${vs.first } ${vs.last }<br/>
</c:forEach>
</body>
fmt库
它是格式化库
<fmt:formatDate value="" pattern="">
value:指定一个Date类型的变量
pattern:用来指定输出的模板!例如:yyyy-MM-dd HH:mm:ss
<body>
<%
Date d=new Date();
pageContext.setAttribute("date", d);
%>
<fmt:formatDate value="${date }" pattern="yyyy-MM-dd HH:mm:ss"/>
</body>
<fmt:formatNumber value="${num1}" pattern="0.00">
保留小数点后2位,它会四舍五入!如果不足2位,以0补位!
<fmt:formatNumber value="${num1}" pattern="#.##">
保留小数点后2位,它会四舍五入!如果不足2位,不补位!
自定义标签的步骤
其实我们在JSP页面中使用标签就等于调用某个对象的某个方法一样,例如:<c:if test=””>,这就是在调用对象的方法一样。自定义标签其实就是自定义类一样!
- 定义标签处理类:必须是Tag或SimpleTag的实现类;
- 编写标签库描述符文件(TLD);
SimpleTag接口是JSP2.0中新给出的接口,用来简化自定义标签,所以现在我们基本上都是使用SimpleTag。
Tag是老的,传统的自定义标签时使用的接口,现在不建议使用它了。
SimpleTag接口介绍
SimpleTag接口内容如下:
- void doTag():标签执行方法;
- JspTag getParent():获取父标签;
- void setParent(JspTag parent):设置父标签
- void setJspContext(JspContext context):设置PageContext
- void setJspBody(JspFragment jspBody):设置标签体对象;
请记住,万物皆对象!在JSP页面中的标签也是对象!你可以通过查看JSP的“真身”清楚的知道,所有标签都会变成对象的方法调用。标签对应的类我们称之为“标签处理类”!
标签的生命周期:
- 当容器(Tomcat)第一次执行到某个标签时,会创建标签处理类的实例;
- 然后调用setJspContext(JspContext)方法,把当前JSP页面的pageContext对象传递给这个方法;
- 如果当前标签有父标签,那么使用父标签的标签处理类对象调用setParent(JspTag)方法;
- 如果标签有标签体,那么把标签体转换成JspFragment对象,然后调用setJspBody()方法;
- 每次执行标签时,都调用doTag()方法,它是标签处理方法。
自定义标签的步骤和el自定义标签的步骤相同
继承SimpleTag接口,创建标签类
添加标签库描述文件(TLD)
导入标签,使用标签
Java文件:MyTag1.java
package cn.edu.sicau.www;
import java.io.IOException;
import javax.servlet.jsp.JspContext;
import javax.servlet.jsp.JspException;
import javax.servlet.jsp.PageContext;
import javax.servlet.jsp.tagext.JspFragment;
import javax.servlet.jsp.tagext.JspTag;
import javax.servlet.jsp.tagext.SimpleTag;
public class MyTag1 implements SimpleTag{
private PageContext pageContext;
private JspFragment jspBody;
private JspTag parent;
@Override
public void doTag() throws JspException, IOException {
pageContext.getOut().println("hello,我是自定义标签!");
}
@Override
public JspTag getParent() {
return this.parent;
}
@Override
public void setJspBody(JspFragment arg0) {
this.jspBody=arg0;
}
@Override
public void setJspContext(JspContext arg0) {
this.pageContext=(PageContext) arg0;
}
public void setParent(JspTag arg0) {
this.parent=arg0;
}
}
tag-jstl.tld文件
<?xml version="1.0" encoding="UTF-8" ?>
<taglib xmlns="http://java.sun.com/xml/ns/javaee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-jsptaglibrary_2_1.xsd"
version="2.1">
<tlib-version>1.0</tlib-version>
<short-name>tag</short-name>
<uri>http://www.siacu.edu.cn</uri>
<tag>
<name>mytag1</name>
<tag-class>cn.edu.sicau.www.MyTag1</tag-class>
<body-content>empty</body-content>
</tag>
</taglib>
导入标签:
<%@ taglib prefix="tag" uri="/WEB-INF/tag-jstl.tld" %>
<body>
<tag:mytag1/>
</body>
自定义标签进阶
继承SimpleTagSupport
继承SimpleTagSuppport要比实现SimpleTag接口方便太多了,现在你只需要重写doTag()方法,其他方法都已经被SimpleTagSuppport完成了。
标签体内容
* empty:无标签体!
* JSP:jsp2.0已经不在支持这个类型了!表示标签体内容可以是:java脚本,可以是标签,可以是el表达式
* scriptless:只能是EL表达式,也可以是其他的标签!
* tagdependent:标签体内容不会被执行,而是直接赋值标签处理类!
不在执行标签下面内容的标签!
在标签处理类中的doTag()中使用SkipPageException来结束!
Tomcat会调用标签处理类的doTag()方法,然后Tomcat会得到SkipPageException,它会跳过本页面其他内容!
MyTag2.java
package cn.edu.sicau.www;
import java.io.IOException;
import javax.servlet.jsp.JspException;
import javax.servlet.jsp.SkipPageException;
import javax.servlet.jsp.tagext.SimpleTagSupport;
public class MyTag2 extends SimpleTagSupport{
@Override
public void doTag() throws JspException, IOException {
this.getJspContext().getOut().println("hello,我是自定义标签,只显示我!");
throw new SkipPageException();
}
}
tag-jstl.tld
<tag>
<name>mytag2</name>
<tag-class>cn.edu.sicau.www.MyTag2</tag-class>
<body-content>empty</body-content>
</tag>
导入包,使用标签
<body>
<tag:mytag2/>
<tag:mytag1/>
</body>
带有属性的标签
步骤:
1. 给你的标签处理类添加属性!
为标签处理类添加属性,属性至少要有一个set方法!这个set方法会在doTag()方法之前被tomcat执行!所在doTag()中就可以使用属性了。
public class MyTag3 extends SimpleTagSupport {
private boolean test;
//先于doTag()函数被tomcat调用
public void setTest(boolean test) {
this.test = test;
}
@Override
public void doTag() throws JspException, IOException {
if(test){
this.getJspBody().invoke(null);//执行标签体内容,把结果写到指定的流中,即页面上。
}
}
}
2. 在tld文件中对属性进行配置
<tag>
<name>mytag3</name>
<tag-class>cn.edu.sicau.www.MyTag3</tag-class>
<body-content>scriptless</body-content>
<attribute>
<name>test</name>
<required>true</required>
<rtexprvalue>true</rtexprvalue>
</attribute>
</tag>
<attribute>
<name>test</name> 指定属性名
<required>true</required> 指定属性是否为必需的
<rtexprvalue>true</rtexprvalue> 指定属性是否可以使用EL
</attribute>
3、导入标签,使用标签
<body>
<tag:mytag3 test="${3>2 }">3>2是正确的</tag:mytag3>
</body>