EL表达式:从JSP2.0开始成为规范,是的原来用scriptlet和表达式完成的事情,EL都能完成
1.配置相关
${applicationScope.name} 等价于 <%=application.getAttribute(“name”)%>
它的好处在于,可以不要求WEB页面设计人员懂Java,还有可以让JSP省略大篇幅的java代码,减少维护难度
以下是在web.xml中配置禁用JSP中使用脚本元素:表示针对所有JSP,禁用掉脚本元素
注意: <%@ page isScriptionEnabled = “false”%>在规范中已经没有了
*.jsp true 如果要忽略EL表达式,则可以有两种配置,一种是指令配置,一种是web.xml配置(指令配置优先级高!)
<%@ page isElIgnored=”true” %>
*.jsp true
2.EL表达式:${person.name}总是放到大括号里
优势:假如有一个Person类,类里有个 setDog,所以我们还得有个Dog类。如果不使用EL表达式,用标准动作来获取,你会发现
<jsp:useBean id=”Person” class=”cn.xx.Person” scope=”request”/>
狗狗的名字是:<jsp:getProperty name=”Person” property=”dog”/>
你希望得到的是狗的 名字 ,实际得到的是 Dog的 toString()返回的结果,而 propety=“dog.name”是不可以的,等于标准动作不能获取类似这样嵌套的性质值(Dog是属性,name是性质值)。而用脚本的话你可以这样
<%= ( (cn.xx.Person) request.getAttribute(“Person”) ).getDog.getName() %>
用EL表达式你更可以这样
${Person.dog.name}
3.EL表达式的隐式对象: 表达式中第一个命名变量可以是一个隐式对象,也可以是一个属性
EL隐式对象与JSP脚本中可用的隐式对象不同,只有pageContext除外。
pageScope
将页面范围的变量名称映射到其值。例如,EL 表达式可以使用 ${pageScope.objectName} 访问一个 JSP 中页面范围的对象,还可以使用 ${pageScope.objectName.attributeName} 访问对象的属性。 作用域属性的MAP
requestScope
将请求范围的变量名称映射到其值。该对象允许访问请求对象的属性。例如,EL 表达式可以使用 ${requestScope.objectName} 访问一个 JSP 请求范围的对象,还可以使用 ${requestScope.objectName.attributeName} 访问对象的属性。 作用域属性的MAP
sessionScope
将会话范围的变量名称映射到其值。该对象允许访问会话对象的属性。例如:$sessionScope.name}
作用域属性的MAP
applicationScope
将应用程序范围的变量名称映射到其值。该隐式对象允许访问应用程序范围的对象。 作用域属性的MAP
param
将请求参数名称映射到单个字符串参数值(通过调用 ServletRequest.getParameter (Stringname) 获得)。getParameter(String) 方法返回带有特定名称的参数。表达式 $(param.name) 相当于 request.getParameter (name)。 请求参数的MAP
paramValues
将请求参数名称映射到一个数值数组(通过调用 ServletRequest.getParameter (Stringname) 获得)。它与 param 隐式对象非常类似,但它检索一个字符串数组而不是单个值。表达式${paramvalues.name)相当于 request.getParamterValues 请求参数的MAP
header
将请求头名称映射到单个字符串头值(通过调用 ServletRequest.getHeader(Stringname) 获得)。表达式 ${header.name} 相当于request.getHeader(name)。 请求首部的MAP
headerValues
将请求头名称映射到一个数值数组(通过调用 ServletRequest.getHeaders(String)获得)。它与头隐式对象非常类似。表达式${headerValues.name} 相当于 request.getHeaderValues(name)。 请求首部的MAP
cookies
将 cookie 名称映射到单个 cookie 对象。向服务器发出的客户端请求可以获得一个或多个 cookie。表达式 ${cookie.name.value} 返回带有特定名称的第一个 cookie 值。如果请求包含多个同名的 cookie,则应该使用 ${headerValues.name} 表达式。 initParam
将上下文初始化参数名称映射到单个值(通过调用 ServletContext.getInitparameter(String name) 获得)。 上下文初始化的MAP
pageContext
JSP页的上下文。它可以用于访问 JSP 隐式对象,如请求、响应、会话、输出、servletContext 等。例如,${pageContext.response} 为页面的响应对象赋值。(在所有隐式对象中,只有该对象不是映射,而是实际引用!pageContext是一个javabean) 它是唯一一个实际引用,是bean
4.操作符 . 和 []
使用点号(.)操作符访问性质和映射值
${Person.name} 第一个变量可以是一个隐式对象,也可以是一个属性,点号右边可以是一个 映射键(第一个变量是映射),也可以是一个bean性质(第一个变量是javaBean属性),而 pageContext隐式对象是一个Bean,它有获取方法,所以其他隐式对象都是Map
使用[]操作符(比.操作符更加强大和灵活)
${Person[“name”]}
.号操作符之所以能工作,是因为Person是一个bean,而name是Person的一个性质值,而且左边只能是一个Map或bean,右边要遵循java标示符中相关的命名规则。如果使用[]时,左边可以是List或数组,右边可以是一个数。
${musicList[“something”]}
示例:对数组使用[]操作符
java/servlet中:
String[] favoriteMusic = {“Two 1”,”HaHa”“Java”,”BT MOVE”};
request.setAttribute(“musicList”,favoriteMusic);
JSP: ${musicList[0]} 或者 ${musicList[“0”]} 都是可以的,因为数组和List中的String索引会强制转成int(对于EL表达式来说,[]操作符并不是数组访问操作符),但是像${musicList[“one”]是不行的,因为one不能转换为int
java.util.Map musicMap = new java.util.HashMap();
musicMap.put("aaa","wahaha"); musicMap.put("bbb","hehhehe"); musicMap.put("ccc","yiyiyi"); musicMap.put("ddd","xixixi"); request.setAttribute("musicMap", musicMap);对于Map,则可以用 ${musicMap[“aaa”]}获取值,它会根据这个键去寻找对应的值,但不可以${musicMap[aaa]},因为容器会去计算搜索该名字绑定的属性,很明显,这里没有aaa绑定的属性。
但是如果加上了 request.setAttribute("gggg", “aaa”);你就可以使用${musicMap[gggg]}这样。
以上的原因在于,中括号没有引号,容器就会计算中括号的内容,搜索与该名字绑定的属性,并替换为该属性的值,在上面的例子中,由于有一个名为“gggg”的请求属性,它的值是“aaa”,而”aaa”是musicMap里一个键,所以${musicMap[gggg]}会被容器计算为${musicMap[“aaa”]},但是这里如果是 ${musicMap[“gggg”]}则不行,因为容器不会计算,它会把引号里的值当作MAP里的键,去寻找值,结果当然找不到了
中括号操作符还可以嵌套:
java.util.Map musicMap = new java.util.HashMap();
musicMap.put("aaa","wahaha"); musicMap.put("bbb","hehhehe"); musicMap.put("ccc","yiyiyi"); musicMap.put("ddd","xixixi"); request.setAttribute("musicMap", musicMap); String[] musicTypes = {“aaa“,”bbb“,”ccc“,”ddd“}; request.setAttribute(“MusicTypes”,musicTypes );${musicMap[MusicType[0]} 等于 ${musicMap[“aaa”]}
操作符 . 后面的东西必须是合法java标示符
${musicMap.aaa}
${musicMap[“aaa”]}
${musicList[“1”]}
----------------------以上都可以,但${musicList[“1”]}不会转换成厦门的
${musicList.1} 错误!!
5.EL获取请求参数
<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%>Insert title here
<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%>Insert title here <%request.setCharacterEncoding("UTF-8");response.setCharacterEncoding("UTF-8"); %> 用户名:${param.name }ID:${param.id } food:${param.food}foods:${paramValues.food[0]},${paramValues.food[1]}结果:
6.关于隐式对象:所有隐式对象中,除了pageContext代表是实际引用(也就是一个javabean),其他都是MAP(COOKIES也算?)!不代表对象本身!!
关于得到 Host 首部
脚本: <%= request.getHeader(“host”)%>
EL:${header[“host”]} 或 ${header.host} 如果有多个值,请使用 headerValues
-----------------------------------------------------------------------
关于得到 HTTP请求方法
脚本:<%= request.getMethod()%>
EL:${request.method} 错误!根本没有隐式request对象
${requestScope.method} 错误!requestScope不代表request对象本身
同理,其他隐式对象都只是相关作用域属性里的一个MAP,而不代表和它有关的对象本身!
所以,隐式对象里惟一代表其本身却又属于隐式对象的只有一个,那就是 pageContext
${pageContext.request.method}
-----------------------------------------------------------------------
关于作用域隐式对象:
虽然EL会在4个作用域里查找,原因除了担心命名冲突外,还有另外一个原因
正常:${person.name} 带上作用域${requestScope.person.name}
假如有人像下面这样设置:正常我们会 ${foo.hh}想获得它的值,但是这是不可能的,所以可以加上隐式对象,用上强大的[]操作符来获取我们想要的值,当然了,正常人不会做request.setAttribute("foo.hh", "aaa");
<%request.setAttribute("foo.hh", "aaa");request.setAttribute("user", "zhangsan"); %>${ requestScope["foo.hh"]}${user }------------------------------------------------------------------
关于其他便捷的功能演示:
打印cookie的值:
原来你要这样:
<%Cookie[] cookies = request.getCookies(); for(int i=0;i现在你可以这样:
${cookie.userName.value}
对于pageContext上下文初始化参数
user root 原来你需要这样:<%= application.getInitParamter(“user”)%>
现在你只需要这样:${initParam.user}
注意:EL initParam 对应的是 <context-param>上下文的初始化参数,不是Servlet初始化参数<init-param>!!!