JSTL
- 什么是JSTL
- 使用JSTL的步骤
- JSTL标签的原理
- 分析标签源码
- 看核心标签库中的forEach标签
- 主标签库常用标签
- forEach标签
- begin、end、step属性
- stuStatus属性
- if标签
- test属性
- var和scope
- choose和when标签
什么是JSTL
JSTL
全称为 Java Standard Tag Library
(Java标准标签库)
JSTL作为最基本的标签库,提供了一系列的JSP标签,实现了基本的功能:集合的遍历、数据的输出、字符串的处理等等。
使用JSTL可以让JSP代码更加的简洁,可读性非常好,重用性非常高,可以完成一些复杂的功能!
使用JSTL的步骤
- 引入
JSTL
标签库对应的jar包:
在IDEA中怎么引入?
在WEB-INF
下新建lib
目录,然后将jar包拷贝到lib当中;
什么时候需要将jar包放到WEB-INF
下的lib
目录下?
Tomcat
没有自带的jar
包
- 在JSP中引入要使用标签库(使用
taglib
指令引入标签库)
JSTL中提供了很多标签库,重点掌握核心标签库(
core
标签库)
JSTL标签的原理
<%taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
以上uri
后面的路径实际上指向了一个xxx.tld
文件。
tld
文件实际上是一个xml
配置文件。
在tld
文件中描述了“标签”和“Java类”之间的关系,
以上核心标签库
对应的tld
文件是:c.tld
文件
分析标签源码
<tag>
<description>//标签对应的描述
Catches any Throwable that occurs in its body and optionally
exposes it.
</description>
<name>catch</name>//标签的名字
<tag-class>org.apache.taglibs.standard.tag.common.core.CatchTag</tag-class>//标签对应的Java类
<body-content>JSP</body-content>//标签体当中可以出现的内容,如果是JSP,就表示标签体中可以出现符合JSP所有语法的代码,例如EL表达式。
<attribute>//属性
<description>//属性的描述
Name of the exported scoped variable for the
exception thrown from a nested action. The type of the
scoped variable is the type of the exception thrown.
</description>
<name>var</name>//属性名
<required>false</required>
//false表示该属性不是必须的,true表示该属性是必须的
<rtexprvalue>false</rtexprvalue>
//这个描述说明了该属性是否支持EL表达式,false表示不支持,true表示支持EL表达式
</attribute>
/*
<c:catch var="">
JSP....
</c:catch>
*/
</tag>
看核心标签库中的forEach标签
下面是forEach
标签的源码(有点小长):
<tag>
<description>
The basic iteration tag, accepting many different
collection types and supporting subsetting and other
functionality
</description>
<name>forEach</name>
<tag-class>org.apache.taglibs.standard.tag.rt.core.ForEachTag</tag-class>
<tei-class>org.apache.taglibs.standard.tei.ForEachTEI</tei-class>
<body-content>JSP</body-content>//该标签允许JSP内容
<attribute>
<description>
Collection of items to iterate over.
(翻译:要遍历的集合)
</description>
<name>items</name>
<required>false</required>
<rtexprvalue>true</rtexprvalue>
//该属性值支持EL表达式
<type>java.lang.Object</type>
<deferred-value>
<type>java.lang.Object</type>
</deferred-value>
</attribute>
<attribute>
<description>
If items specified:
Iteration begins at the item located at the
specified index. First item of the collection has
index 0.
If items not specified:
Iteration begins with index set at the value
specified.
</description>
<name>begin</name>
<required>false</required>
<rtexprvalue>true</rtexprvalue>
<type>int</type>
</attribute>
<attribute>
<description>
If items specified:
Iteration ends at the item located at the
specified index (inclusive).
If items not specified:
Iteration ends when index reaches the value
specified.
</description>
<name>end</name>
<required>false</required>
<rtexprvalue>true</rtexprvalue>
<type>int</type>
</attribute>
<attribute>
<description>
Iteration will only process every step items of
the collection, starting with the first one.
</description>
<name>step</name>
<required>false</required>
<rtexprvalue>true</rtexprvalue>
<type>int</type>
</attribute>
<attribute>
<description>
Name of the exported scoped variable for the
current item of the iteration. This scoped
variable has nested visibility. Its type depends
on the object of the underlying collection.
</description>
(翻译:迭代的当前项的导出作用域变量的名称。这个作用域变量具有嵌套的可见性。它的类型取决于基础集合的对象。)
<name>var</name>
<required>false</required>
<rtexprvalue>false</rtexprvalue>
//不可以用EL表达式
</attribute>
<attribute>
<description>
Name of the exported scoped variable for the
status of the iteration. Object exported is of type
jakarta.servlet.jsp.jstl.core.LoopTagStatus. This scoped variable has nested
visibility.
</description>
<name>varStatus</name>
<required>false</required>
<rtexprvalue>false</rtexprvalue>
</attribute>
</tag>
- 在此标签属性
items
中,该属性的属性值是支持EL
表达式的,那么就可以像下面这样使用:
- 在此标签属性
var
中,该属性代表的是集合中的每一个元素,var
后面的名字是自取的是随意的。
测试结果:
主标签库常用标签
forEach标签
- 上面解释了的
forEach
中的var
和items
属性标签
begin、end、step属性
<%@page contentType="text/html;charset=UTF-8"%>
<%@taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<c:forEach var="i" begin="1" end="10" step="1">
${i}<br>
</c:forEach>
测试结果:
由于可以使用EL
表达式去访问var
,这里我们可以猜测var
被存在某个域中了;
stuStatus属性
varStatus
=“这个属性表示var的状态对象,这里是一个Java对象,这个Java对象代表了var的状态”
varStatus=“这里面名字是随意的”
varStatus
这个状态对象有count
属性,可以直接使用。
<%@ page import="javawen.jsp.bean.User" %>
<%@ page import="java.util.List" %>
<%@ page import="java.util.ArrayList" %>
<%@page contentType="text/html;charset=UTF-8" %>
<%--引入标签库--%>
<%@taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<%
List<User> list = new ArrayList<>();
User user1 = new User("zx","13",34);
User user2 = new User("zs","343",94);
User user3 = new User("xm1","12413",24);
list.add(user1);
list.add(user2);
list.add(user3);
request.setAttribute("user",list);
%>
<%--items通过源码我们知道是支持EL表达式的--%>
<c:forEach items="${user}" var="u" varStatus="xx">
编号:${xx.count},name:${u.username},password:${u.password},age:${u.age}
<br>
</c:forEach>
测试结果:
if标签
if
标签(test
属性(必须),var
属性(非必须),scope
属性(非必须))
test属性
看下面源码可以知道,if
标签中test
属性必须存在并且是支持EL表达式的;
<%@page contentType="text/html;charset=UTF-8"%>
<%@taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<c:if test="${empty paramValues.username}">
<h1>用户名为空</h1>
</c:if>
测试效果:
var和scope
var
=“这里填的是一个变量”,这个变量名是布尔类型的,其值和test
相对应。
下面看看var
属性描述的翻译:
scope
=“这里填的是四大作用域中的其中一个”,可以填(pageContext、request、session、application
)。
表示var
作用的范围!
下面是其属性描述翻译:
测试:
<%@page contentType="text/html;charset=UTF-8"%>
<%@taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<c:if test="${empty paramValues.username}" var="flag" scope="application">
<h1>用户名为空</h1>
</c:if>
${flag}
choose和when标签
<%@page contentType="text/html;charset=UTF-8" %>
<%@taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<%--
下面相当于
if(){
}else if(){
}else if(){
}else{
}
--%>
<c:choose>
<c:when test="${param.age<18}">
青少年
</c:when>
<c:when test="${param.age<35}">
青年
</c:when>
<c:when test="${param.age<55}">
中年
</c:when>
<c:otherwise>
老年
</c:otherwise>
</c:choose>
测试结果: