1、EL表达式简介:
EL 全名为Expression Language。
主要的作用:
a.获取数据:
EL表达式主要用于替换JSP页面中的脚本表达式,以从各种类型的web域 中检索java对象、获取数据。
(某个web域 中的对象,访问javabean的属性、访问list集合、访问map集合、访问数组)
b.执行运算:
利用EL表达式可以在JSP页面中执行一些基本的关系运算、逻辑运算和算术运算,
以在JSP页面中完成一些简单的逻辑运算。${user==null}
c.获取web开发常用对象
EL 表达式定义了一些隐式对象,利用这些隐式对象,web开发人员可以很轻松获得对web常用对象的引用,从而获得这些对象中的数据。
d.调用Java方法
EL表达式允许用户开发自定义EL函数,以在JSP页面中通过EL表达式调用Java类的方法。
2、EL表达式获取数据:
EL表达式语句在执行时,会调用pageContext.findAttribute方法,
用标识符为关键字,分别从page、request、session、application四个域中查找相应的对象,
找到则返回相应对象,找不到则返回”” (注意,不是null,而是空字符串)。
语法是:${user}
可以操作javaBean对象,拿到里面的属性值
例如:这个里面的对象就自己去定义(比较简单)
<body>
<%
User user = new User() ;
user.setUsername("MyName") ;
user.setAge(20) ;
Friend f = new Friend() ;
f.setName("FriendName") ;
Cat[] cs = new Cat[2] ;
cs[0] = new Cat("喵喵","白色") ;
cs[1] = new Cat("咪咪","黑色") ;
f.setCats(cs) ;
user.setFriend(f) ;
//将数据放入某个域对象
session.setAttribute("user", user) ;
//从List中拿数据
List<String> list = new ArrayList<String>() ;
list.add("11111") ;
list.add("22222") ;
request.setAttribute("list", list) ;
List<User> list1 = new ArrayList<User>() ;
list1.add(user) ;
request.setAttribute("list1", list1) ;
//从集合中拿数据
Map<String,User> map = new HashMap<String,User>() ;
map.put("a", user) ;
request.setAttribute("map", map) ;
%>
el表达式支持对象的导航:<br>
拿到user的名字: ${user.username} || ${user["username"] }<br>
拿到user的friend的名字: ${user.friend.name} || ${user["friend"]["name"] }<br>
拿到user的friend的第一只猫的名字: ${user.friend.cats[0].name} || ${user["friend"]["cats"][0]["name"] }<br>
拿到user的friend的第二只猫的颜色: ${user.friend.cats[1].color} || ${user["friend"]["cats"][1]["color"] }<br>
<hr>
拿到list集合中的所有数据:${list} <br>//会将list中所有数据输出来
拿到list集合中的第一个数据:${list[0]} <br>
集合数据的导航:${list1[0].friend.cats[0].color }<br>
<hr>
拿到map中的所有的数据: ${map }<br>
拿到map中的第一个值: ${map["a"].friend.cats[1].color }<br>
</body>
3、EL表达式运算符:(比较简单)
例如:
<body>
<%
request.setAttribute("n", 10) ;
List<String> list = new ArrayList<String>() ;
list.add("aaaaaaa") ;
request.setAttribute("list", list) ;
User user = null ;
request.setAttribute("user", user) ;
%>
<hr>
对二元运算符的支持:${3+4 } || ${n + 10} || ${n/4 } || ${5 / n }<br>
对比较运算符的支持: ${n>10 } || ${n gt 10} || ${n == 10 }<br>
对逻辑运算符的支持: ${n > 5 && n < 10 } || ${n > 5 and n < 10 }<br>
对 三元运算符的支持: ${n>5?"真的":"假的" } <br>
对empty运算符的支持: ${empty list } || ${not empty list } <br>
判断对象是否为null: ${empty user} || ${not empty user}<br>
${user }
${pageContext.request.contextPath } //拿到工程路径名称
</body>
4、EL表达式的11个隐式对象:
例如:
<body>
<%
pageContext.setAttribute("name", "name1") ;
request.setAttribute("name", "name2") ;
session.setAttribute("name", "name3") ;
application.setAttribute("name", "name4");
%>
默认按从小到大的范围去找:${name }<br>
利用requestScope这个对象,可以直接从request范围中去拿数据:${requestScope.name }<br>
</body>
5、EL表达式-自定义函数:
为什么要自定义函数呢?在el表达式里面,对字符串的操作只支持 == 和 != ,如果我想取一个字符串的长度
那么久没办法了。
例如:
<%
request.setAttribute("s", "abc") ;
%>
${s == "abc" }//ture
${s != "abc" }//false
具体操作:
a.在src里面创建一个包(com.example.function)定义一个class,创建一个函数(必须是static的)
public class Demo {
//此方法和页面的upper方法对应,注意一定要是static
public static String upper(String s){
return s.toUpperCase() ;
}
}
b.在WEB-INF目录下建立一个扩展名为tld(Tag Libary Definetion,标签库描述文件)的xml文件.
(只要是在lib文件夹外都行,不管你有几层目录)
如果你对头文件不熟悉不知道怎么写,可以查看工程中的
jstl-1.2.jar中的模板(jstl-1.2.jar --- META-INF --- fn.tld)
例如:a.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.1</tlib-version>
<short-name>fn</short-name>
<!-- 命名空间 -->
<uri>http://java.sun.com/myfunction</uri>
<function>
<!-- name表示页面上函数的名字 -->
<name>upper</name>
<function-class>com.example.function.Demo</function-class>
<!-- 注意一定要写包名,除了8个基本数据类型,这个upper可以和页面上的upper名称不一样 -->
<function-signature>java.lang.String upper(java.lang.String)</function-signature>
</function>
</taglib>
c.在jsp页面中导入自定义的函数
<%@ taglib uri="http://java.sun.com/myfunction" prefix="fun" %>
d.在jsp页面中使用
<body>
${fun:upper("abc") }//这个fun就是你taglib中prefix属性设置的
</body>
注意:如果prefix="fun1" , 那么你使用就是:${fun1:upper("abc") }
访问这个jsp页面,就会输出 ABC
很多情况下我们不需要自己定义,sun公司已经定义好了
<%@ taglib uri="http://java.sun.com/jsp/jstl/functions" prefix="fn" %>
${fn:upper("abc") }
6、自定义标签:
jstl标签库(java standard tag lib)
过程类似自定义方法。
a.在后台创建一个class
需要实现一个SimpleTag接口,因为我们实现这个接口比较麻烦,
sun公司给了个已经实现SimpleTag接口的类,我们只需要继承这个类(SimpleTagSupport)
然后重写里面的方法就可以了
//演示输出当前时间
com.example.jstl
public class ShowTime extends SimpleTagSupport{
@Override
public void doTag() throws JspException, IOException {
//获得当前的时间
Date d = new Date() ;
//获得pageContext对象,看javaee帮助可以看到,PageContext是继承JspContext的,所以可以强转
PageContext pagecontext = (PageContext)getJspContext() ;
//获取输出流对象
JspWriter out = pagecontext.getOut() ;
//向页面输出
out.write(d.toLocaleString()) ;
}
}
b.在WEB-INF目录下建立一个扩展名为tld(Tag Libary Definetion,标签库描述文件)的xml文件.
a.tld
模板可以参考
jstl-1.2.jar中的模板(jstl-1.2.jar --- META-INF --- c-1-0-rt.tld(第一个最新))
例如:
<?xml version="1.0" encoding="ISO-8859-1" ?>
<!DOCTYPE taglib
PUBLIC "-//Sun Microsystems, Inc.//DTD JSP Tag Library 1.2//EN"
"http://java.sun.com/dtd/web-jsptaglibrary_1_2.dtd">
<taglib>
<tlib-version>1.0</tlib-version>
<jsp-version>1.2</jsp-version>
<short-name>my</short-name>
<uri>http://java.sun.com/myjstl</uri>
<tag>
<name>showTime</name>
<tag-class>com.example.jstl.ShowTime</tag-class>
<body-content>empty</body-content>
</tag>
</taglib>
c.在jsp页面中导入自定义的标签
<%@ taglib uri = "http://java.sun.com/myjstl" prefix="my" %>
d.在jsp页面中使用
<body>
<!-- 显示当前时间 -->
<my:showTime/>
</body>
访问jsp页面,可以看到输出的结果:2017-7-14 23:10:36
这个的执行原理就是:执行到<my:showTime/>的时候,就看prefix="my" 对应的命名空间,
是【uri = "http://java.sun.com/myjstl"】,jsp引擎就在WEB-INF中,查找每一个tld文件的uri,
找到了showTime标签,然后就执行java代码。
7、自定义标签-body-content的取值:
JSP:不要考虑。(给传统标签处理类用的)
empty:传统和简单标签都能用的。开始标签和结束标签没有主体内容时用。
scriptless:给简单标签用的。开始标签和结束标签有主体内容时用。但是内容不能有<%
tagdependent:给简单标签用的。告诉标签处理类,主体内容是普通的文本
例如:控制标签的部分内容不显示
<tag>
<name>demo1</name>
<tag-class>com.heima.jstl.Demo1</tag-class>
<body-content>tagdependent</body-content>
</tag>
在Demo1的doTag中不做任何处理
你好<my:demo1>隐藏了</my:demo1>
输出的结果就是:你好