在沒有學會EL表達式之前,我們想在JSP文件中獲取servlet或者其他JSP頁面傳來的值,通常都是在JSP頁面中編寫java代碼來實現。而在jsp頁面編寫Java 代碼,這種做法時不規范的,將會產生許多的弊端,如:
1、代碼的可維護性差,給人員的分工帶來了許多麻煩;
2、降低了代碼的可讀性;
3、降低了程序的安全性;
而在JSP中,有另一種語法,代替了java代碼來獲取request域中的值,它就是EL表達式。
首先我們來看一個樣例:
以下是兩個javaBean,分別為Student和Address,而在Student中有一個Address類型的屬性:

1 //學生類 2 public class Student { 3 4 private String name; //姓名 5 private int age; //年齡 6 private Address address; //地址,它是另外一個javaBean類型 7 8 public String getName() { 9 return name; 10 } 11 public void setName(String name) { 12 this.name = name; 13 } 14 public int getAge() { 15 return age; 16 } 17 public void setAge(int age) { 18 this.age = age; 19 } 20 public Address getAddress() { 21 return address; 22 } 23 public void setAddress(Address address) { 24 this.address = address; 25 } 26 27 } 28 29 30 //地址類 31 public class Address { 32 private String homeAddress; //家庭地址 33 private String schoolAddress; //學校地址 34 35 public String getHomeAddress() { 36 return homeAddress; 37 } 38 public void setHomeAddress(String homeAddress) { 39 this.homeAddress = homeAddress; 40 } 41 public String getSchoolAddress() { 42 return schoolAddress; 43 } 44 public void setSchoolAddress(String schoolAddress) { 45 this.schoolAddress = schoolAddress; 46 } 47 48 }
在一個servlet中,我們使用以下代碼向jsp頁面發送請求:

1 Student student = new Student(); //創建一個學生對象 2 student.setName("學生1"); 3 student.setAge(18); 4 Address a = new Address(); //創建一個地址對象 5 a.setHomeAddress("shanghai"); 6 a.setSchoolAddress("beijing"); 7 student.setAddress(a); //將地址對象設置給學生對象 8 request.setAttribute("student", student); //將student對象放入request
這樣,我們就能在請求轉發到的jsp頁面獲取到這個對象了。而使用EL表達式如何來做呢?
一、EL表達式的格式:
EL表達式的格式是以‘$’開頭,后面跟着一個大括號{ },而括號中內容,則可以理解為我們要獲取的值的路徑,而在括號里面的寫法卻用兩種:
1、使用點連接:
第一種方式比較簡單,就是使用點來連接各個屬性,最終確定某個屬性的值。假設我們要獲取剛剛請求轉發的student對象的name屬性的值,它是當前request域中的student這個對象的屬性,則EL表達式的寫法為:
${requestScope.student.name }
而若是想要獲取student對象的address屬性中的homeAddress屬性的值,則寫法類似:
${requestScope.student.address.homeAddress }
這里的requestScope表示我們要取的值在request域中,第一個參數就是區域名+Scope,而后面就是這個區域的哪個對象,若是要獲取對象的屬性,則使用"."連接,和java代碼中 對象.屬性 的寫法類似。
2、使用中括號連接
第二種使用EL表達式獲取值的方式就是使用中括號[ ]代替點“.”,中括號中寫入屬性名,並且屬性名用雙引號或者單引號括起來,例如,還是取出上面的兩個取值,使用中括號的寫法如下:
${requestScope['student']['name'] } <!-- 在中括號中使用單引號或者雙引號將屬性名括起來 --> ${requestScope["student"]["address"]["homeAddress"] }
使用中括號代替點,區域名寫法不變,獲取request域中的數據還是通過requestScope(區域名+Scope),而后面屬性名卻是寫在中括號中,並且使用雙引號或者單引號括住。
3、點與中括號混合使用
在EL表達式中,點與中括號可以混合使用,如下面的EL表達式,依然是獲取request域中的student對象的address屬性的homeAddress屬性:
<!-- 即使用了點連接,也使用了中括號,且同時使用了雙引號和單引號 --> ${requestScope["student"]['address'].homeAddress }
當然,這種寫法並不推薦,降低了代碼的可讀性,容易出錯。
二、在EL表達式中,中括號的一些特殊作用:
通過上面的例子,一般給我們感覺都是使用點來連接屬性更加簡單,但是中括號的功能卻比點更加強大。下面就來舉例說明。
1、EL表達式通過中括號,獲取名字中帶有特殊符號的屬性值
假設在request域中,一些值的名稱帶有特殊符號,那使用點連接的EL表達式將無法成功獲取到它的值,使用中括號卻能,如下面代碼所示:
//向request域中傳入名字為"a-a"的值 request.setAttribute("a-a", "aaa");
上面這個名字為“a-a”的屬性被傳入了request域,而分別通過點和中括號兩種方式進行獲取:
${requestScope["a-a"] } <!-- 使用中括號的方式獲取 --> ${requestScope.a-a } <!-- 使用點的方式獲取 -->
以下是獲取結果:
2、EL表達式通過中括號獲取數組的值
在EL表達式中,若向request域中傳入了一個數組或者ArrayLIst容器,則可以通過中括號的方式,獲取數組中的每一個值。如下代碼向request域中傳入一個數組和一個ArrayList:
1 //向request域傳入一個數組 2 int array[] = {1,2,3,4}; 3 request.setAttribute("array", array); 4 5 //向request域傳入一個ArrayList 6 ArrayList<String> list = new ArrayList<>(); 7 list.add("aaa"); 8 list.add("bbb"); 9 request.setAttribute("list", list);
使用EL表達式在JSP中獲取數組以及ArrayList中的每一個元素的值:
1 *************使用中括號el表達式獲取數組的值********************<br> 2 <!-- 通過下標獲取數組的值 --> 3 ${requestScope.array[0] }<br> 4 ${requestScope.array[1] }<br> 5 6 *************使用中括號el表達式獲取ArrayList的值********************<br> 7 <!-- 通過下標獲取ArrayList的值 --> 8 ${requestScope.list[0] }<br> 9 ${requestScope.list[1] }<br>
可以看到,上面的EL表達式通過 “.”獲取到了request域中的array和list,在通過【下標】的方式獲取數組中的每一個值。,結果如下:
3、在EL表達式中通過中括號獲取Map容器中的值
若向request域中傳入一個Map容器,通過EL表達式也可以獲取Map容器中的值,方式與獲取數組的值類似,也是通過中括號,但是中括號中寫的不是下標,而是key-value中的key。如下代碼向request域中傳入了一個HashMap容器:
1 HashMap<String,String> map = new HashMap<>(); 2 map.put("key1", "value1"); 3 map.put("key2", "value2"); 4 request.setAttribute("map", map);
在JSP頁面中,通過EL表達式來獲取map中的值:
1 *************使用EL表達式獲取Map容器中的值**************<br> 2 ${requestScope.map.key1 } <br> <!-- 通過點的方式獲取,點后面根key --> 3 ${requestScope.map["key2"] } <br> <!-- 通過中括號的方式獲取,中括號中為key -->
使用EL表達式獲取Map容器中值,不僅僅可以使用中括號,使用點也能夠做到,上面代碼的第一種方式就是使用點來實現的,點后面跟map中元素的key的值;而只用中括號,中括號中放入的也是map中元素的key值。運行結果如下:
三、EL表達式中的算術運算符與邏輯運算符:
EL表達式中支持大部分Java的邏輯運算符與算術運算符,可以使用符號或單詞縮寫兩種形式,如百分號可以是%,也可以是mod,如下圖:
使用上面的運算符,根據運算結果,將會在頁面上顯示true或false,如下代碼:
${1<2 } 或 ${1 lt 2 } <br> ${1< 2 || 1>2 } 或 ${1 lt 2 || 1 gt 2 } <br> ${empty requestScope.aaa } <br><!-- request中不存在叫做aaa的屬性,將在頁面打印true --> ${empty requestScope.map } <br><!-- request中存在叫做map的屬性,將在頁面打印false -->
四、EL表達式中的隱式對象:
在JSP中,存在九大隱式對象,也叫九大內置對象,request,response,out,session......。而在EL表達式中,同樣存在隱式對象,如下所示:
EL表達式中的隱式對象大致分為三類:
1、作用域訪問對象
即pageScope,requestScope,sessionScope以及applicationScope四個,表示的含義如上圖,也就是各自表示一個作用域。上面我們用的都是requestScope,因為都是將值存入request域,並從request域中取出。下面我們來演示另外一個,將數據存入session域,並從session域中取出。將數據存入session域的代碼如下:
request.getSession().setAttribute("sessionKey", "sessionValue");
使用EL表達式中的sessionScope從session域中取出數據,代碼如下:
${sessionScope.sessionKey }
不難看出,使用方法域requestScope一樣,只是操作的區域不同而已。另外兩個作用域訪問對象也是如此。而作用域之間也存在大小關系,四個作用域訪問對象的大小關系是:pageScope < requestScope < sessionScope < applicationScope。知道這個有什么用呢?用處就在於EL表達式取值的默認機制。當我們取值時不指定作用域時,默認將從小到大依次尋找四個作用域,看是否存在這個值,若存在則取出第一個找到的值。如下代碼分別在request域和session域中都傳入了一個名稱相同的數據:
1 request.getSession().setAttribute("Key", "Value"); 2 request.setAttribute("Key", "Value2");
在JSP頁面中獲取名為Key的值,且不使用作用域訪問參數指定作用域,代碼如下:
獲取名為Key的值:${Key }
結果顯示如下圖:
可以看到,獲取到的時傳入request域中的Value2,因為request域小於session域,默認先從小的域中去找。
2、參數訪問對象:
參數訪問對象中使用比較多的就是param以及paramValues,它們的作用就是獲取與request.getParameter()一樣,用來獲取表單中提交的數據。param用來獲取單個數據,而paramValues用來獲取多個數據,即為數組中的數據。如下代碼是一個form表單,其中有一個text類型的輸入框,用來測試param,一個checkbox類型的復選框,用來測試paramValues:
1 <form action="index2.jsp"> 2 姓名:<input type="text" name="name"/> 3 愛好:<input type="checkbox" name="hobbies" value="pingpong"/>乒乓球 4 <input type="checkbox" name="hobbies" value="basketball"/>籃球 5 <input type="checkbox" name="hobbies" value="football"/>足球 6 <input type="submit" value="submit"/> 7 </form>
運行結果如下:
我們在輸入框中輸入“測試”,復選框選中其中的兩個,並在JSP頁面中獲取,paramValues獲取值的方式與數組相同,獲取代碼如下:
姓名:${param.name }<br> 愛好: ${paramValues.hobbies[0] }, ${paramValues.hobbies[1] }, <%--EL表達式中,若值為null,將不顯示,而不是報異常 --%> ${paramValues.hobbies[2] },
在頁面中顯示的結果如下,注意,顯示的不是<input>標簽外面的中文,而是<input>中value屬性的值:
這里有有一點值得注意,在結果頁面,愛好這一行最后有兩個逗號,這是因為看上面EL代碼可知,我在JSP中使用paramValues獲取了三個復選框的值,但是提交的時候只選擇了兩個,也就是說沒有第三個的值,${paramValues.hobbies[2] }為null,而在EL表達式中,null值將不顯示,而不是像java代碼一樣報異常,這也是EL的好處之一。這也就導致只顯示出最后的逗號,而沒有值。
除了獲取表單中的值,param也能獲取超鏈接中傳來的值,如:http://localhost:8080/ELProject/index2.jsp?aa=1,在鏈接中傳入了一個aa,值為1,則也可以使用param獲取到aa的值,使用${param.aa}。
3、JSP隱式對象:
EL表達式中也包含JSP的隱式對象,就是pageContext,通過它可以獲得所有JSP的隱式對象,方法如下:
1 ${pageContext.request } <!-- 獲取jsp的request對象 --> 2 ${pageContext.response} <!-- 獲取jsp的response對象 --> 3 ${pageContext.session} <!-- 獲取jsp的session對象 -->
也可以通過級聯的方式使用:
${pageContext.request.serverPort }<!-- 級聯方式獲取端口號 -->
以上就是EL表達式的一些基本的使用方式。