JSP的EL表达式

EL 

全名为ExpressionLanguage。

EL主要作用:

1.获取数据:

EL表达式主要用于替换JSP页面中的脚本表达式,以从各种类型的web域 中检索java对象、获取数据。(某个web域 中的对象,访问javabean的属性、访问list集合、访问map集合、访问数组)

2.执行运算:

利用EL表达式可以在JSP页面中执行一些基本的关系运算、逻辑运算和算术运算,以在JSP页面中完成一些简单的逻辑运算。${user==null}

3.获取web开发常用对象

EL 表达式定义了一些隐式对象,利用这些隐式对象,web开发人员可以很轻松获得对web常用对象的引用,从而获得这些对象中的数据。

4.调用Java方法

EL表达式允许用户开发自定义EL函数,以在JSP页面中通过EL表达式调用Java类的方法。


1.拿取数据:

l使用EL表达式获取数据语法:“${标识符}”
lEL表达式语句在执行时,会调用pageContext.findAttribute方法,用标识符为关键字,分别从pagerequestsessionapplication四个域中查找相应的对象,找到则返回相应对象,找不到则返回””(注意,不是null,而是空字符串)。
l示例:${user}
      <body>
	<%
		pageContext.setAttribute("name", "张三丰") ;
		request.setAttribute("name", "张无忌") ;
		session.setAttribute("name", "张翠山") ;
		application.setAttribute("name", "张果老");
	%>

     	${name } 
 </body> 

页面分别按顺序拿到数据:

张三丰

张无忌

张翠山

张果老

如果表达式中写的是不存在的则拿到的是空字符串不会报错。不会出现空指针异常


EL表达式也可以很轻松获取JavaBean的属性,或获取数组、Collection、Map类型集合的数据,例如:
${user.address.city}
${user.list[0]}:访问 有序集合某个位置的元素
${map.key}  : 获得map集合中指定key的值

结合JSTL的foreach标签,使用EL表达式也可以很轻松迭代各种类型的数组或集合,示例:
迭代数组
迭代collection类型集合
迭代map类型集合

示例:
User.java:
package com.heima.bean;

public class User {

	private String username ;
	
	private  int age ;
	
	private Friend friend ;

	public String getUsername() {
		return username;
	}

	public void setUsername(String username) {
		this.username = username;
	}

	public int getAge() {
		return age;
	}

	public void setAge(int age) {
		this.age = age;
	}

	public Friend getFriend() {
		return friend;
	}

	public void setFriend(Friend friend) {
		this.friend = friend;
	}
}


Friend.java:
package com.heima.bean;

public class Friend {

	private String name ;
	
	private Cat[] cats ;

	public String getName() {
		return name;
	}

	public void setName(String name) {
		this.name = name;
	}

	public Cat[] getCats() {
		return cats;
	}

	public void setCats(Cat[] cats) {
		this.cats = cats;
	}
	
}


Cat.java:
package com.heima.bean;

public class Cat {

	private String name ;
	
	private String color ;
	
	public Cat() {
	}

	public Cat(String name, String color) {
		super();
		this.name = name;
		this.color = color;
	}

	public String getName() {
		return name;
	}

	public String getColor() {
		return color;
	}
}

1.jsp:
<body>		   
		   User user = new User() ;
		   user.setUsername("郭靖") ;
		   user.setAge(20) ;
		   
		   Friend f = new Friend() ;
		   f.setName("令狐冲") ;
		   
		   Cat[] cs = new Cat[2] ;
		   cs[0] = new Cat("喵喵","白色") ;
		   cs[1] = new Cat("咪咪","黑色") ;
		   
		   f.setCats(cs) ;
		   
		   user.setFriend(f) ;
		   
		   //将数据放入某个域对象
		   session.setAttribute("user", user) ;
		   
		   List<String> list = new ArrayList<String>() ;
		   list.add("aaaaaaaaaa") ;
		   list.add("bbbbbbbb") ;
		   list.add("cccccccccc") ;
		   list.add("dddddddddd") ;
		   
		   request.setAttribute("list", list) ;
		   
		   List<User> list1 = new ArrayList<User>() ;
		   list1.add(user) ;
		   
		   request.setAttribute("list1", list1) ;
		   
		   Map<String,User> map = new HashMap<String,User>() ;
		   map.put("a", user) ;
		   
		   request.setAttribute("map", map) ;
        %>
        
        ${name }
        
        <hr>
        el表达式支持对象的导航:<br>  ||或者  只要提供了get方法就可以拿到(可以没有set方法)
                         拿到郭靖的名字: ${user.username} || ${user["username"] }<br> username是键的名字
                         拿到郭靖的朋友的名字: ${user.friend.name} || ${user["friend"]["name"] }<br>
                         拿到郭靖的朋友的第一只猫的名字: ${user.friend.cats[0].name} || ${user["friend"]["cats"][0]["name"] }<br>
                         拿到郭靖的朋友的第二只猫的颜色: ${user.friend.cats[1].color} || ${user["friend"]["cats"][1]["color"] }<br>
                         
                         
        <hr>
                         拿到list集合中的所有数据:${list }  <br>
                         拿到list集合中的第一个数据:${list[0] }  <br>
                         集合数据的导航:${list1[0].friend.cats[0].color }<br>
        <hr>
                         拿到map中的所有的数据: ${map }<br>
                         拿到map中的第一个值: ${map["a"].friend.cats[1].color }<br>
                         
  </body>

拿不到set的数据,无序,没顺序的,就没索引,拿不了



运行结果:


在页面上拿取各种数据的时候:

从数据库里拿出数据,数据封装在javabean里面,把javabean放到了集合里面,集合放在session里或request对象里(即放到域对象里面),在页面上要把数据库里面的数据显示出来,就要通过域对象把数据拿出来,显示在页面上,拿取的时候就采用el表达式拿取。


2.对各种运算符的支持



<body>
	   2.el表达式对运算符的支持<br>
	   存储一些变量;
	      <%
	      	  request.setAttribute("n", 10) ;
	          List<String> list = new ArrayList<String>() ;
	          list.add("aaaaaaa") ;
	          
	          request.setAttribute("list", list) ;
	          
	          User user = null ;
	          request.setAttribute("user", user) ;
	      %>
	   <hr>
	   对一元运算符的支持:${-n }<br>
	   对二元运算符的支持:${3+4 } || ${n + 10} || ${n/4 }  || ${5 / n }<br>  整型会转变为double类型。
	   对比较运算符的支持: ${n>10 } || ${n gt 10} || ${n == 10 }<br>  gt:>   eq:=
	   对逻辑运算符的支持: ${n > 5 && n < 10  } || ${n > 5 and n < 10  }<br>
	   对 三元运算符的支持: ${n>5?"真的":"假的" } <br>
	 对empty运算符的支持: ${empty list } || ${not empty list } <br>  判断list是否为空。 是不是不为空。
	 判断对象是否为null: ${empty user} || ${not empty user}<br>
	 ${user }  ${pageContext.request.contextPath }
	 
  </body>
运行结果:


EL的特点:永远没有空指针。

不支持字符串连接操作

 执行简单的数学或逻辑运算:

empty运算符:判断一个对象是不是null和空字符串,如果是返回true;还能判断一个集合中是否有元素,没有任何元素,返回true。


3.获取web开发常用对象

EL中的11个隐式对象(难点:容易和JSP的隐式对象混淆)

EL表达式内置对象

表示类型

备注

对应的jsp内置对象

pageContext

javax.servlet.jsp.PageContext

JSP的内置对象完全一样

pageContext

requestScope

java.util.Map<String,Object>

代表者ServletRequest中的那个Map

没有

pageScope

java.util.Map<String,Object>

代表者PageContext中的那个Map

没有

sessionScope

java.util.Map<String,Object>

代表者HttpSession中的那个Map

没有

applicationScope

java.util.Map<String,Object>

代表者ServletContext中的那个Map

没有

param

java.util.Map<String,String>

代表一个请求参数

没有

paramValues

java.util.Map<String,String[]>

代表重名的请求参数

没有

header

java.util.Map<String,String>

代表一个请求消息头

没有

headerValues

java.util.Map<String,String[]>

代表重名的请求消息头

没有

initParam

java.util.Map<String,String>

代表web.xml中配置的全局参数

没有

cookie

java.util.Map<String,Cookie>

获取cookie值的,key是cookie的name,value是cookie对象本身

没有

注意cookie:这里的cookie是一个map,他对应的值才是一个真正的Cookie


1.pageContext:获取工程路径:

   ${pageContext.request.contextPath}


2.

requestScope

pageScope

sessionScope

applicationScope

这四个:限定了变量寻找的范围:

<body>
	<%
		pageContext.setAttribute("name", "张三丰") ;
		request.setAttribute("name", "张无忌") ;
		session.setAttribute("name", "张翠山") ;
		application.setAttribute("name", "张果老");
	%>

     	默认按从小到大的范围去找:${name }<br>  
     	结果:张三丰
     	
     	直接从request范围中去拿数据:${requestScope.name }<br>  
     	结果:张无忌  如果没有request对象,则输出空字符串
</body>


3.param、paramValues拿取提交的参数:

表单:

el表达式的内置对象param
<body>
	<form action="${pageContext.request.contextPath }/5.jsp" method = "post">
		姓名:<input type = "text" name = "username" ><br>
		密码:<input type = "text" name = "pass" ><br>
		确认密码:<input type = "text" name = "pass" ><br>
		<input type = "submit" value = "提交" >
	</form>
	<a href = "${pageContext.request.contextPath }/5.jsp?name=mmm">5.jsp</a>
	
	<%--<jsp:forward page="5.jsp?name=abc">   <pre name="code" class="html">                   请求转发:不用加工程路径
<jsp:param value="30" name="age"/> </jsp:forward>--%></body>

 
 

拿取:

header  headerValues  initParam

el表达式的内置对象param
<body>
	<% request.setCharacterEncoding("UTF-8") ; %>解决中文乱码
              用el表达式的内置对象param获取表单的数据: ${param.username }||${param["username"] }<br>
	<hr>
	 用el表达式的内置对象param获取超链传递的数据: ${param.name }||${param["name"] }<br>
	<hr>
	 用el表达式的内置对象param获取请求转发传递的数据: ${param.name }||${param["name"] } || ${param.age }||${param["age"] }<br>
	<hr>
	 用el表达式的内置对象paramValues获取表单中同名控件的数据: ${paramValues.pass[0] } || ${paramValues.pass[1] } <br>
	 <hr>
	 用el表达式的内置对象header获取请求头的数据: ${header["Accept-Encoding"] }<br> 带有-的 一定要用引号引起来
	 <hr>
	 用el表达式的内置对象headerValues获取请求头的数据: ${headerValues["Accept-Encoding"][0] }<br>  获取同名的请求头的信息
	 <hr>
	 用el表达式的内置对象initParam获取全局配置的数据: ${initParam.name }<br>   拿取xml里面配置的全局的参数
	  <hr>
	 用el表达式的内置对象Cookie(map类型)获取浏览器携带的Cookie(拿到的是map类型): ${cookie}<br>
	 用el表达式的内置对象Cookie获取正真的cookie对象 ${cookie.JSESSIONID}<br>  通过键拿到值 键是 <span style="font-family: Arial, Helvetica, sans-serif;">JSESSIONID</span>
	 用el表达式的内置对象Cookie获取正真的cookie对象的名字: ${cookie.JSESSIONID.name}<br>
	 用el表达式的内置对象Cookie获取正真的cookie对象 的value属性的值: ${cookie.JSESSIONID.value}<br>
	
	<%
		request.setAttribute("s", "abc") ;
	%>
	${s == "abc" }
</body>
在xml里面配置一个全局的参数:

<context-param>
		<param-name>name</param-name>
		<param-value>张无忌</param-value>
	</context-param>

运行结果:




4.调用Java方法:

   自定义函数

对于字符串来说,EL表达式不支持各种方法,不支持各种运算,只支持等与不等的比较运算:

<%
		request.setAttribute("s", "abc") ;
	%>
	${s == "abc" }
运行结果:true


思路:自定义函数由于是自己定义的,所以要使他跟后台的java代码联系起来,使得jsp引擎解析到自定义函数时,去调用后台的java代码执行

在编写函数时,由于此函数jsp引擎不认识,希望他能够掉用后台代码,所以方法一定要是静态的。要写一个配置文件,让页面上的代码和后台的java代码发生联系:
在WEB-INF里面新建一个File:必须是tld文件 标签描述文件  格式跟xml一样
该文件除了不能放在lib文件夹下之外,其他地方都可以放

eg:

后台的java代码

Demo.java:

package com.heima.function;

public class Demo {

	//此方法和页面的upper方法对应
	public static String upper(String s){
		return s.toUpperCase() ;
	}
}

页面的jsp代码:

还要在上面导入包:

<%@ taglib uri="http://java.sun.com/myfunction" prefix="fun" %>

<body>
	4.el表达式支持自定义函数<br>
	<hr>
	${"abcde"}
	${fun:upper("abc") }
	${fn:contains("abcde","abc") }
	
</body>

配置文件xml的代码:

此代码的编写可以参考

当一个工程建好后,里面都会有javaEE5或6 下面的jstl:java标准的标签库  最后一项:META-INF--fn.tld  第一二三段都要拷贝过来

再随便拷贝一个function修改

<?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">
 
  <tlib-version>1.1</tlib-version>
  <short-name>fn</short-name>
  <uri>http://java.sun.com/myfunction</uri>
 
 <function>
     <!-- name表示页面上函数的名字 -->
    <name>upper</name>
    <function-class>com.heima.function.Demo</function-class>    对应的后台的类:包名+类名
    <function-signature>java.lang.String upper(java.lang.String)</function-signature>   
  </function>
 </taglib>
在页面上使用自定义函数步骤:
1.编写一个java类,该类定义几个静态的方法,必须是静态的
2.编写描述文件,目的:让页面上自己定义的函数和后台的java代码发生一个联系,来指明当解析到自定义函数的时候应该调用哪一个类的哪一个方法
  注意类名和签名都是全路径:包名+类名(除了8种基本的数据类型(因为没有包名))
3.在要使用的页面上必须用taglib引进来

sun公司提供了一些已经定义好了的函数
http://java.sun.com/jsp/jstl/functions
导入这个包后就可以用这些函数了:
<%@ taglib uri="http://java.sun.com/jsp/jstl/functions" prefix="fn" %>


<body>
	
	${fn:contains("abcde","abc") }
	
</body>
前面是否包含后面:看后面的字符串是不是在前面里面
运行结果:true











  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值