简介:
JSTL是apache对EL表达式的扩展(JSTL依赖EL),JSTL是标签语言,使用非常方便.
导包:jstl-*.jar
引入标签库:<%@taglib prefix=“前缀” uri=“标签库路径”%>
<%@taglib prefix=“my” uri="/WEB-INF/mytags/mytag1.tld"%>:注意部分版本不支持在WEB-INF目录下创建名为tags的目录.
JSTL标签库
- core:核心标签库(重点)
- fmt:格式化标签库
- sql:数据库标签库(过时不用)
- xml:xml标签库(过时不用)
core标签:常用前缀c表示
- 导入标签库:<%@taglib prefix=“c” uri=“http://java.sun.com/jstl/core”%>
out:输出标签,<c:out>,功能为输出内容
- value:可以是字符串,也可以是EL表达式
- default:当输出内容是null的时候,会输出default内容
- escapeXml:是否需要转义,默认true
- 举例:
<c:out value=“abc>:输出abc
<c:out value=”${a}" default=“abc”/>:输出对象a的值,如果为空则输出abc
set设置标签:<c:set>,功能位为域对象添加属性
- var:设置的属性名
- value:属性值,可以使EL表达式
- scope:可选输入将属性值放入到哪个域对象中,默认为page,也可以为request,session,application
- 举例:
<c:set var=“a” value=“aa” scope=“request”></c:set>
remove标签:<c:remove>,删除域对象的属性
- var:需要删除属性名
- scope:指定需要删除属性的域,如果不指定,则删除所有域对应该名称的属性
- 举例:
<c:remove var=“a” scope=“request”/>
url:<c:url>,功能位输出url路径(带项目名称)
- value:指定一个路径!他会在路径前面自动添加项目名称
<c:url value="/index.jsp/>:输出为/learn_jsp/index.jsp - var:指定变量名,一旦添加该属性,则该url标签不输出到页面而是将该变量名保存到域中
- scope:配合var一起使用,将指定url保存到指定域中
- 子标签:<c:param>,用来给url后面添加参数的
<c:url value="/index.jsp">
<c:param name="username" vlaue="张三"/>
</c:url>
结果为/learn_jsp/index.jsp?username=%e5%bc%a0%e4%b8%89
if:<c:if>,判断条件执行
- test:内容为boolean值,如果为true则执行内容
如:<c:if test=" e m p t y n a m e " > 没 有 n a m e 值 < / c : i f > < c : i f t e s t = " {empty name}">没有name值</c:if> <c:if test=" emptyname">没有name值</c:if><c:iftest="{not empty a }">${a }</c:if>
choose:<c:choose>,选择执行,同java的if…else if…else
- 子标签<c:when>,when表示一个条件,满足就执行when标签内部内容
- 子标签<c:otherwise>,如果存在,则必须为choose的最后一个子标签,表示当所有when都不满足时执行
<c:choose>
<c:when test="${age gt 60 }">老年</c:when>
<c:when test="${age gt 30 }">壮年</c:when>
<c:when test="${age gt 20 }">青年</c:when>
<c:when test="${age gt 0 }">小孩</c:when>
<c:otherwise>年龄内容有问题</c:otherwise>
</c:choose>
forEach:<c:forEach>标签为循环遍历数组集合
按次数遍历循环
- var:变量名,相当于java的int i;
- begin:从多少开始遍历,相当于java的i=0;
- end:遍历到多少结束,相当于java的i<=10
- step:遍历步长,默认为1,相当于java的i++
<c:forEach var="i" begin="0" end="10" step="1">
${i }
</c:forEach>
相当于java中:for(int i=0;i<=10;i++){}
输出结果:0 1 2 3 4 5 6 7 8 9 10
遍历数组或集合
- items:需要遍历的数组或集合对象
- var:将数组或集合中的对象赋值给var值
<c:forEach items="${params }" var="str">
${str}
</c:forEach>
相当于java中:for(Object str:params){}
forEach遍历的循环状态
varStatus:循环状态变量
循环状态有如下属性:
- count:循环元素的个数
- index:循环元素的下表
- first:是否为第一个元素
- last:是否为最后一个元素
- current:当前遍历的元素
<%
String[] params=new String[]{"one","two","three"};
request.setAttribute("params", params);
%>
<c:forEach items="${params }" var="str" varStatus="vs">
${vs.index },${vs.count },${vs.first },${vs.last },${vs.current }<br/>
</c:forEach>
结果为:
0,1,true,false,one
1,2,false,false,two
2,3,false,true,three
fmt标签库
时间格式化:fmt:formatDate
- value:需要格式化的日期对象
- pattern:格式化形式,如yyyy-MM-dd HH:mm:ss
- 举例:
<fmt:formatDate value="${date }" pattern=“yyyy-MM-dd HH:mm:ss”/>
输出结果2020-01-18 22:36:58
数字格式化:
- value:需要格式化的数字对象
- pattern:格式化形式,四舍五入,如果位数不足,0.00会进行部位,#.##不会进行补位
- 举例
<fmt:formatNumber value="${num }" pattern="0.00"></fmt:formatNumber>
<fmt:formatNumber value="${num }" pattern="#.##"></fmt:formatNumber>
自定义标签库
步骤:创建标签处理类
- 创建tld文件
- 引用tld中定义的标签
创建标签处理类:
实现SimpleTag接口
- 除getParent()方法外,其余set方法和doTag方法都是由tomcat负责自动执行,其中set方法都是在doTag()方法前已经被tomcat执行过,所以执行doTag()方法时,JspContext内容不会为空.
- void doTag():每次执行标签的时候回调用该方法
- JspTag getParent():返回父标签,非tomcat自主调用
- void setParent(JspTag):设置父标签
- void setJspBody(JspFragment):设置标签体
- void setJspContext(JspContext):设置jsp上下文,JspContext的子实现类有PageContext
继承SimpleTagSupport类
- 每次实现父接口,然后重写五个方法很麻烦,所以JSP提供一个支持类,该类已经重写了所有SimpleTag的父接口,我们只需要重写doTag(),负责逻辑处理即可
- void doTag():每次执行标签的时候回调用该方法
创建tld文件:
- 在WEB-INF下创建tld文件,保证客户端访问不到,不能创建tags文件夹,否则出错.
- name:标签至此哪个的功能名
- tag-class:使用标签最终执行的类
- body-content:标签体的种类:
– empty(常用):标签体无内容
– scriptless(常用):只能使用EL表达式作为标签,也可以执行其他标签
– JSP(不用):jsp2.0后不支持这个类型,表示标签可以是jsp,java脚本,el表达式
– tagdependent(不用):标签体内容不会被执行,而是直接赋值给标签处理类. - 自定义属性:
attribute是可选属性,如果需要在EL表达式中使用属性,则配置
如果配置attribute,则在实现SimpleTag类中,需要添加对应的属性,并附上set方法,因为该方法tomcat需要自动调用,用来赋值.
<tag>
<name>mytag5</name>
<tag-class>com.zgd.learn.jsp.jstl.tag.MyTag5</tag-class>
<body-content>scriptless</body-content>
<!-- attribute是可选属性,如果需要在EL表达式中使用属性,则配置 -->
<attribute>
<!-- 标签属性名 -->
<name>test</name>
<!-- 是否为必须的 -->
<required>true</required>
<!-- 是否支持EL表达式 -->
<rtexprvalue>true</rtexprvalue>
</attribute>
</tag>
当执行到某标签的时候需要跳过页面下面其他内容的时候,可以在doTag()中主动抛出SkipPageException异常
自定义标签库案例:
自定义处理Tag标签类
package com.zgd.learn.jsp.jstl.tag;
import java.io.IOException;
import javax.servlet.jsp.JspException;
import javax.servlet.jsp.tagext.SimpleTagSupport;
public class MyTag5 extends SimpleTagSupport
{
private boolean test;
public boolean isTest()
{
return test;
}
public void setTest(boolean test)
{
this.test = test;
}
@Override
public void doTag() throws JspException, IOException
{
if (test)
{
this.getJspBody().invoke(null);
}
// JspWriter out = this.getJspContext().getOut();
// out.print("正常执行Tag中...");
// throw new SkipPageException();
}
}
自定义tld文件:
<?xml version="1.0" encoding="UTF-8" ?>
<taglib xmlns="http://java.sun.com/xml/ns/j2ee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://java.sun.com/xml/ns/j2ee http://java.sun.com/xml/ns/j2ee/web-jsptaglibrary_2_0.xsd"
version="2.0">
<tlib-version>1.0</tlib-version>
<short-name>mytag</short-name>
<uri>http://jsp.learn.com/jsp/jstl/mytag</uri>
<tag>
<name>mytag5</name>
<tag-class>com.zgd.learn.jsp.jstl.tag.MyTag5</tag-class>
<body-content>scriptless</body-content>
<attribute>
<!-- 标签属性名 -->
<name>test</name>
<!-- 是否为必须的 -->
<required>true</required>
<!-- 是否支持EL表达式 -->
<rtexprvalue>true</rtexprvalue>
</attribute>
</tag>
</taglib>
在JSP中引入自定义的标签库
<%@taglib prefix="my" uri="/WEB-INF/mytags/mytag1.tld"%>
<my:mytag5 test="${not empty xxx }">
${xxx}
</my:mytag5>
问题:
问题:在JSP页面中不支持EL表达式获取内容
- 异常类型:org.apache.jasper.JasperException org.apache.jasper.JasperException: /jstl.jsp (line: 19, column: 1) According to TLD or attribute directive in tag file, attribute test does not accept any expressions
- 问题原因:使用了JSP2.0,但是没有使用JSTL标签库的备用版本(RT库)
- 解决方案:
方案一:修改web.xml中版本信息修改为2.3
方案二:使用core_rt标签库,<%@ taglib uri=http://java.sun.com/jstl/core_rt prefix=“c”%>