JavaWeb之EL和自定义标签
EL 表达式
使用它可以极大的便利 JSP 页面中的数据获取和处理
语法结构
所有的 EL 都是以 ${ 为起始,以 } 为结尾
EL 变量
${username} 表示取出某一范围内名称为 username 的变量,因为此时并没有指定哪个范围的 username,所以它的默认情况下会先从 Page 范围找,如果找不到,会依次从 Request、Session、Application 范围,直到找到值回传,如果没找到,返回 null。
案例
在 testel.jsp 页面中,首先在头部需要注明开启 EL 表达式:
当前页面存取 session 值
1、
运行结果:
以上取值方式等同于:
方式一针对某个范围内进行查找,而方式二没有指定,则默认从 Page 开始查找。
注意:
如果在存 session 的 key 里面含有特殊字符,则应使用 [] 来取值
2、
由图,新建一个用户实体,分别设置属性,并取值。
3、
提交表单数据并当前页面并显示:
执行结果:
方式一采用的以往通过 JSP 内置对象的 request 来获取参数,而方式二采用 EL 表达式来获取,
4、
执行结果
由结果得知,EL 可以自动进行类型转换
EL 隐含对象
与范围有关的:
applicationScope、sessionScope、requestScope、pageScope
与输入有关的:
param、paramValues
其他隐含对象:
cookie、header、headerValues、initParam、pageContext
对于 pageContext 对象:
即为 PageContext 类型,但只能读取属性就可以一直“.”下去
由图可以获取相关等属性
Empty 属性
可以作用于一个集合,若集合不存在或者集合没有元素,则结果为 true
自定义标签
概念:
用户定义的一种自定义的 JSP 标记,当一个含有自定义标签的 JSP 页面被 JSP 引擎编译成 Servlet 时,tag 标签被转化成了对一个称为标签处理类的对象的操作。所以,当 JSP 页面被 JSP 引擎转化成 Servlet 后,实际上 tag 标签被转化为对 tag 处理类的操作。使用自定义标签可以降低 JSP 开发的复杂度和维护量
编写自定义标签:
核心是编写处理类,一个标签对应一个标签处理器类,而一个标签库则是很多标签处理器的集合,所有标签处理器都要实现 JspTag 接口,该接口中没有定义任何方法,主要作为 Tag 和 SimpleTag 接口的父接口。
标签形式:
1、空标签:<hello/>
2、带有属性的空标签:<max num1="3" num2="5"/>
3、带有内容的标签:<greeting>hello</greeting>
4、带有内容和属性的标签:<greeting name="tom">hello<greeting/>
编写步骤:
1、表写完成标签功能的 java 类(标签处理器)
2、编写标签库描述(tld)文件,在 tld 文件中对自定义标签进行描述
3、在 JSP 页面中导入和使用自定义标签
案例:
确保项目中已导入如下 jar 包:
在 tag 包下新建 HelloSimpleTag 标签处理器类并实现 SimpleTag
然后在 WEB-INF 下新建 mytag.tld 配置文件
头部信息与 core 一致
<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">
完成以上步骤后在 JSP 引用该 tag
通过引用,可以对照 mytag.tld 的配置文件说明。
重启 tomcat
通过运行结果可以看出,执行了 HelloSimpleTag 里的 setJspContext 方法和 doTag 方法。
实现 SimpleTag 接口的标签处理类的生命周期:
1、setJspContext
JSP 引擎将代表 JSP 页面的 pageContext 对象传递给标签处理器对象
2、setParent
JSP 引擎将父标签处理器对象传递给当前标签处理器对象。只有存在父标签时,JSP 引擎才会调用该方法
3、setXXX
设置标签属性,只要定义属性才调用该方法
4、setJspBody
若存在标签体,JSP 引擎将把标签体封装成一个 JspFragment 对象,调用 setJspBody 方法将 JspFragment 对象传递给标签处理器对象,若标签体为空 setJspBody 将不会被 JSP 引擎调用
5、doTag
容器调用标签处理器对象的 doTag 方法执行标签逻辑
对于 setJspContext,在方法里把 jspContext 对象赋予全局变量 pageContext,这样就能获取到 JSP 中的所有隐含对象。
编写带属性的标签
首先,在 tld 配置文件下添加如下内容
注:rtexprvalue 表示的是 runtime expression value
然后在 HelloSimpleTag 类下添加两个成员变量 value 和 count 用来接收参数,强烈建议使用 String 类型的参数,并且实现两者的 set 方法。
接着在 doTag 里面获取参数,并且进行逻辑处理
最后在 JSP 里面引用标签
如果是接收动态值可以这么写
如果重新新建了 tag 类,只需在 tld 配置文件里面重新添加 tag 标签,并进行属性的说明
通常情况下,开发简单标签直接继承 SimpleTagSupport 就可以,可以直接调用其对应的 getter 方法得到对应的 API
编写带标签体的自定义标签
1、在自定义标签的标签处理器中使用 JspFragment 对象封装标签体信息
2、若配置了标签含有标签体,则 JSP 引擎会调用 setJspBody() 方法把 JspFragment 传递给标签处理类,在 SImpleTagSupport 中还定义了一个 getJspBody() 方法,用于返回 JspFragment 对象
3、JspFragment 的 invoke(writer)方法:把标签体内容从 Writer 中输出,若为 null,则等同于 invoke(getJspContext().getOut()),即直接把标签体内容输出到页面上
4、在 tld 文件中,使用 body-content 节点来描述标签体的类型:
empty:没有标签体
scriptless:标签体可以包含 el 表达式和 JSP 动作元素,但不能包含 JSP 的脚本元素
说明:
由图,第一种属于 el 表达式,第二种表示 JSP 脚本元素。
tagdependent:表示标签体交由标签本身去解析处理,若指定 tagdependent,在标签体中的所有代码都会原封不动的交给标签处理器,而不是将执行结果传递给标签处理器
大部分情况下,类型取值为 scriptless
如图,获取标签体的内容,并转换成大写打印在页面上
编写带父标签的自定义标签
编写一个父标签 TestParentTag,并编写一个子标签 TestSonTag,在 JSP 引用的时候,父标签在控制台打印信息,子标签作为父标签的标签体在页面上显示父标签的内容
TestParentTag:
TestSonTag:
tld 配置:
JSP 引用:
运行结果:
通过案例可以得出:
1、父标签无法获取子标签的引用,父标签仅把子标签作为标签体来使用
2、子标签可以通过 getParent() 来获取父标签的引用(需继承 SimpleTagSupport 或实现 SimpleTag 接口的该方法),若子标签的确有父标签,JSP 引擎会把代表父标签的引用通过 setParent(JspTag parent) 赋给标签处理器
3、父标签的类型是 JspTag 类型,该 JspTag 接口为空接口,用来统一 SimpleTag 和 Tag 的,简单标签和传统标签
4、在 tld 配置文件中,不需要为父标签有额外的配置,但子标签是以标签体的形式存在的,所以父标签的 body-content 需要设置为 scriptless
JSTL fn 函数
为了简化在 JSP 页面操作字符串,JSTL 中提供了一套 EL 自定义函数,这些自定义函数包含了 JSP 页面经常用到的字符串操作
使用方法如下:
如图,在头部引用函数的声明,然后通过 ${fun:contains("name", "a")} 来操作字符串
以上为本人的一些学习笔记,如有出错欢迎指正,陆续更新!!!