1、EL表达式语法
<%@ page isELIgnored="false" %>
<%
pageContext.setAttribute("name","www.cx.cn") ;
%>
<%=pageContext.getAttribute("name")%>
<br>
#####${name}
- EL表达式是在jsp中输出的语句,十分简洁
- 语法是:${内置对象的属性名}
2、EL表达式主要功能
1、对于null自动转换成空串
<%=pageContext.getAttribute("name123")%>
<br>
#####${name123}
- 用getAttribute,如果在内置对象中找不到对应属性名的属性值,就返回null----很容易引起空指针异常
- 用EL表达式,如果在内置对象中找不到属性值,会自动将null转换为空字符串, 而不是null —避免空指针异常
2、在指定的内置对象域查找属性值
- 没有指定域时,按照 page—request—session—applciation的顺序查找
<%
pageContext.setAttribute("name","www.cx.cn") ;
request.setAttribute("name","zs") ;
%>
<h1>****${name}</h1>
el表达式先从page内置对象里找“name”的属性值,没找到,再到request里找,找到了,返回属性值 “zs”;
- 如果想要el在指定内置对象域找属性值,加上requestScope.name
<%
pageContext.setAttribute("name","www.cx.cn") ;
request.setAttribute("name","zs") ;
%>
<h1>****${requestScope.name}</h1>
这样el表达式就会直接去request内置对象里找属性值;
但是,设定了内置对象域后,el表达式只会在设定的内置对象里查找,如果没有找到,就返回空串 。
3、根据上下文对数据类型转换
<%
pageContext.setAttribute("a","30");
request.setAttribute("b",5);//自动装箱,integer类型
%>
<h1>${a}</h1><br>
<h1>${b}</h1><br>
<h1>${a*b+3}</h1>
<h1>
${a>b}
</h1>
<h1>
${3*5+7}
</h1>
request.setAttribute(“b”,5); setAttribute(String,Object),因此这里的5 是Integer类型,是对象地址。这是int的自动装箱
-
对于**${a*b+3}**
a的值是字符串,而b的值是整型(在进行运算时,Integer类型会进行自动拆箱,调用valueOf方法),el表达式根据上下文,将字符串型“30”转化为整型30,然后进行运算
-
${a>b} ,
同理,对Integer类型5拆箱得到int类型的5。而字符串型 “30”和int型5是不能比较的,EL表达式根据上下文,会将“30”转换为整型30和来5比较,返回true
-
${3*5+7} ,el表达式会直接进行运算,然后输出在页面
这就是EL表达式的强大的处理能力,可以根据上下文进行类型转换或计算。
4、EL表达式和JavaBean的应用
Simple.java
package cn.cx.servlet.el ;
public class Simple
{
private String name ;
public Simple()
{}
public void setName(String name)
{
this.name = name ;
}
public String getName()
{
return this.name ;
}
};
ELServletDemo02.java
package cn.cx.servlet.el ;
import java.io.* ;
import javax.servlet.* ;
import javax.servlet.http.* ;
public class ELServletDemo02 extends HttpServlet
{
public void doGet(HttpServletRequest req,HttpServletResponse resp) throws IOException,ServletException
{ Simple s;
//System.out.println(s);
s = new Simple() ;
s.setName("lisa") ;
//sim里是Simple对象的地址
req.setAttribute("sim",s) ;
// 服务器端跳转
req.getRequestDispatcher("eldemo04.jsp").forward(req,resp) ;
}
public void doPost(HttpServletRequest req,HttpServletResponse resp) throws IOException,ServletException
{
this.doGet(req,resp) ;
}
};
//04.jsp
<h1>***${sim.name}</h1>
web.xml
<servlet>
<servlet-name>el02</servlet-name>
<servlet-class>cn.cx.servlet.el.ELServletDemo02</servlet-class>
<load-on-startup>0</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>el02</servlet-name>
<url-pattern>/eldemo/el_2</url-pattern>
</servlet-mapping>
- ${sim.name} 就相当于request.getAttribute(“sim”).getName()
- sim.name,sim—在request内置对象里找属性名为sim的属性值,得到的是Simple对象的地址
- .name,是调用Simple对象的getName()方法 ,不是调用属性。
- ${sim123.name}
如果要查找的属性名为sim123,没有找到属性名为sim123的属性值,就会返回空串,不再进行后面的代码
- ${sim.name123}
在内置对象里找到sim属性名的属性值,但是没有找到方法name123,就会报错
内置对象中找属性名的属性值时,如果没找到就会返回一个空串;但如果是找到了属性名对应的属性值,但是在调用这个对象的方法时找不到这个方法,就会报错!
3、对象的关联关系
对象之间不止有1对1,我们之前写的两个对象之间就是正常的1对1。很多时候还有一对多或者多对多的情况,例如一个班级对应多个学生;多个学生对应多个课程
1、一对多
class stduent{
private Stirng sname;
private int sid;
private Teacher tea;//关联写在多的一方
}
class teacher{
private String tname;
private int tid;
}
class test{
psvm(){
Teacher t = new Teacher();
t.setTid(1);
t.setTname("tom");
//学生和老师实现一对多的关系。通过对象,将学生的t属性指向老师对象。学生和老师建立起关系
Student s1 = new Student();
s1.setSid(10);
s1.setSname("s1");
s1.setTea(t); //学生和老师建立关系
Student s2 = new Student();
s2.setSid(11);
s2.setSname("s1");
s2.setTea(t); //学生和老师建立关系
Student s3 = new Student();
s3.setSid(12);
s3.setSname("s1");
s3.setTea(t); //学生和老师建立关系
//通过学生对象拿到关联的老师的名字
s1.getTea().getTname();
//web页面里
request.setAttribute("student",s3);
//通过el表达式深度导航
${student.tea.tname}
}
}
- 在Java中,描述这种一对多的关系,总是将这个关系加在多的那一方。例如这里是多名学生对应一个老师,那么就是在学生的Bean中加上老师对象的属性,从而在学生和老师之间产生联系
- s1.setTea(t); 将老师对象的地址 set进学生对象里,就可以通过学生对象地址调用getTea获取老师对象地址,再通过老师对象地址获取到老师的信息----学生和老师产生了联系
- s1.getTea().getTname();
通过s1所指向的学生对象的地址,调用getTea()方法,得到老师对象的地址,再通过其调用getTname()方法,最终得到老师的名字
在jsp中用EL表达式来简化:${student.tea.tname} ,这就是EL表达式的深度导航。
2、多对多
需要通过中间的类来建立多对多关系
员工Bean NameBean.java
package cn.cx.servlet.el ;
public class NameBean
{
private String firstName ;
private String lastName ;
public NameBean()
{}
public void setFirstName(String firstName)
{
this.firstName = firstName ;
}
public void setLastName(String lastName)
{
this.lastName = lastName ;
}
public String getFirstName()
{
return this.firstName ;
}
public String getLastName()
{
return this.lastName ;
}
};
公司Bean: companyBean.java
package cn.cx.servlet.el ;
public class CompanyBean
{
private String companyName ;
private String business ;
public CompanyBean()
{}
public void setCompanyName(String companyName)
{
this.companyName = companyName ;
}
public void setBusiness(String business)
{
this.business = business ;
}
public String getCompanyName()
{
return this.companyName ;
}
public String getBusiness()
{
return this.business ;
}
};
建立关系 雇佣Bean EmployeeBean.java
package cn.cx.servlet.el ;
public class EmployeeBean
{
private NameBean name ; //关联属性,放在多的一方(employee雇佣)多个公司可以雇佣一个人员
private CompanyBean company ;//关联属性,多个人员可以被一个公司雇佣
//两个多对一-----一个多对多
public EmployeeBean()
{}
public void setName(NameBean name)
{
this.name = name ;
}
public void setCompany(CompanyBean company)
{
this.company = company ;
}
public NameBean getName()
{
return this.name ;
}
public CompanyBean getCompany()
{
return this.company ;
}
}
建立 Employee、Name、Company三者的关系
实现:
package cn.cx.servlet.el ;
import java.io.* ;
import javax.servlet.* ;
import javax.servlet.http.* ;
public class ELServletDemo03 extends HttpServlet
{
public void doGet(HttpServletRequest req,HttpServletResponse resp) throws IOException,ServletException
{
NameBean nb = new NameBean() ;
nb.setFirstName("Li") ;
nb.setLastName("sa") ;
CompanyBean cb = new CompanyBean() ;
cb.setCompanyName("www.cx.cn") ;
cb.setBusiness("JAVA EE、JAVA SE、JAVA ME") ;
EmployeeBean eb = new EmployeeBean() ;
//员工对象和公司对象都是employee的属性
//通过emplyee与员工价建立多对一
eb.setName(nb) ;//设置nameBean对象的地址
//通过emplyee与公司建立多对一
eb.setCompany(cb) ;//设置companyBean对象的地址
// 保存属性
req.setAttribute("emp",eb) ;
// 服务器端跳转
req.getRequestDispatcher("eldemo05.jsp").forward(req,resp) ;
}
public void doPost(HttpServletRequest req,HttpServletResponse resp) throws IOException,ServletException
{
this.doGet(req,resp) ;
}
};
/*
<servlet>
<servlet-name>el03</servlet-name>
<servlet-class>cn.cx.servlet.el.ELServletDemo03</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>el03</servlet-name>
<url-pattern>/eldemo/el_3</url-pattern>
</servlet-mapping>
*/
eldemo05.jsp
<h1>FirstName:${emp.name.firstName}</h1><br>
<h1>Business:${emp.company.business}</h1><br>
- 在Java中这么写:
获得雇佣该员工的公司业务
eb.getCompany().getBusiness()
获取公司雇佣的员工的名称
eb.getName().getFirstName()
- 在jsp中使用EL表达式的深度导航
${eb.company.business}
${eb.name.firstName}
4、EL表达式中的集合
对于查询出来的多条结果,我们是用多个结果Bean去封装,多个结果Bean怎么传递到浏览器?通过将多个结果Bean放进一个集合里,然后jsp读取集合里的元素。下面示例,用el表达式能不能将集合里的元素读取出来?
package cn.cx.servlet.el ;
import java.io.* ;
import java.util.* ;
import javax.servlet.* ;
import javax.servlet.http.* ;
public class ELServletDemo04 extends HttpServlet
{
public void doGet(HttpServletRequest req,HttpServletResponse resp) throws IOException,ServletException
{
//将三个SimpleBean放入集合List l中
List l = new ArrayList() ;
Simple s = null ;
s = new Simple() ;
s.setName("zhangsan") ;
l.add(s) ;
s = new Simple() ;
s.setName("lisi") ;
l.add(s) ;
s = new Simple() ;
s.setName("wangwu") ;
l.add(s) ;
req.setAttribute("all",l) ;
// 服务器端跳转
req.getRequestDispatcher("eldemo06.jsp").forward(req,resp) ;
}
public void doPost(HttpServletRequest req,HttpServletResponse resp) throws IOException,ServletException
{
this.doGet(req,resp) ;
}
};
/*
<servlet>
<servlet-name>el02</servlet-name>
<servlet-class>cn.cx.servlet.el.ELServletDemo04</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>el02</servlet-name>
<url-pattern>/eldemo/el_4</url-pattern>
</servlet-mapping>
*/
eldemo06.jsp
<%@page import="java.util.*"%>
<%--
要使用Iterator进行输出
--%>
<h1>${all}</h1><br>
<h1>${all[2].name}</h1><br>
<%
// List要使用Iterator输出
List l = (List)request.getAttribute("all") ;
Iterator iter = l.iterator() ;
while(iter.hasNext())
{
// 将取出的对象放在page范围之中
pageContext.setAttribute("sim",iter.next()) ;
%>
<h1>${pageScope.sim.name}</h1>
<%
}
%>
- ${all} all所指是l集合对象的地址,因为list复写了toString方法,所以输出集合就是将集合里的元素的地址输出。这里输出到页面的是三个Simple对象的地址
- ${all[2].name} all[2]指向的是集合中下标为2的元素,也就是第三个simple对象地址 ,调用第三个simple对象的getname方法 ,输出wangwu
- 但是如果要遍历出all集合的每一个对象的getName,通过el表达式是做不到的(除非一个一个通过下标获取,但是这样显然是不可取的),我们只能通过java来遍历all集合