EL工具包介绍
由Java技术开发一个jar包
作用:降低JSP文件开发时Java命令开发强度
Tomcat服务器本身自带了EL工具包(Tomcat安装地址/lib/el-api.jar)
JSP相关知识本文中有JSP规范的相关介绍
EL表达式
1.命令格式:${作用域对象别名.共享数据}
2.命令作用:
1)EL表达式是EL工具包提供一种特殊命令格式【表达式命令格式】
2)EL表达式在JSP文件上使用
3)执行时从指定的【作用域对象】中读取指定【共享数据】的内容并自动的写入到响应体
EL表达式作用域对象别名
1.JSP文件可以使用的作用域对象
1) ServletContext application: 全局作用域对象
2) HttpSession session: 会话作用域对象
3) HttpServletRequest request: 请求作用域对象
4) PageContext pageContext: 当前页作用域对象
这是JSP文件独有的作用域对象。Servlet中不存在
在当前页作用域对象存放的共享数据仅能在当前JSP文件中使用,不能共享给其他Servlet或则其他JSP文件
真实开发过程,主要用于JSTL标签与JSP文件之间数据共享数据
JSTL------->pageContext---->JSP
2.EL表达式提供作用域对象别名
JSP EL表达式
application ${applicationScope.共享数据名}
session ${sessionScope.共享数据名}
request ${requestScope.共享数据名}
pageContext ${pageScope.共享数据名}
下面用代码演示一下分别使用java代码和EL表达式在JSP中实现共享数据的读取
Servlet
public class OneServlet extends HttpServlet {
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
//分别将共享数据添加到作用域对象
//全局作用域对象
ServletContext application=request.getServletContext();
//会话作用域对象
HttpSession session=request.getSession();
application.setAttribute("sId",10);
session.setAttribute("sName","mike");
request.setAttribute("home","北京");
//通过请求转发的方式调用index_1.jsp,由index_1.jsp负责将作用域对象共享数据读取并写入响应体中
request.getRequestDispatcher("/index_1.jsp").forward(request,response);
}
}
使用Java代码读取共享数据
<%
//读取全局作用域对象中的共享数据
Integer sId=(Integer) application.getAttribute("sId");
//读取会话作用域对象中的共享数据
String sName=(String)session.getAttribute("sName");
//读取请求作用域对象中的共享数据
String home=(String)request.getAttribute("home");
%>
sId:<%=sId%><br/>
sName:<%=sName%><br/>
home:<%=home%><br/>
使用EL表达式
学员Id:${applicationScope.sId}<br/>
学员姓名:${sessionScope.sName}<br/>
学员地址:${requestScope.home}<br/>
很明显EL表达式简化了在JSP文件中读取共享数据的步骤
EL表达式将引用对象属性写入响应体中
1.命令格式: ${作用域对象别名.共享数据名.属性名}
2.命令作用: 从作用域对象读取指定共享数据关联的引用对象的属性值。并自动将属性的结果写入到响应体
3.属性名: 一定要去引用类型属性名完全一致(大小写)
4.EL表达式没有提供遍历集合方法,因此无法从作用域对象读取集合内容输出
首先创建一个Student类
public class Student {
private Integer sId;
private String sName;
public Student() {
}
public Student(Integer sId, String sName) {
this.sId = sId;
this.sName = sName;
}
public Integer getsId() {
return sId;
}
public void setsId(Integer sId) {
this.sId = sId;
}
public String getsName() {
return sName;
}
public void setsName(String sName) {
this.sName = sName;
}
}
创建Servlet
public class OneServlet extends HttpServlet {
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
//创建一个引用类型实例对象
Student student=new Student(10,"mike");
//将引用类型对象存入请求作用域对象
request.setAttribute("student",student);
//请求转发,向Tomcat申请调用index_1.jsp
request.getRequestDispatcher("/index_1.jsp").forward(request,response);
}
}
index_1.jsp
学生编号:${requestScope.student.sId}<br/>
学生姓名:${requestScope.student.sName}<br/>
EL表达式简化版
1.命令格式: ${共享数据名}
2.命令作用: EL表达式允许开发人员开发时省略作用域对象别名
3.工作原理:
EL表达式简化版由于没有指定作用域对象,所以在执行时采用【猜】算法
首先到【pageContext】定位共享数据,如果存在直接读取输出并结束执行
如果在【pageContext】没有定位成功,到【request】定位共享数据,如果存在直接读取输出并结束执行
如果在【request】没有定位成功,到【session】定位共享数据,如果存在直接读取输出并结束执行
如果在【session】没有定位成功,到【application】定位共享数据,如果存在直接读取输出并结束执行
如果在【application】没有定位成功,返回null
pageContext--->request--->session--->application
4.存在隐患:
容易降低程序执行速度【南辕北辙】
容易导致数据定位错误
5.应用场景:
设计目的,就是简化从pageContext读取共享数据并输出难度
简化版设计之初就是为了从当前页作用域对象读取数据并输出。所以从request,session,application读取数据并输出时应 该避免使用简化版
6.EL表达式简化版尽管存在很多隐患,但是在实际开发过程中,开发人员为了节省时间,一般都使用
简化版,拒绝使用标准版
Servlet
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
//向当前用户session添加一个共享数据
HttpSession session=request.getSession();
session.setAttribute("key","hehe");
//向当前请求作用域对象中添加一个共享数据
request.setAttribute("key","haha");
//通过请求转发方式,申请调用index_1.jsp
request.getRequestDispatcher("/index_1.jsp").forward(request,response);
}
}
index_1.jsp
标准版EL表达式输出session中的key值:${sessionScope.key}<br/>
简化版EL表达式输出session中的key值:${key}
EL表达式支持运算表达式
1.前提: 在JSP文件有时需要将读取共享数据进行一番运算之后,将运算结果写入到响应体
2.运算表达式:
1) 数学运算
2) 关系运算: > >= == < <= != gt ge eq lt le !=
3)逻辑运算: && || !
演示数学运算
public class OneServlet extends HttpServlet {
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
request.setAttribute("key1","100");
request.setAttribute("key2",200);
//通过请求转发的方式调用index_1.jsp 并将结果写入到响应体中
request.getRequestDispatcher("index_1.jsp").forward(request,response);
}
}
<!--将作用域对象中共享数据读取出来相加,将相加的结果写入到响应体中-->
<%
String num1=(String)request.getAttribute("key1");
Integer num2=(Integer)request.getAttribute("key2");
int sum=Integer.valueOf(num1)+num2;
%>
传统的java命令计算后的结果:<%=sum%>
<hr/>
EL表达式计算后的结果:${requestScope.key1+requestScope.key2}
演示关系运算
public class TwoServlet extends HttpServlet {
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
request.setAttribute("age",25);
request.getRequestDispatcher("index_2.jsp").forward(request,response);
}
}
<!--传统Java命令实现关系运算的输出-->
<%
Integer age=(Integer)request.getAttribute("age");
%>
<%
if (age>18){
%>
欢迎光临<br/>
<%
}else {
%>
谢绝入内<br/>
<%
}
%>
EL表达式输出关系运算
${age>18?"欢迎光临":"谢绝入内"}
EL表达式提供的内置对象
术语 |
定义 |
param |
将请求参数名称映射到单个字符串参数值(通过调用 ServletRequest.getParameter (String name) 获得)。getParameter (String) 方法返回带有特定名称的参数。表达式 ${param . name}相当于 request.getParameter (name)。 |
paramValues |
将请求参数名称映射到一个数值数组(通过调用 ServletRequest.getParameter (String name) 获得)。它与 param 隐式对象非常类似,但它检索一个字符串数组而不是单个值。表达式 ${paramvalues. name} 相当于 request.getParamterValues(name)。 |
header |
将请求头名称映射到单个字符串头值(通过调用 ServletRequest.getHeader(String name) 获得)。表达式 ${header. name} 相当于 request.getHeader(name)。 |
headerValues |
将请求头名称映射到一个数值数组(通过调用 ServletRequest.getHeaders(String) 获得)。它与头隐式对象非常类似。表达式 ${headerValues. name} 相当于 request.getHeaderValues(name)。 |
cookie |
将 cookie 名称映射到单个 cookie 对象。向服务器发出的客户端请求可以获得一个或多个 cookie。表达式 ${cookie. name .value} 返回带有特定名称的第一个 cookie 值。如果请求包含多个同名的 cookie,则应该使用 ${headerValues. name} 表达式 |
initParam |
将上下文初始化参数名称映射到单个值(通过调用 ServletContext.getInitparameter(String name) 获得)。 |
param
相当于java代码中的request.getParameter();
1.命令格式: ${param.请求参数名}
2.命令作用: 通过请求对象读取当前请求包中请求参数内容,并将请求参数内容写入到响应体
3.代替命令: index.jsp
发送请求: Http://localhost:8080/myWeb/index_1.jsp?userName=mike&password=123
<%
String userName = request.getParameter("userName");
String password = request.getParameter("password");
%>
<%=userName%>
<%=password%>
paramValues
相当于java代码中的request.getParameterValues();
1.命令格式:${paramValues.请求参数名[下标]}
2.命令作用:
如果浏览器发送的请求参数是[一个请求参数关联多个值]
此时可以通过paramValues读取请求参数下指定位置的值并写入到响应体
3.代替命令: http://localhost:8080/myWeb/index_2.jsp?pageNo=1&pageNo=2&pageNo=3
此时pageNo请求参数在请求包以数组形式存在
pageNo:[1,2,3]
<%
String array[]= request.getParameterValues("pageNo");
%>
第一个值:<%=array[0]%>
第二个值:<%=array[1]%>
pageContext
对应的完整的java类名:javax.servlet.jsp.PageContext
这个内置对象在EL表达式中对应的隐含对象是:PageContext
使用EL表达式从pageContext范围中取数据的时候使用EL表达式中的内置对象pageScope
如果想调用pageContext内置对象的方法,需要使用EL表达式的内置对象pageContext
举例:使用EL表达式获取base路径
使用java代码获取base路径
<%
String path=request.getScheme()+"://"+request.getServerName()+request.getServerPort()+"/"+request.getContextPath();
%>
<%=path%>
<br/>
使用EL表达式内置对象PageContext
${pageContext.request.scheme}://${pageContext.request.serverName}${pageContext.request.serverPort}/${pageContext.request.contextPath}
<br/>
使用EL表达式从Map集合中读取数据
<%
Map<String,Emp> empMap=new HashMap<>();
empMap.put("e1",e1);
empMap.put("e2",e2);
request.setAttribute("empMap",empMap);
%>
员工1:${empMap.get("e1").ename}
员工1编号:${empMap.get("e1").eno}
员工2:${empMap.get("e1").ename}
员工2编号:${empMap.get("e1").eno}
使用EL表达式从List集合中读取数据
<%
List<Emp> empList=new ArrayList<Emp>();
empList.add(e1);
empList.add(e2);
request.setAttribute("empList",empList);
%>
${empList[0]}
${empList[1]}
${empList[0].ename}
${empList[1].ename}
EL表达式的专有异常
javax.el.PropertyNotFoundException:类型【xxxx】不存在【属性名】既在某个类中没有找到对应的属性
JSTL
(JSP Standard Tag Libary)jsp标准的标签库(掌握核心标签 c标签)
使用标签代替java代码,标准是sun制定的,Apache实现的(sun收录)
使用JSTL的步骤:
*导入jar包 jstl.jar standard.jar
*在需要使用标签额jsp页面上使用taglib指令引入标签库
<%@taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
*在需要使用标签的位置直接使用标签即可
解释标签
<tag>
<description></description> 标签的描述
<name>if</name> 标签的名字
<tag-class>org.apache.taglibs.standard.tag.rt.core.IfTag</tag-class> 标签对应的需要执行的类
<body-content>JSP</body-content> 标签体中的内容类型
<attribute> 标签中可以出现的属性
<description></description> 对属性的描述
<name>test</name> 属性的名字
<required>true</required> 该属性是否是必须的 true是必须的
<rtexprvalue>true</rtexprvalue> 该属性是否可以接收EL表达式 true表示支持接收EL表达式
<type>boolean</type> 该属性的数据类型
</attribute>
<attribute>
<description></description>
<name>var</name>
<required>false</required>
<rtexprvalue>false</rtexprvalue>
</attribute>
<attribute>
<description></description>
<name>scope</name>
<required>false</required>
<rtexprvalue>false</rtexprvalue>
</attribute>
</tag>
常用的标签
<%--模拟if...else--%>
<c:choose>
<c:when test="${param.age<5}">
婴幼儿
</c:when>
<c:when test="${param.age<18}">
少年
</c:when>
<c:when test="${param.age<35}">
青年
</c:when>
<c:otherwise>
老年
</c:otherwise>
</c:choose>
<hr/>
<%--循环foreach--%>
<c:forEach begin="1" end="10" step="1" var="i">
${i}
</c:forEach>
<br/>
<%--java代码--%>
<%
for(int i=1;i<=10;i++){
pageContext.setAttribute("i",i);
%>
${i}
<%
}
%>
<hr/>
<%--循环获取List集合--%>
<%
List<Emp> empList=new ArrayList<Emp>();
Emp e1=new Emp(110,"张三");
Emp e2=new Emp(111,"李四");
Emp e3=new Emp(112,"王五");
empList.add(e1);
empList.add(e2);
empList.add(e3);
pageContext.setAttribute("empList",empList);
%>
<c:forEach items="${empList}" var="emp" varStatus="empStatus">
${empStatus.count}、${emp.eno}、${emp.ename}<br/>
</c:forEach>
<br/>
<%--使用java代码--%>
<%
for(Emp e:empList){
pageContext.setAttribute("e",empList);
%>
<%=e.getEno()%>、<%=e.getEname()%><br/>
<%
}
%>
<hr/>
<%--可以切割字符串--%>
<%--127.0.0.1,192.168.1.100,192.168.1.3,192.168.8.4--%>
<c:forTokens items="${initParam.ips}" delims="," var="ip">
${ip}<br/>
</c:forTokens>
函数
1、函数是对EL表达式的补充,函数是属于JSTL的一部分,对应的配置文件是:stander.jar中的fn.tld文件
2、函数也是联合EL表达式也是代替jsp中的Java代码的
3、函数分:内置函数、自定义函数
4、内置函数的使用步骤
*导入jar包(jstl.jar、standard.jar)
*使用taglab指令导入函数库
*在需要使用函数的位置使用即可
5、函数详解
<function> 函数描述
<description></description> 函数名
<name>contains</name> 函数对应的类
<function-class>org.apache.taglibs.standard.functions.Functions</function-class> 函数对应的类中需要执行的方法
<function-signature>boolean contains(java.lang.String, java.lang.String)</function-signature>
<example>
<c:if test="${fn:contains(name, searchString)}"> 例子
</example>
</function>
6、EL标签怎么使用,函数就怎么使用
7、自定义的标签的步骤
*在WEB-INF目录下新建egov.tld文件,从fn.tld文件中拷贝模板
*编写一个类,在该类中编写一个方法,该方法必须是public的,并且必须是static的
*使用即可