在 Java EE 7 之後,釋出了 Expression Language 3.0,成為一個獨立的規格(JSR 341)。
在 EL 3.0 中,允許指定變數,例如,想要將 a
指定為 "10"
,b
指定為 "20"
,可以如下:
${a = "10"}
${b = "20"}
被指定值之後,EL 3.0 會將 a
、b
的值輸出至頁面,實際上,變數會被指定為頁面範圍屬性,可以使用 pageContext.getAttribute("a")
取得,上面的例子中相當於:
<% pageContext.setAttribute("a", "10") %><%= pageContext.getAttribute("a") %>
<% pageContext.setAttribute("b", "10") %><%= pageContext.getAttribute("b") %>
如果在 EL 運算式中加上分號,可以繼續執行指定的 EL 運算式,而最後一個運算式的結果會顯示在頁面上,例如底下會顯示 20:
${a = "10"; b = "20"}
而底下會顯示 0:
${a = "10"; b = "20"; 0}
如果想要建立 List
、Set
或 Map
,可以如下:
${scores = [100, 95, 88, 75]}
${names = {"Justin", "Monica", "Irene"}}
${passwords={"Admin" : "123456", "Manager" : "654321"}}
如果想要串接字串,可以使用 +=
,例如:
${firstName = "Justin"}
${lastName = "Lin"}
${firstName += lastName}
注意,這跟一般程式語言中,a += b
相當於 a = a + b
不同,在 ${firstName += lastName}
時,只是用 +=
來區別 +
,以便表示字串串接,執行過後顯示出串接結果為 "JustinLin"
,然而 firstName
仍然是 "Justin"
,如果想要 firstName
被指定為串接後的結果,必須撰寫 ${firstName = firstName += lastName}
。
+
仍然是用在數字運算,例如運算的結果會是 30:
${a = "10"}
${b = "20"}
${a + b}
如果 a
、b
無法被剖析為數值,就會引發 NumberFormatException
。
然而,以下運算的結果會是 "1020"
,因為 +=
會串接字串:
${a = "10"}
${b = "20"}
${a += b}
你可以直接呼叫物件的方法,例如將字串轉大寫:
${name = "Justin"}
${name.toUpperCase()}
如果呼叫的方法沒有傳回值,那麼就不會顯示結果,例如:
${pageContext.setAttribute("token", "123")}
你甚至可以直接呼叫靜態方法或取用靜態成員,預設 java.lang
中的類別是可以直接呼叫其靜態方法或取用靜態成員的:
${Integer.parseInt("123")}
${Math.round(1.6)}
${Math.PI}
如果要是其他套件中的類別,可以透過 pageContext.getELContext().getImportHandler().importClass(".....")
來追加,例如:
${pageContext.ELContext.importHandler.importClass("java.time.LocalTime")}
${LocalTime.now()}
除了 importClass()
之外,也可以使用 importPackage()
、importStatic()
等方法,如果要呼叫建構式的話,直接於類別名稱之後接上 ()
就可以了,不用加上 new
。例如:
${String("Justin")}
EL 也支援 Lambda 運算式,例如:
${plus = (x, y) -> x + y}
${plus(10, 20)}
${() -> plus(10, 20) + plus(30, 40)}
如果 Lambda 運算式有參數的話,可以使用 ()
指定引數來運算,若沒有參數,那麼會立即運算。
既然 EL 3.0 中,可以呼叫方法,也可以使用 Lambda 運算式,那麼就可以形成 Java SE 8 那種流暢的 Stream 風格:
${names = ["Justin", "Monica", "Irene"]}
${names.stream().filter(name -> name.length() == 5).toList()}