Java Web之第7章EL表达式和JSTL

7.1初识JavaBean

在软件开发时,一些数据和功能需要在很多地方使用,为了方便将它们进行“移植”,Sun公司提出一种JavaBean即使,使用JavaBean可以对这些数据和功能进行封装,做到“一次编写,到处运行“
为了降低JSP页面复杂度,增强代码的重用性,Sun公司还制定了一套标准标签库JSTL,同时为了获得Servlet域对象中存储的数据,在JSP2.0规范里还提供了EL表达式语言,大大简化了开发的难度

7.1.1什么是JavaBean

JavaBean:是Java开发语言中一个可以重复使用的软件组合,它本质上就是Java类。为了规范JavaBean的开发,Sun公司发布了JavaBean的规范,它要求一个标准的JavaBean组件需要遵循一定的编码规范,具体如下:
(1)它必须具有有个一个公共的,无参的构造方法,这个方法可以是编译器自动产生的默认构造方法
(2)它提供公共的setter方法和getter方法,让外部程序设置和获得JavaBean的属性

7.1.2访问JavaBean的属性

类的属性:指的是类的成员变量
JavaBean的属性:它和成员变量不是一个概念,它是以方法定义的形式出现的,这些方法必须具备一定的命名规范
例如,在JavaBean中包含一个String类型的属性name,那么在JavaBean中必须至少包含getName()和setName()方法中的一个,这两个方法的声明如下所示:

public String getName(){
	...//表示省略
}
public String setName(){
	...//表示省略
}
  • getName()方法:称为getter方法或者属性修改器,该方法以小写的get前开始,后跟属性名,属性名的第1个字母要大写,例如,nickName属性的getter方法为getNickName()
  • setName()方法:称为setter方法或者属性修改器,该方法必须以小写的set前缀开始,后跟属性名,属性名的第1个字母要大写,例如,nickName属性的getter方法为setNickName()

如果一个属性只有getter方法,则该属性为只读属性。如果一个属性只有setter方法,则该属性为只写属性。如果一个属性既有getter方法,又有setter方法,则该属性为读写属性。通常来说,在开发JavaBean时,其属性都定义为读写属性
注意:对于JavaBean属性的命名方式有一个例外情况。如果属性的类型为boolean,它的命名方式应该使用is/set,而不是get/set,例如,有一个boolean类型的属性married,命名格式如下:

public boolean isMarried(){
	...//此处省略
}
public void setMarried(boolean married){
	...//表示省略
}

7.1.3BeanUtils工具

BeanUtils:动态访问Java对象的属性,掌握它的使用有助于提高程序的开发效率,BeanUtils工具中封装了许多类,其中最核心的是org.apache.commons.beanutils包下的BeanUtils类。BeanUtils常用的方法如下:

方法名声明 功能描述
static void populate(Object bean,Map<String,?extends Object>properties) 根据指定的名称/值对为相应的JavaBean属性设置值
static void setProperty(Object bean,String name,Object value) 设置指定的属性值,传入的类型要求能转换成相应属性的类型
static String getProperty(Object bean,String name) 返回指定bean指定属性的值,返回值类型为String类型

7.2EL表达式

在JSP开发中,为了获取Servlet域对象中存储的数据,经常需要书写很多Java代码,这样的做法会使JSP页面混乱,难以维护,为此在JSP2.0规范中提供了EL表达式

7.2.1初识EL

EL:Expression Language的缩写,它是一种简单的数据访问语言。EL表达式的语法非常简单,都是以${表达式}为格式

7.2.2EL中的标识符

在EL表达式中,经常需要使用一些符号来标记一些名称,如变量名,自定义函数名等,这些符号被称为标识符。EL表达式中的标识符可以由任意的大小写字母,数字和下划线组成。为了避免出现非法标识符,在定义标识符需要遵循以下规范:
(1)不能以数字开头
(2)不能是EL中的保留子,如and,or,gt
(3)不能是EL隐式对象,如pageContext
(4)不能包含单引号,双引号,减号和正斜线等特殊字符

7.2.3EL中的保留字

保留字就是编程语言里事先定义好并赋予了特殊含义的单词,EL表达式中的这些保留字不能被作为标识符,以免在程序编译时发送错误

7.2.4EL中的变量

EL表达式中的变量就是一个基本的存储单元,EL表达式可以将变量映射到一个对象上,EL表达式中的变量不用事先定义就可以直接使用。具体格式如下:

${变量名}

7.2.5EL中的常量

EL表达式中的常量又称字面量,它是不能改变的数据
1.布尔常量:布尔常量用于区分一个事物的正反两面,它的值只有两个,分别是true和flase
2.整形常量
3.浮点数常量
4.字符串常量:是用单引号或双引号引起来的一连串字符。由于字符串常量需要单引号或双引号引起来,所有,字符串本身包含的单引号或双引号需要用反斜杠进行转义,即用"“表示字面意义上的单引号,用“””表示字面意义上的双引号。如果字符串本身包含反斜杠\,也要进行转义,即用\表示字面意义上的一个反斜杠
注意只有字符串常量用单引号引起来时,字符串本身包含的单引号才需要进行转义,而双引号不必进行转义;只有字符串常量用双引号引起来,字符串本身包含的双引号才需要转义,而单引号不必转义
5.Null常量:用于表示变量引用的对象为空,它只有一个值,用null表示

7.2.6EL中的运算符

1.点运算符:用于访问JSP页面中某些对象的属性,如JavaBean对象,List集合,Array数组等,其语法格式如下:

${customer.name}

上述语法的作用是访问customer对象中的name属性
2.方括号运算符:用于访问JSP页面中某些对象的属性。当获得属性名中包含一些特殊符号,如“-”或“?”等并非字母或数字的符号,就只能使用方括号运算符来访问该属性,其语法如下:

${user["My-name"]}

点运算符和方括号运算符的区别:
(1)点运算符和方括号运算符在某种情况下可以互换,${student.name}等价于${student["name"]}
(2)方括号运算符还可以访问List集合或数组中指定的索引的某个元素
(3)方括号运算符和点运算符可以相互组合使用
3.算术运算符
4.比较运算符
5.逻辑运算符
6.empty运算符:用于判断某个对象是否为null或“ ”,结果为布尔类型,其基本语法如下:

${empty var}

(1) var变量不存在,即没有定义,返回true
(2) var变量的值为null,就返回true
(3)var变量引用集合(Set,Map和List)类型对象,并且在集合对象中不包含任何元素时,则返回值为true
7.条件运算符
8.“()”运算符:用于改变其他运算符优先级
注意:在应用EL表达式取值的,没有数组的下标越界,没有空指针异常,没有字符串的拼接

7.2.7EL隐式对象

EL中的隐式对象共有11个,具体如下:

隐含对象名称 描述
pageContext 对应于JSP页面中的pageContext对象
pageScope 代表page域中用于保存属性的Map对象
requestScope 代表request域中用于保存属性Map对象
sessionScope 代表session域中用于保存属性的Map对象
applicationScope 代表application域中用于保存属性的Map对象
param 表示一个保存了所有请求参数的Map对象
paramValues 表示一个保存了所有请求参数的Map对象,它对于某个请求参数,返回的是一个String类型数组
header 表示一个保存了所有JTTP请求头字段的Map对象
headerValues 表示一个保存了所有HTTP请求头字段的Map对象,返回String类型数组
cookie 用来取得使用者的cookie值,cookie的类型Map
intParam 表示一个保存了所有Web应用初始化参数的Map对象

1.Web域相关对象
在Web开发中,pageContext,HttpServletRequest,HttpSession和ServletContext这个对象之所以可以存储数据,是因为它们内部都定义了体格Map集合,这些Map集合是一定作用范围的,例如,HttpServletRequest对象存储的数据只在当前请求中可以获取到。我们习惯把这些Map集合称为域,这些Map集合所在的对象称为域对象。在EL表达式中,为了获取指定的数据,提供了pageContext,HttpServletRequest,HttpSession和ServletContext4个隐式对象。注意:EL表达式只能在这4个作用域中获取数据
2.Cookie对象
在JSP开发中,经常需要获取客户端的Cookie信息,为此,在EL表达式中,提供了Cookie隐式,该对象是一个代表所有Cookie信息的Map集合,Map集合中元素的键位各个Cookie的名称,值则为对应的Cookie,具体如下:

获取cookie对象的信息:${cookie.userName}
获取cookie对象的名称:${cookie.userName.name}
获取cookie对象的值:${cookie.uaweName.value}

7.3JSTL

7.3.1什么是JSTL

从JSP1.1规范开始,JSP就支持使用自定义标签,使用自定义标签大大降低了JSP页面的复杂度,同时增强了代码的重用性。为此,许多Web应用厂商都定制了自身应用的标签库,然而同一功能的标签由不同的Web应用厂商可能是不同的,这就导致市面上出现了很多功能相同的标签,令网页制作者无从选择。为了解决这个问题 ,Sun公司制定了一套标准标签库,简称JSTL
JSTL:标准标签库,这个标签库是由5个不同功能的标签库共同组成的,具体如下:

标签库 标准库的URL 前缀
Core http://java.sun.com/jsp/jstl/core c
I18N http://java.sun.com/jsp/jstl/fmt fml
SQL http://java.sun.com/jsp/jstl/sql sql
XML http://java.sun.com/jsp/jstl/xml x
Functions http://java.sun.com/jsp/jstl/functions fn

(1)Core是一个核心库,它包含了实现Web应用中同样操作的标签。例如,用于输出文本内容的<c:out>标签,用于条件判断的<c:if>标签,用于迭代循环的的<c:foreEach>
(2)I18N是一个国际化/格式化标签库,它包含实现Web应用程序的国际化标签和格式化标签。例如,设置JSP页面的本地信息,设置JSP页面的时区,使日期按照本地格式显示等
(3)SQL是一个数据库标签库,它用于访问数据库和对数据库的中数据进行操作的标签。例如,从数据库中获得数据库连接,从数据库表中检索数据等。
(4)XML是一个操作XML文档的标签库,它包含对XML文档中的数据进行操作的标签。例如,解析XML文件,输出XML文档中的内容,以及迭代处理XML文档中的元素。XML广泛应用于Web开发,使用XML标签库处理XML文档更加简单方便
(5)Functions是一个函数标签库,它提供了一套自定义EL函数,包含了JSP页面制作者常要用到的字符串操作。例如,提取字符串中的子字符串,获取字符串的长度等

7.3.3JSTL中Core标签库

1.<c:out>标签:该标签可以将一段文本内容或表达式的结果输出到客户端。如果<c:out>标签输出的文本内容中包含需要进行转义的特殊字符,<c:out>标签会默认对它们进行HTML编码转换后再输出。<c:out>标签由两种语法格式,具体如下:

语法1:没有标签体的情况下:
<c:out value="value" [default="defaultValue"]
[escapeXml="{true|false}"]/>
语法2:有标签体的情况
<c:out value="value"  [escapeXml="{true|false}"]>
		defaultValue
</c:out>

再上述语法中,没有标签体的情况下,需要使用default属性指定默认值;有标签体的情况下,在标签体中指定输出的默认值。<c:out>有多个标签,具体如下:
(1)value属性用于指定输出的文本内容
(2)default属性用于指定当value属性为null时所输出的默认值,该属性是可选的
(3)escapeXml属性用于指定是否将特殊字符进行HTML编码转换后进行输出,默认值为true
注意只有当value属性值为null时,<c:out>标签才会输出默认值,如果没有指定默认值,则默认输出空字符串
2.<c:if>标签:专门用于完成JSP页面中的条件判断,它有两种语法格式:

语法1:没有标签体的情况下
<c:if test="testCondition" var="result"
[scope="{page|request|session|application}"]/>
语法2:有标签体的情况下
<c:if test="testCondition" var="result"
[scope="{page|request|session|application}"]/>
	body content
</c:if>

在上述语法中,<c:if>标签有三个属性,具体如下:
(1)test属性用于设置逻辑表达式
(2)var属性用于指定逻辑表达式中变量的名字
(3)scope属性用于指定var变量的作用范围,默认值为page。如果属性test的计算结果为true,那么标签体将被执行,否则标签体不会被执行
3.<c:choose>标签:该标签用于指定多个条件选择的组合边界,它必须与<c:when>,<c:otherwise>标签一起使用
(1)<c:choose>标签没有属性,在它的标签体中只能嵌套一个或多个<c:when>标签和零个或一个<c:otherwise>标签,并且同一个<c:choose>标签中所有的<c:when>子标签必须出现在<c:otherwise>子标签之前,其语法格式如下:

<c:choose>
	Body content(<when> and  <otherwise> subtags)
</c:choose>

(2)<c:when>标签只有一个test属性,该属性的值为布尔类型。test属性支持动态值,其值可以是一个条件表达式,如果条件表达式的值为true,就执行 这个<c:when>子标签体的内容,其语法格式如下:

<c:when test="testCondition">
	Body content
</c:otherwise>

(3)<c:otherwise>标签没有属性,它必须作为<c:choose>标签最后分支出现,当所有的<c:when>标签的test条件都不成立时,才执行和输出<c:otherwise>标签体的内容,其语法格式如下:

<c:otherwise>
	conditional block
</c:otherwise>

4.<c:forEach>标签:该标签专门用于迭代集合对象中的元素,如Set,List,Map,数组等,并且能重复执行标签体中的内容,它有两种语法格式,具体如下:

语法1:迭代包含多个对象的集合
<c:forEach [var="varName"] items="collection" [varStatus="varStatusName"]
[begin="begin"] [end="end"] [step="step"]>
	body content
</c:forEach>
语法2:迭代指定范围内的集合
<c:forEach [var="varName"] [varStatus="varStatusName"] begin="begin" end="end" [step="step"]>
	body content
</c:forEach>

在上述语法格式中,<c:forEach>标签有多个属性,具体属性作用如下:
(1)var属性用于指定将当前迭代到的元素保存到page域中的名称
(2)items属性用于指定将要迭代的对象
(3)varStatus属性用于指定当前迭代状态信息的对象保存到page域中的名称
(4)begin属性用于指定从集合中第几个元素开始进行迭代,begin的索引值从0开始。如果没有指定的items属性,就从begin指定的值开始迭代,直到迭代结束为止
(5)step属性用于指定迭代的步长,即迭代因子的增量
<c:forEach>标签的begin,end,step属性分别用于指定循环的起始索引,结束索引和步长。使用这些属性可以迭代集合对象中某一范围内的元素
<c:forEach>标签的varStatus属性用于设置一个javax.servlet.jsp.jstl.core.LoopTagStatus类型的变量,这个变量包含了从集合中取出元素的状态信息,使用<c:forEach>标签的varStatus属性可以获取以下信息:
(1)count:表示元素在集合中的序号,从1开始计数
(2)index:表示当前元素在集合中的索引,从0开始计数
(3)first:表示当前是否为集合中的第1个元素
(4)last:表示当前是否为集合中的最后一个元素
5.<c:param>标签和<c:url>标签
<c:param>标签:用于获取URL地址中的附加参数
<c:url>标签:用于按特定的规则重新构造URL
<c:redirect>标签:负责重定向
<c:param>标签:用于在URL地址中的附加参数,它通常嵌套在<c:url>标签内使用。<c:param>标签有两种语法格式,具体如下:

语法1:使用value属性指定参数的值
<c:param name="name" value="value">
语法2:在标签体中指定参数的值
<c:param name="name">
	parameter value
</c:param> 

在上述语法中,<c:param>中有两个属性:
(1)name属性用于指定参数的名称
(2)value属性用于指定参数的值,当使用<c:param>标签为一个URL地址附近参数时,它会自动对参数值进行URL编码
<c:url>标签:该标签可以在JSP页面中构造一个新的地址,实现URL的重写。<c:url>标签有两种语法格式,具体如下:

语法1:没有标签实体的情况
<c:url value="value" [context="cotext"] [var="varName"]
[scope="{page|request|session|application}"]>
语法2:在标签实体的情况,在标签体重指定构造URL参数
<c:url value="value" [context="cotext"] [var="varName"]
[scope="{page|request|session|application}"]>
	<c:param>标签
</c:url>

在上述语法中,<c:url>标签中有多个属性,具体如下:
(1)value属性用于指定构造的URL
(2)context属性用于指定导入同一个服务器下其他Web应用的名称
(3)var属性用于指定将构造的URL地址保存到域对象的属性名称
(4)scope属性用于指定将构造好的URL保存到域对象中

猜你喜欢

转载自blog.csdn.net/weixin_44516267/article/details/89536972