/*
*EL表达式
*1、EL是JSP内置的表达式语言
* jsp2.0开始 不让再使用java脚本,而是使用el表达式和动态标签来替代java脚本
* EL替代的是<%=..%> EL只能做输出。
* jsp2.0 要把html和css分离、要把html和javascript分离、要把java脚本替换成标签。标签的好处是非java人员都可以使用
* JSP2.0-纯标签页面,即:不包含<%...%> <%!...%> 以及<%=...%>
* EL(Expression Language)是一门表达式语言,它对应<%=...%> 在JSP中,表达式会被输出,所以EL表达式也会被输出
* EL的格式: ${...} ${1+2}
*1.1、关闭EL
* 如果希望JSP忽略EL表达式 需要在page指令中指定 isElIgnored="true"
* 如果希望忽略某个EL表达式,那么可以在EL表达式之前添加"\" 例如\{1+2}
*1.2、EL运算符
* +、-、*、/、%、==、!=、<、>、>=、<=、&&(and 并且)、||(or或者)、!(not 非)、empty(是否为空)
*1.3、EL不显示null
* 当EL表达式的值为NULL时,会在页面上显示空白,即什么都不显示
*1.4、EL表达式格式
* 操作List和数组${list[0]}、${arr[0]};
* 操作bean的属性 ${person.name}、${person['name']}对应person.getName()方法
* 操作Map的值 ${map.key}、{map['key']} 对应map.get(key)
*2、EL表达式来读取四大域
* ${xxx} 区域查找名为xxx的属性,如果不存在,输出空字符串,而不是null
* ${pageScope.xxx}、${requestScope.xxx}、${sessionScope.xxx}、${applicationScope.xxx},指定域获取属性
*3、EL可以输出的东西都在11个内置对象中
* 共有11个内置对象,无需创建即可使用。这11个内置对象中有10个是Map类型的,最后一个是pageContext对象(不是Map)
* pageScope requestScope sessionScope applicationScope param paramValues header headerValues initParam cookie pageContext
*3.1、域相关内置对象
* 域内置对象一共有四个
* pageScope:${pageScope.name}等同于pageContext.getAttribute("name");
* requestScope:${requestScope.name} 等同于request.getAttribute("name");
* sessionScope:${sessionScope.name}等同于session.getAttribute("name");
* applicationScope:${applicationScope.name}等同于application.getAttribute("name");
* 如果在域中保存的是javabean对象,那么可以使用EL来访问javabean属性 因为EL只做读取操作,所以javabean移动要提供get方法,而set方法没有要求
* 全域查找${person} 表示依次在pageScope、requestScope、sessionScope、applicationScope四个域中查找名为person的属性
*3.2、请求参数相关内置对象
* param和paramValues这两个内置对象是用来获取请求参数的
* param:Map<String,String>类型,param对象可以用来获取参数,与request.getParameter()方法相同
* 在使用EL获取参数时,如果参数不存在,返回的是空字符串,而不是null。这一点与使用request.getParameter()方法是不同的
* paramValues: paramValues是Map<String,String[]>类型,当一个参数名,对应多个参数值时可以使用它
*3.3、请求头相关的内置对象
* header和headerValues是与请求头相关的内置对象
* header:Map<String,String>类型,用来获取请求头
* headerValues:headerValues是Map<String,String[]>类型。当一个请求头名称,对应多个值时,使用该对象
*3.4、应用初始化参数相关内置对象
* initParam:intitParam是Map<String,String>类型,他对应web.xml文件中的<context-param>参数
* EL表达式在获取Map的值或Bean的属性值时,可以使用"点"的方法 也可以使用"下标"方法
* ${initParam.a}与${initParam['a']},他们是完成相同的。但是,如果Map的键,或Bean的属性名包含下划线时,那么就必须使用"下标"方法${initParam['a_a']}
*3.5、Cookie相关内置对象
* cookie:cookie是Map<String,Cookie>类型,其中key是cookie的名字,而值是Cookie对象本身 ${cookie.username}是获取username这个名字的cookie ${cookie.username.value}才是这个cookie的值
*3.6、pageContext对象
* pageContext:pageContext是pageContext类型 可以使用pageContext对象调用getXXX()方法,例如pageContext.getRequest(),可以${pageContext.request}也就是读取JavaBean属性
* ${pageContext.request.contextPath}项目名 前有斜杠
*
*EL函数库(由JSTL提供)[jsf是sun公司提供的(没火起来)]
* EL函数库是由第三方对EL的扩展,我们现在学习的EL函数库是由JSTL添加的
* EL函数库就是定义一些有返回值的静态方法。然后通过EL语言来调用它们。当然,不只是JSTL可以定义EL函数库,我们也可以自定义EL函数库
* EL函数库中包含了很多对字符串的操作方法,以及对集合对象的操作。例如:${fn:length("abc")}会输出3即字符串的长度
*2、导入函数库
* 因为是第三方的,所以需要导入,导入需要使用taglib指令
* <%@tablib prefix="fn" uri="http://java.sun.com/jsp/jstl/functions"%>
*3、EL函数库介绍
* String toUpperCase(String input)把参数转换成大写
* String toLowerCase(String input)把参数转换成小写
* int indexOf(String input,String substring) 从大串,输出小串的位置
* boolean contains(String input,String substring)查看大串是否包含小串
* boolean containsIgnoreCase(String input,String substring)忽略大小写,是否包含
* boolean startsWith(String input,String substring)是否以小串为前缀
* boolean endsWith(String input,String substring)是否以小串为后缀
* String substring(String input,int beginIndex,int endIndex)截取字串 0,5 包含0不包含5
* String substringAfter(String input,String substring)获取大串中,小串所在位置后面的字符串 abc-lll ,"-" lll
* substringBefore(String input,String substring)获取大串中,小串所在位置前面的字符串 abc-lll ,"-" abc
* String escapeXml(String input)把input中的"<"、">"、"&"、"'"、"""进行转义 把字符串的">"、"<" 转义
* String trim(String input) 去除前后空格
* String replace(String input,String substringBefore,String substringAfter)替换
* String[] split(String input,String delimiters) 分割 字符串,得到字符串数组
* int length(Object obj)可以获取字符串、数组、各种集合的长度
* String join(String array[],String separator)联合字符串数组 合并 可以合成多个数组
*
*${fn:substring("0123456789",5,-1 )} 56789
*${fn:escapeXml("<html></html>")} <!--<html></html>-->
*4、自定义EL函数库
* 写一个类,下一个有返回值的静态方法
* 编写my.tld文件,可以参考fn.tld文件,把my.tld文件放到/WEB-INF目录下(不给别人看隐藏) 参考的文件可以下载jstl后搜索
* 在页面中添加taglib指令,导入自定义标签库
* <%@ taglib prefix="my" uri="/WEB-INF/TLDS/my.tld"%>
* 在jsp页面使用自定义的函数${my:fun()}
*/
<%
request.setAttribute("request_xxx", "request_aaa");
//pageContext的优先级最高
pageContext.setAttribute("request_xxx", "request_bbb");
session.setAttribute("request_xxx", "request_ccc");
//session还没有销毁 如果不是下一次会话那么 还是session
application.setAttribute("request_xxx", "request_ddd");
%>
${request_xxx }
${pageScope.request_xxx}
${requestScope.request_xxx }
${sessionScope.request_xxx }
${applicationScope.request_xxx}
使用El获取request域的emp 要先导入函数
<%@page import="my.domain.*" %>
<body>
<%
Address address = new Address();
address.setCity("宁波");
address.setStreet("鄞州");
Employee emp = new Employee();
emp.setName("李四");
emp.setSalary(11112);
emp.setAddress(address);
request.setAttribute("emp", emp);
%>
<h3>使用El获取request域的emp</h3>
${requestScope.emp.address.street}<!-- 相当于request.getAttribute("emp").getAddress().getStreet()只是示意 -->
</body>
<body>
<%--map.key是el的语法 ,requestScope[map].xxx[键]
map['key']这种也可以操作map
--%>
<%--http://localhost:8080/day30_02/param/a.jsp?username=aaa --%>
${param.username }<br/>
${paramValues.hobby[0] }
${paramValues.hobby[1] }
</body>
header EL标签
<!-- 要使用['']不然会把中间的-当作减号 -->
${header['User-Agent']}
<web-app>
<!-- 需要放在servlet上面不然因为顺序会报错 全局初始化 所有servlet都可以用 -->
<!-- servletcontext来获取 而不是servlet servletconfig是局部的-->
<context-param>
<param-name>xxx</param-name>
<param-value>XXX</param-value>
</context-param>
<context-param>
<param-name>aaa</param-name>
<param-value>AAA</param-value>
</context-param>
应该可以获取初始化参数的值 但是不知道为什么直接被当作文本解析
解决->Web.xml中 web-app版本不够高 换成 2.4成功显示
或者在jsp页面添加<%@page isELIgnored=”false” %> 也行
web.xml
<web-app version="2.4"
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-app_2_4.xsd">
也可以在web.xml添加配置信息
<jsp-config>
<jsp-property-group>
<el-ignored>false</el-ignored>
</jsp-property-group>
</jsp-config>
${initParam.xxx}
${cookie.JSESSIONID.value}
<!-- 以后更改项目名可以动态接上 使用这个方式开始长,以后方便 -->
<form action="${pageContext.request.contextPath }/cookie/a.jsp" method="post">
<input type="submit" value="xxx"/>
</form>
<hr/>
${pageContext.session.id }
<!-- 用 alt+/可以找网址 -->
<%@ taglib prefix="fn" uri="http://java.sun.com/jsp/jstl/functions"%>
<%@ page isELIgnored="false" %>
<h1>jstl提供的EL函数库</h1>
${fn:substring("0123456789",5,-1 )}<!-- 56789 -->
MyFunction.java
public class MyFunction {
public static String fun(){
return "自创EL测试";
}
}
my.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">
<description>my</description>
<display-name>MY functions</display-name>
<tlib-version>1.0</tlib-version>
<short-name>my</short-name>
<uri>http://www.my.cn/el/functions</uri>
<function>
<name>fun</name>
<function-class>my.fn.MyFunction</function-class>
<function-signature>java.lang.String fun()</function-signature>
</function>
</taglib>
使用自定义EL标签库
<%@taglib prefix="my" uri="/WEB-INF/tlds/my.tld" %>
<h1>${my:fun()}</h1>