java:EL表达式
EL表达式:
1)el表达式主要用于获取数据,它的原理是:通知JSP引擎调用pageContext.findAttribute()方法,以标识符为关键字从各个域中先后( page ——
request —— session —— application )获取对象,如果在一个域中获取到了,则不再从下个域中寻找,返回结果。如果域对象中不存在标识符所对应
的对象,则返回结果为””(注意,不是null)。
2)EL表达式的四大作用:
>> 获取数据(重点)
>> 执行运算
>> 获取web开发对象
>> 调用java方法
3)可用page指令的isELIgnored属性类控制页面忽略所有的EL表达式,此时,所有的EL表达式都会被当成一个普通的字符串来处理:
<%@ page isELIgnored="false" %> // 默认为false
1、EL作用之一:获取数据
1)获取四个域中的值:
a、
<%
pageContext.setAttribute("key", "el_page");
request.setAttribute("key", "el_request");
%>
key:${key}
<%-- 输出结果为:el_page --%>
b、
<c:set var="username" value="张三" scope="page" ></c:set>
username: ${username}
username: ${pageScope.username}
2)获取存储在四个域中的JavaBean对象的属性值 ${beanName.属性名 } :
举例:
a、
<jsp:useBean id="student" class="cn.itcast.web.domain.Student" scope="page"/>
<jsp:setProperty name="student" property="name" value="张三" />
<jsp:setProperty name="student" property="age" value="30" />
<jsp:setProperty name="student" property="ID" value="24" />
<%-- 输出结果为:张三,30,24 --%>
姓名:${student.name}<br/>
年龄:${student.age}<br/>
ID:${student.ID}<br/>
注意:当使用EL表达式获取javaBean的属性的值时,前提是:这个对象必须是存进域中的,如果student对象时以普通方式创建,
即:Student student = new Student(24,"张三",30),则返回的结果为””(空串)。因为底层用的方式是:pageContext.findAttribute()
b、使用jstl设置javaBean的属性,用EL表达式获取(推荐):
<jsp:useBean id="student" class="cn.itcast.web.jsp.domain.Student" scope="request"></jsp:useBean>
<c:set target="${student}" property="name" value="张三" ></c:set>
<c:set target="${student}" property="age" value="15" ></c:set>
student.getName:${student.name}<br/>
student.getAge :${student.age}
3)在多个对象中导航的时候,如: ${XXX . YYY . ZZZ}
首先会调用pageContext.findAttribute(“XXX”)的方法,在四个域中寻找XXX的对象,接着是调用getYYY()的方法找到YYY对象,再调用getZZZ()
的方法得出结果,即:pageContext.findAttribute().getYYY().getZZZ()前提是:XXX、YYY对象也是存在与四个域中的!
${student.name.class.name}:
用意:pageContext.findAttribute("student").getName().getClass().getName();
但因为pageContext.findAttribute("student").getName().getClass()返回的是:java.lang.String.class的对象,而这个对象并没有存
在四个域中,而且经过验证,无法将Class字节码存入域对象:<jsp:useBean id="class" class="java.lang.Class" />
因为id的值在此表示对象的引用变量,而class为java中的保留关键字,所以无法用这种方式!!所以这样做是错误的。
4)获取数组、Collection、Map类型集合的数据(重点)
a、获取List集合的元素
<%
List<String> strList = new ArrayList<String>();
strList.add("haha"); strList.add("hehe"); strList.add("xixi");
session.setAttribute("strList", strList); // 别忘了把集合绑定到域中
%>
第一个用户:${strList[0]}<br/>
第二个用户:${strList[1]}<br/>
第三个用户:${strList[2]}<br/>
<c:forEach var="name" items="${strList}">
${name} <%-- haha hehe xixi --%>>
</c:forEach>
b、获取Map集合的元素,注意Map集合的取出方式,调用的是entrySet的方法
<%
Map<String,Student> map = new HashMap<String,Student>();
Student s1 = new Student("A111","张三",12); Student s2 = new Student("B222","李四",12);
Student s3 = new Student("C333","王五",12);
map.put(s1.getId(), s1); map.put(s2.getId(), s2); map.put(s3.getId(), s3);
application.setAttribute("studentMap", map); // 别忘了把集合绑定到域中
%>
${studentMap}<br/>
<c:forEach var="entry" items="${studentMap} >
学生的编号:${entry.key}<br/>
学生的姓名:${entry.value}<br/>
</c:forEach>
c、获取Set集合的元素
<%
Set<String> set = new HashSet<String>();
set.add("aaaaaaa");
set.add("bbbbbbb");
pageContext.setAttribute("set", set); // 别忘了把集合绑定到域中
%>
${set}<br/> <%-- [bbbbbbb, aaaaaaa] --%>
<c:forEach var="str" items="${set}">
${str}<br/>
</c:forEach>
d、获取数组的元素
<%
int [] array = {1,2,3,4,5};
pageContext.setAttribute("array", array, PageContext.SESSION_SCOPE); // 别忘了把数组绑定到域中
%>
第二个值:${array[1]}<br/>
<c:forEach var="intValue" items="${array}">
${intValue}<br/>
</c:forEach>
2、EL作用之二:执行简单的运算和逻辑判断
示例:
${1==1}<br/> <%--true--%>
${5+4}<br/><%--9--%>
${student.age + 10}<br/><%--40--%>
${student.age > 20 && student.age < 50}<br/><%--true--%>
三种EL表达式中经常使用的运算符和一种表达式:
1、empty运算符 :检查变量是否为null或“空”,很好用!!!
2、二元表达式 :${user!=null?user.name : “”} ,很好用!!!
3、[ ] 和 . 号运算符
<c:set var="user" value="王五" scope="page" />
<c:remove var="user" scope="page" />
欢迎${!empty user ? user : "游客"}光临!!
<hr/>
数据回显:
<c:set var="city" value="广州" />
<select>
<option ${city == "广州" ? "selected" : ""}>广州</option>
<option ${city == "上海" ? "selected" : ""}>上海</option>
<option ${city == "北京" ? "selected" : ""}>北京</option>
</select>
3、EL表达式作用之三:获取WEB开发常用对象
- EL表达式语言中定义了11个隐含对象,使用这些隐含对象可以很方便地获取web开发中的一些常见对象,并读取这些对象的数据。
- 语法:${隐式对象名称}
<%--1、利用pageContext把当前的web应用路径写活: --%>
<a href="${pageContext.request.contextPath}/result.jsp" target="_blank">点击</a>
<%--
底层用的方法就是:
HttpServletRequest req = (HttpServletRequest)pageContext.getRequest();
String contentPath = req.getContextPath();
--%>
<%--2、在指定的域中获取绑定的对象 --%>
<c:set var="user" value="pageScope_user" scope="page" />
<c:set var="user" value="requestScope_user" scope="request"/>
<c:set var="user" value="sessionScope_user" scope="session"/>
<c:set var="user" value="applicationScope_user" scope="application"/>
用户:${pageScope.user}<br/>
用户:${requestScope.user}<br/>
用户:${sessionScope.user}<br/>
用户:${applicationScope.user}<br/>
<%--3、测试param与paramValues,地址栏访问:
http://localhost:8080/jsp/el.jsp?sex=nan&like=basketball&like=football&like=swim --%>
性别:${param.sex}<br/>
<%--底层代码:针对于一个参数
String sex = pageContext.getRequest().getParameter("sex");
--%>
第一个爱好:${paramValues.like[0]}<br/>
第二个爱好:${paramValues.like[1]}<br/>
第三个爱好:${paramValues.like[2]}<br/>
<%--底层代码:针对多个同名参数
String [] like = pageContext.getRequest().getParameterValues("like");
--%>
<%--4、测试header与headerValues --%>
请求头:${header}<br/>
请求头:${header.host}<br/>
请求头:${header.cookie}<br/>
请求头:${headerValues['Accept-Encoding'][0]}<br/>
请求头:${headerValues['Accept-Language'][0]}<br/>
<%--
测试headerValues时,如果头里面有“-” ,例Accept-Encoding,则
要headerValues[“Accept-Encoding”]
--%>
<%--5、测试cookie与initParam --%>
<%
Cookie cookie = new Cookie("password", "123456");
cookie.setMaxAge(24*60);
response.addCookie(cookie);
%>
cookie的名:${cookie.password.name}<br/>
cookie的值:${cookie.password.value}<br/>
<%--
测试cookie时,例${cookie.key}取的是cookie对象,如访问cookie的名称和值,须${cookie.username.name}或${cookie.username.value}。
new Cookie(“username”,”jack”);
--%>
web初始化参数:${initParam.tel}<br/>
web初始化参数:${initParam.email}<br/>
<%--
<context-param>
<param-name>tel</param-name>
<param-value>123</param-value>
</context-param>
<context-param>
<param-name>email</param-name>
<param-value>xxx@qq.com</param-value>
</context-param>
--%>
4、EL表达式作用之四:调用java方法
EL表达式语法允许开发人员开发自定义函数,以调用Java类的方法。
示例:${prefix:method(params)}
1)在EL表达式中调用的只能是Java类的静态方法。
2)这个Java类的静态方法需要在TLD文件中描述,才可以被EL表达式调用。
3)EL自定义函数用于扩展EL表达式的功能,可以让EL表达式完成普通Java程序代码所能完成的功能。
4)EL函数只能访问与WEB无关的需求,与WEB有关的需求还是需要使用自定义标签来解决。
一般来说, EL自定义函数开发与应用包括以下三个步骤:
1)编写一个Java类的静态方法。
2)编写标签库描述符(tld)文件,在tld文件中描述自定义函数,在WEB-INF/目录下。
3)在JSP页面中导入和使用自定义函数。
1) 写一个普通类,在其中写一个静态的方法
public class Filter {
// 转义方法
public static String filter(String message) {
return null;
}
}
2)tld文件的配置:
<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.0</tlib-version>
<short-name>el</short-name> // 函数的前缀
<uri>http://java.sun.com/jsp/jstl/el</uri>
<function>
<name>filter</name>
<function-class>cn.itcast.web.jsp.el.Filter</function-class>
<function-signature>java.lang.String filter(java.lang.String)</function-signature>
</function>
</taglib>
3)在JSP页面中引用自定义EL函数
<%@ page language="java" pageEncoding="UTF-8"%>
<%@ taglib uri="http://java.sun.com/jsp/jstl/el" prefix="el" %>
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<body>
${el:filter("<a href='#'>点点</a>")}<br/>
</body>
</html>
开发EL Function注意事项:
1)编写完标签库描述文件后,需要将它放置到<web应用>\WEB-INF目录中或WEB-INF目录下的除了classes和lib目录之外的任意子目录中。
2)TLD文件中的<uri> 元素用指定该TLD文件的URI,在JSP文件中需要通过这个URI来引入该标签库描述文件。
<function>元素用于描述一个EL自定义函数,其中:
<name>子元素用于指定EL自定义函数的名称。
<function-class>子元素用于指定完整的Java类名。
<function-signature>子元素用于指定Java类中的静态方法的签名,方法签名必须指明方法的返回值类型及各个参数的完整类型,
各个参数之间用逗号分隔。
EL注意事项:
EL表达式是JSP 2.0规范中的一门技术 。因此,若想正确解析EL表达式,需使用支持Servlet2.4/JSP2.0技术的WEB服务器。
注意:有些Tomcat服务器如不能使用EL表达式
1)升级成tomcat6/7
2)升级JSTL的JAR包
3)在JSP中加入<%@ page isELIgnored="false" %> 即,告诉JSP引擎不忽略EL表达式语言。
4)struts中不推荐使用EL表达式,而struts使用的是OGNL(对象导航语言)