1、EL表达式
EL(Express Language)的格式为${key}来直接访问四个域中的attribute对应的对象,可以直接内嵌在JSP页面内部,从而简化代码的编写。EL表达式在web.xml为2.4版本之后自动开启,所以需要确保web_app的版本为2.4以后。
EL的pageScope、requestScope、sessionScope、applicationScope分别对应JSP的四个内置对象,通过${xxxScope.key}访问对象。可以省略使用Scope直接使用域内的对象,这时EL会依次从小到大地访问pageContext、Request、Session、Application四个域并查找key,如果找到则返回对应的对象,并停止继续向后查找,因此在使用EL表达式时尽量不要使用相同名字的键值。如下所示为在JSP页面通过EL访问四个域中的属性:
<%
pageContext.setAttribute("key1","pageAttr");
request.setAttribute("key2","requestAttr");
session.setAttribute("key3","sessionAttr");
application.setAttribute("key4","applicationAttr");
request.setAttribute("key1","requestAttr"); //与page中的key1同名,不会被访问到
%>
//输出结果依次为:pageAttr、requestAttr、sessionAttr、applicationAttr
${key1}、${key2}、${key3}、${key4}
EL表达式可以通过.或者[]来访问对象属性,例如${user.name}和${user["name"]是等价的。此外可以通过[]访问数组对象,例如${users[0].name}代表访问数组users的第一个对象的name属性。注意当属性中包含特殊字符时或者属性名是变量时需要通过[]访问:
${user["first-name"]} //包含特殊字符
${user[key]} //属性为变量key
例如定义一个User类,并通过jsp动作完成对象的创建和属性的设置,之后直接通过${对象名.属性名}访问到了对象myUser的属性name
public class User {
private String name;
private int age;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
}
--------------------------------------
<jsp:useBean id="myUser" class="entity.User" />
<jsp:setProperty name="myUser" property="name" value="小明" />
用户姓名:${myUser.name}
EL会完成自动类型的转换,将request请求中的参数转换为数字:
//原来需要手动转换类型
String str_count=request.getParameter("count")
int count=Integer.parseInt(str_count)
count += 20
//EL自动完成类型转换
${count+20}
此外EL表达式还可以进行简单算术表达式和逻辑表示的运算
5/2=${5/2} <!--计算算术表达式-->
5>3?${5>3} <!--计算逻辑表达式-->
${empty myUser} <!--判空操作-->
2、JSTL
JSTL(Jsp Standarded Tag Library)是JSP的一个标准标签库集合。通过使用标签库可以复用重复率较高的代码块,不仅提高了开发效率,而且有较强的可读性。
使用之前需要先导入jar包,从apach官网http://archive.apache.org/dist/jakarta/taglibs/standard/binaries/下载jstl的jar包,我下载的是1.1.2版本,在Tomcat 9与Servlet 4.0版本上可以正常使用。下载后找到lib目录下有jstl.jar、standard.jar包,将其复制到Java项目的lib目录下并添加到项目依赖,注意standard.jar包中有自动补全所需的tld文件,导入之后在IDEA中使用jstl可以自动补全。在要使用JSP页面添加如下语句引入JSTL。
<%@ taglib prefix="c" uri="http://java.sun.com/jstl/core_rt" %>
注意这里引入的是core_rt而不是core,使用core库在执行EL表达式时会报错如下,使用core_rt可以正常输出EL的值
According to TLD or attribute directive in tag file, attribute [value] does not accept any expressions
控制标签
out标签用于jstl的输出与显示,value属性为输出的值,default属性设置value为空时显示的内容,escapeXml="false"设置转义value中的XML标记,例如下面的输出为 < out >。可以直接输出常量,但是输出的变量就需要放在EL表达式内。
<c:out value="< out >" default="默认值" escapeXml="false"></c:out>
set标签用于设置变量与值,var属性为变量名,value变量值,scope为变量的作用域,也可以省略value将变量值写在标签内
<c:set var="var1" value="value1" scope="session"/>
<c:set var="var2">value2</c:set>
<c:out value="${var1}"/>
<c:out value="${var2}"/>
通过set还可以为对象进行赋值,target属性指向对象名,property设置要赋值的属性
<jsp:useBean id="user1" class="modules.User"/> <!--创建一个User类对象-->
<c:set target="${user1}" property="name" value="小赵"/> <!--为对象属性赋值-->
<c:out value="${user1.name}"/>
remove标签用于删除设置的变量,var为变量名,scope代表范围域
<c:remove var="var1" scope="session"/>
catch标签用于捕获异常,将可能出错的代码段放在catch标签内,然后将出错信息保存在erro变量,之后输出error的内容
<c:catch var="error">
<c:out value="${1/0}"/>
</c:catch>
<c:out value="${error}"/>
流程控制标签
if标签用于进行判断,如果test属性为true则执行其标签对内的语句,可以通过其var属性查看其判断结果为true还是false
<c:set var="score" value="70"/>
<c:if test="${score>=60}" var="testPass" scope="session">
<c:out value="及格"/>
</c:if>
<c:out value="结果布尔值:${testPass}"/>
choose标签类似于switch,通过when标签进行条件判断,如果test为true则执行其子标签,否则继续进行下一个when标签的判断,如果都不符合则执行otherwise标签的内容。例如下面只输出优秀
<c:set var="score" value="90"/>
<c:choose>
<c:when test="${score>=80}">
<c:out value="优秀"/>
</c:when>
<c:when test="${score>=60}">
<c:out value="及格"/>
</c:when>
<c:otherwise>
<c:out value="不及格"/>
</c:otherwise>
</c:choose>
循环控制标签
forEach标签用于遍历集合元素,items属性为要遍历的元素,var指代其中的子元素,begin、end用于设置遍历的起始和终止位置,step代表步长(隔几个元素取一个),varStatus用在子元素中表示子元素的位置属性。如下所示遍历weeks数组,从数组2个位置到第6个位置,步长为2,指定每个元素var为day,其状态varStatus为itemStatus。
<%
List<String> weeks=new ArrayList<String>();
weeks.add("Monday");
weeks.add("Tuesday");
weeks.add("Wednesday");
weeks.add("Thursday");
weeks.add("Friday");
weeks.add("Saturday");
weeks.add("Sunday");
session.setAttribute("weeks",weeks);
%>
<c:forEach var="day" items="${weeks}" begin="2" end="6" step="2" varStatus="itemStatus">
<c:out value="${day}"/>
<c:out value="index:${itemStatus.index}"/>
<c:out value="count:${itemStatus.count}"/>
<c:out value="first:${itemStatus.first}"/>
<c:out value="last:${itemStatus.last}"/>
<br>
</c:forEach>
输出结果如下:可见itemStatus的index代表其在原来数组中的位置,count代表输出的第几个元素,first、last代表是否为输出的第一个、最后一个元素
Wednesday index:2 count:1 first:true last:false
Friday index:4 count:2 first:false last:false
Sunday index:6 count:3 first:false last:true
forToken标签用于分割字符串并进行遍历结果,items分割的字符串,delims为分隔符,var为子串变量
<c:forTokens items="010-11223344" delims="-" var="subStr">
<c:out value="${subStr}"/>
</c:forTokens>
URL操作标签
import标签可以将其他页面内容包含到本页面,与jsp的include动作只能引入本web项目的文件不同的是,它可以引入其他应用甚至是网上的url
<c:catch var="pageError">
<c:import url="https://www.baidu.com" charEncoding="UTF-8"/>
</c:catch>
<c:out value="${pageError}"/>
还可以将页面内容保存在字符串importWeb中,之后进行处理,
<c:import url="https://www.baidu.com" charEncoding="UTF-8" var="importWeb" scope="application"/>
<c:out value="${importWeb}"/>
redirect标签可用于页面的重定向,并且可以通过request的parameter传递参数
<c:redirect url="https://www.baidu.com">
<c:param name="username">小王</c:param>
<c:param name="password">1234</c:param>
</c:redirect>
JSTL函数
JSTL还提供了一些常用的函数功能,如果需要使用jstl中的内置函数,需要再包含一个库:
<%@ taglib prefix="fn" uri="http://java.sun.com/jsp/jstl/functions" %>
函数使用如下:例如contains函数可以判断字符串中是否包含子字符串,indexOf字符串索引
<c:out value="是否包含:${fn:contains('123456@163.com', '@')}"/>
<c:out value="位置:${fn:indexOf('123456@163.com', '@')}"/>
还有一些常用的函数例如: