這節我們總結一下EL表達式相關內容。
1. EL表達式主要作用
EL表達式說白了,就是讓JSP寫起來更加方便,它屬於JSP技術。那么它主要都有哪些方面的作用呢?
1.1 獲取數據
EL表達式可以用於替換JSP頁面中的腳本表達式,以從各種類型的web域中檢索Java對象、獲取數據(某個web域中的對象,訪問javabean的屬性、訪問list,map集合、訪問數組)。在JSP頁面中可使用${標識符}的形式,通知JSP引擎調用pageContext.findAttribute()方法,以標識符為關鍵字從各個域對象中獲取對象。如果對象中不存在標識符所對應的對象,則返回""(注意不是null)。下面是EL表達式獲取數據的幾種情況,由於JSP是用來獲取servlet傳遞過來的數據,所以在這個JSP里面先模擬向域中存放數據,再獲取。具體看下面的例子:
<%@page import="javaBean.Address"%> <%@page import="javaBean.Person"%> <!-- javaBean的具體代碼就不寫了,很簡單 --> <%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%> <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"> <html> <head> <title>EL表達式</title> </head> <body> <% request.setAttribute("name", "aaa"); //先向request域中存個對象 %> <!-- 相當於pageContext.findAttribute("name") 會從page request session application四個域中尋找 --> ${name } <!-- 在JSP頁面中使用EL表達式可以獲取bean的屬性 --> <% Person p = new Person(); p.setAge(12); request.setAttribute("person", p); %> ${person.age} <!-- 在JSP頁面中使用EL表達式可以獲取bean中的bean。。。 --> <% Person person = new Person(); Address address = new Address(); person.setAddress(address); request.setAttribute("person", person); %> ${person.address.name} <!-- 在JSP頁面中使用EL表達式可以獲取List集合指定位置的數據 --> <% Person p1 = new Person(); p1.setName("aa"); Person p2 = new Person(); p2.setName("bb"); List<Person> list = new ArrayList<Person>(); list.add(p1); list.add(p2); request.setAttribute("list", list); %> ${list[0].name} <!-- 在JSP頁面中使用EL表達式可以獲取map集合的數據 --> <% Map<String,String> map = new HashMap<String,String>(); map.put("a", "aaaax"); map.put("b", "bbbbx"); map.put("1", "ccccx"); request.setAttribute("map", map); %> ${map.a} ${map["1"] } <!-- 以數字為關鍵字時候的取法 --> <!-- 使用EL表達式可以獲取web應用的名稱 --> <a href="${pageContext.request.contextPath }/1.jsp">點擊</a> </body> </html>
1.2 執行運算
語法:${運算表達式} EL表達式支持如下運算符:
==(eq) !=(ne) <(lt) >(gt) <=(le) >=(ge) &&(and) ||(or) !(not)
empty運算符:檢查對象是否為null或“空”。
二元運算式:${user!=null? user.name : ""}。
運算符比較簡單,不多說了……
1.3 獲取web開發常用對象
EL表達式語言中定義了11個隱含對象,使用這些隱含對象可以很方便地獲取web開發中的一些常見對象,並讀取這些對象的數據。
語法:${隱式對象名稱} : 獲得對象的引用。
隱含對象名稱以及描述:
pageContext: //對應於JSP頁面中的pageContext對象(注意:取的是pageContext對象)
pageScope: //代表page域中用於保存屬性的Map對象
requestScope: //代表request域中用於保存屬性的Map對象
sessionScope: //代表session域中用於保存屬性的Map對象
applicationScope: //代表application域中用於保存屬性的Map對象
param: //表示一個保存了所有請求參數的Map對象
paramValues: //表示一個保存了所有請求參數的Map對象,它對於某個請求參數,返回的是一個String[]
header: //表示保存了所有http請求頭字段的Map對象
headerValues: //同上,返回String[]數組。注意:如果頭里面有"-",例如Accept-Encoding,則要headerValues["Accept-Encoding"]
cookie: //表示一個保存了所有cookie的Map對象
initParam: //表示了一個保存了所有web應用初始化參數的Map對象
具體看下面的例子:
<%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%> <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"> <html> <head> <title>EL隱式對象</title> </head> <body> <!-- ${name} 表示 pageContext.findAttribute("name") 過程是這樣:首先判斷name是否為EL的隱式對象,如果是直接返回該隱式對象的引用,不是則調用findAttribute方法 --> ${pageContext } <!-- 拿到pageContext的引用:org.apache.jasper.runtime.PageContextImpl@155ef996 --> <!-- 拿到pageContext就可以拿到所有其他域對象了,比如 ${pageContext.request} --> <br> <!-- 從指定的page域中查找數據 --> <% pageContext.setAttribute("name", "aaa");//map %> ${pageScope.name } <!-- ${name}會從四個域里面查找name 而${pageScope.name}只會從page域中查找 --> <br> <!-- 從request域中查找數據 --> <% request.setAttribute("name", "bbb"); %> ${requestScope.name } <!-- 如果用${name}會取到aaa,因為會首先在pageContext中查找 --> <br> <!-- 從session域中查找數據,可以用於檢查用戶是否登陸 --> <!-- 從application域中查找數據,與上面的原理都相同 --> <!-- 獲得用於保存請求參數的map,並從map中獲取數據 --> <!-- http://localhost:8080/test/1.jsp?name=eson_15 --> ${param.name } <!-- 拿到eson_15 --> <!-- 此表達式會經常用在數據回顯上 --> <form action="${pageContext.request.contextPath }/servlet/ReqisterServlet" method="post"> <input type="text" name="username" value="${param.username }"> <input type="submit" value="注冊"> </form> <br> <!-- paramValue獲得請求參數 map{"",String[]} --> <!-- http://localhost:8080/test/1.jsp?like=sing&like=dance --> ${paramValues.like[0] } ${paramValues.like[1] } <br> <!-- header獲取請求頭 --> ${header.Accept } ${header["Accept-Encoding"]} <br> <!-- headerValues和paramValues一樣的 --> <!-- 獲取客戶機提交的cookie --> ${cookie.JSESSIONID.value } <!-- 獲得cookie對象中名為JSESSIONID的cookie值 --> <br> <!-- 獲取web應用初始化參數 --> ${initParam.name } <!-- 用於獲得web.xml中<context-Param>中的參數 --> <br> </body> </html>
1.4調用java方法
EL表達式語法允許開發人員開發自定義函數,以調用java類的方法。示例:${prefix: method(params)}
在EL表達式中調用的只能是java類的靜態方法,這個java類的靜態方法需要在TLD文件中描述,才可以被EL表達式調用。EL自定義函數用於擴展EL表達式的功能,可以讓EL表達式完成普通java程序代碼所能完成的功能。
我們在工程test的test包里新建一個名為HtmlFilter的class,如下:
public class HtmlFilter { //轉義 public static String filter(String message) { if (message == null) return (null); char content[] = new char[message.length()]; message.getChars(0, message.length(), content, 0); StringBuilder result = new StringBuilder(content.length + 50); for (int i = 0; i < content.length; i++) { switch (content[i]) { case '<': result.append("<"); break; case '>': result.append(">"); break; case '&': result.append("&"); break; case '"': result.append("""); break; default: result.append(content[i]); } } return (result.toString()); } }
然后在WebRoot下新建一個file,名為test.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>A tag library exercising SimpleTag handlers.</description> <tlib-version>1.0</tlib-version> <short-name>SimpleTagLibrary</short-name> <uri>http://tomcat.apache.org/jsp2-example-taglib</uri> <function> <name>filter</name> <function-class>test.HtmlFilter</function-class> <function-signature>java.lang.String filter(java.lang.String)</function-signature> </function> </taglib>
<function>元素用於描述一個EL自定義函數,其中:
<name>子元素用於指定EL自定義函數的名稱。
<function-class>子元素用於指定完整的java類名。
<function-signature>子元素用於指定java類中的靜態方法的簽名,方法簽名必須指明方法的返回值類型及各個參數的類型,各個參數之間用逗號分隔。
然后新建一個JSP文件,導入<%@ taglib uri="/WEB-INF/test.tld" prefix="fn" %>,在body中寫上:${fn:filter("<a href=''>點點</a>") }即可調用HtmlFilter類中的靜態方法filer了。
開發EL Function注意事項:
1)編寫完標簽庫描述文件后,需要將它放置到<web應用>\WEB-INF目錄中或WEB-INF目錄下的除了classes和lib目錄之外的任意子目錄中。
2)TLD文件中的<uri>元素用來指定該TLD文件的URL,在JSP文件中需要通過這個URL來引入該標簽庫描述文件。
2. SUN公司的EL函數庫
由於在JSP頁面中顯示數據時,經常需要對顯示的字符串進行處理,SUN公司針對於一些常見處理定義了一套EL函數庫供開發者使用。這些EL函數在JSTL開發包中進行描述,因此在JSP頁面中使用SUN公司的EL函數庫,需要導入JSTL開發包,並在頁面中導入EL函數庫,如下所示:
<%@ taglib uri="http://java.sun.com/jsp/jstl/functions" prefix="fn" %>
JSTL中的常用EL函數
1) fn:toLowerCase函數將一個字符串中包含的所有字符轉換為小寫形式,並返回轉換后的字符串,它接受一個字符串類型的參數,例如:
fn:toLowerCase("Www.Baidu.com")返回字符串為"www.baidu.com"
fn:toLowerCase("")返回值為空字符串。
fn.toUpperCase將一個字符串包含的所有字符轉換為大寫,參數與上面一樣
2) fn:trim函數刪除一個字符串的首尾空格,並返回刪除空格后的結果字符串,它接收一個字符串類型的參數。需要注意的是,fn:trim函數不能刪除字符串中間位置的空格。
3)fn:length函數返回一個集合或數組大小,歐返回一個字符串中包含的字符的個數,返回值為int類型。該函數接受一個參數,這個參數可以是<c:forEach>標簽的items屬性支持的任何類型,包括任意類型的數組、java.util.Collection、java.util.Iterator、java.util.Enumeration、java.util.Map等類的實例對象和字符串。如果fn:length函數的參數為null或者是元素個數為0的集合或數組對象,則函數返回0;如果參數時空字符串,則函數返回0。
4)fn:split函數以指定字符串作為分隔符,將一個字符串分隔成字符串數組並返回這個字符串數組。該函數接收兩個字符串類型的參數,第一個參數表示要分隔的字符串,第二個參數表示作為分隔符的字符串。如:fn:split("www.baidu.com",".")[1]的返回值為字符串"baidu"。
5)fn:join函數以一個指定的分隔符,將一個數組中的所有元素合並為一個字符串。fn:join函數接收兩個參數,第一個參數是要操作的字符串數組,第二個參數是作為分隔符的字符串。如果fn:join函數的第二個參數是空字符串,則fn:join函數的返回值直接將元素連接起來。例如:假設stringArray是保存在web域中的一個屬性,它表示一個值為{"www","baidu","com"}的字符串數組,則fn:join(stringArray,".")返回字符串"www.baidu.com"。fn:join(fn:split("www,baidu,com",","),".")的返回值為字符串"www.baidu.com"。
6)fn:contains函數檢測一個字符串中是否包含指定的字符串,返回值為布爾類型。fn:contains函數在比較兩個字符串是否相等時是大小敏感的。fn:contains函數接收兩個字符串類型的參數,如果第一個參數字符串中包含第二個參數字符串,則fn:contains函數返回true,否則返回false。如果第二個參數的值為空字符串,則fn:contains總是返回true。實際上,fn:contains(string, substring)等價於fn:indexOf(string, substring)!=-1。忽略大小的EL函數:fn:containsIgnoreCase
7)fn:startsWith函數用於檢測一個字符串是否是以指定字符串開始的,是則返回true,不是則返回false。fn:startsWith函數接收兩個字符串類型的參數,如果第一個參數字符串以第二個參數字符串開始,則函數返回為true,否則函數返回false,如果第二個字符串為空字符串,則函數總是返回true。與之對應的EL函數:fn:endsWith
8)fn:replace函數將一個字符串中包含的指定字符串替換為其它的指定字符串,並返回替換后的結構字符串。fn:replace方法接收三個字符串類型的參數,第一個參數表示要操作的源字符串,第二個參數表示元字符串中要被替換的子字符串,第三個參數表示要被替換成的字符串。如:fn:replace("www baidu com"," ",".")的返回值為字符串"www.baidu.com"。
9)fn:substring函數用於截取一個字符串的子字符串並返回截取到的子字符串。該函數接收三個參數:第一個參數用於指定要操作的源字符串,第二個參數是用於指定截取子字符串開始的索引值,第三個參數是用於指定截取子字符串結束的索引值,第二和第三個參數都是int類型,其值都是從0開始。
10)fn:substringAfter函數用於截取並返回一個字符串中的指定子字符串第一次出現之后的子字符串。該函數接收兩個字符串類型的參數:第一個表示要操作的源字符串,第二個表示指定的子字符串。]如:fn:substringAfter("www.baid.com",".")的返回值為字符串"baidu.com"與之對應的EL函數為:fn:substringBefore
11)fn:escapeXml函數表示轉義,將xml文件原封不動輸出,該函數有一個參數,接收被轉義的字符串。
EL表達式就總結這么多,如有錯誤之處歡迎留言指正~