【Head First Servlets and JSP】筆記23:Expression Language(EL) 完全攻略
基本上是《Head First Servlets and JSP》內容的整理、擴充。順便推薦一個供參考的JSP教程:JSP Tutorial 內容很全面,還有一些有趣的實例。
- 完整代碼參考
- EL隱式對象匯總
- pageContext使用參考
- EL表達式的基本規則
- 關於EL的一些細節
- 通過EL獲得request參數
- 從request得到更多信息
- 獲得Request Method?
- xxxxScope有意義嗎?
- 通過EL調用函數
- EL與數學運算
1、EL隱式對象匯總。如下所示:
更詳細的內容可以參考 JSP 4個域對象-9個內置對象-11個EL隱式對象
2、EL中的“爸爸”——pageContext
3、EL表達式的基本規則
EL表達式的基本格式為${........},下面所說的映射指的的是類似於map(也叫字典)的東西(具有“鍵”和“值”);而bean指的是例如person、dog這樣的對象。
點號
[]是更好的點號
4、使用EL的一些細節
【細節A】
【細節B】
也就是說,如果不是list["xxx"]而是list[xxx]的話,xxx將會被計算!
【細節C】
5、通過EL獲得request參數,類似於下面這樣的
鏈接到代碼
6、如果想從請求得到更多信息呢?例如說,你想得到服務器主機的信息。鏈接到代碼
7、不能通過,也不能通過(EL根本沒有request這個隱式對象!),
關鍵時刻還得靠pageContext!
xxxScope這種東西,只是屬性(attribute)的一個映射表罷了!鏈接到代碼
8、如果我們想獲取某個person的名字,既可以使用${person.name}(自動查找4個作用域!),也可以使用${requestScope.person.name}(指定作用域查找),
前者更為簡單、直觀,那麽xxxScope有存在的意義嗎?
- 防止命名沖突,在多個作用域存在同名屬性能夠正確引用。
- 解決一種特殊情況,比如我們在Servlet中,或者是JSP腳本中使用右邊的句子
在這之後要獲得person的名字,類似這樣是行不通的(都是點號的鍋!。。),這種情況只有xxxScope可以解決,這樣就ok了。
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>小狗領養中心</title> </head> <body> <form action="addDog" method="get" accept-charset="UTF-8"> <p>你的名字:<input type="text" name="name" value="王明" style="width:80px;"></p> <p>年齡:<input type="text" name="age" value="19" style="width:50px;"></p> <p>qq:<input type="text" name="qq" value="55667788" style="width:90px;"></p> <hr> <!-- 下面是演示內容 --> <p>第一個食物:<input type="text" name="food" value="青菜"></p> <p>第二個食物:<input type="text" name="food" value="馬鈴薯"></p> <p><input type="submit" value="確定領養"></p> </form> </body> </html>
<%@ page contentType="text/html;charset=UTF-8" language="java" %> <html> <head> <title>領養成功</title> </head> <body> <jsp:useBean id="person" type="po.Person" scope="request" /> <jsp:setProperty name="person" property="age" /> <p>成功領養!狗的名字是:${person.dog.name}</p> <hr> <%-- person 是請求作用域的一個屬性,點號右邊是“bean性質” --%> <p>${person.name}</p> <p>${person.age}</p> <p>${person.qq}</p> <p>${person.dog}</p> <hr> <%-- 表達式左側還可以是一個EL隱式對象,嘗試輸出一些東西 --%> <p>打印【person對象】:${requestScope.person}</p> <p>打印【Request parameters】:${param}</p> <p>換種方式打印:${paramValues}</p> <p>打印【HTTP request headers】:${header}</p> <p>打印這個:${cookie}</p> <%-- 點號右邊是“映射鍵” --%> <p>${param.age}</p> <p>${param.qq}</p> <%-- 通過JSP直接獲得請求參數(Request parameters) --%> <p>${cookie.JSESSIONID}</p> <%-- paramValues其實是這麽用的 --%> <p>food1: ${paramValues.food[0]}</p> <p>food2: ${paramValues.food[1]}</p> <%-- 得到“host”首部 --%> <p>Host is: ${header.host}</p> <p>or:${header["host"]}</p> <%-- 得到“http”請求方法,這裏涉及到一個問題 --%> <p>Method is: ${pageContext.request.method}</p> <%-- 打印JSESSIONID --%> <p>JSESSIONID is: ${cookie.JSESSIONID.value}</p> <%-- 打印上下文初始化參數值 --%> <p>my email is: ${initParam.myEmail}</p> <hr> <%-- pageContext是個例外,它是實實在在的pageContext對象的引用 --%> <p>${pageContext.findAttribute("person")}</p> <p>${pageContext.request.queryString}</p> <hr> <%-- [] 演示 --%> <p>${person.name}</p> <p>${person["name"]}</p> <%-- 打印String數組 --%> <p>數組:${musicList}</p> <p>${musicList[0]}</p> <p>${musicList[2]}</p> <p>${musicList[99]}</p> <%-- 越界訪問不會拋錨,也不會留白 --%> <p>${musicList["2"]}</p> <%-- 自動完成類型轉換 --%> <%-- 這樣是合法的! --%> <p>${musicMap[J]}</p> </body> </html>
完整war打包下載
成功領養!狗的名字是:小黃
王明
19
55667788
[email protected]
打印【person對象】:[email protected]
打印【Request parameters】:{qq=55667788, name=ç??æ??, age=19, food=é??è??}
換種方式打印:{qq=[Ljava.lang.String;@a3a764c, name=[Ljava.lang.String;@5a79efe0, age=[Ljava.lang.String;@3e48d526, food=[Ljava.lang.String;@59ce9ecc}
打印【HTTP request headers】:{referer=http://localhost:8080/, accept-language=zh-CN,zh;q=0.8, cookie=JSESSIONID=62E8FAF608E7A23D82CE1ECD0EF32C12, host=localhost:8080, upgrade-insecure-requests=1, connection=keep-alive, cache-control=max-age=0, accept-encoding=gzip, deflate, sdch, br, user-agent=Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/58.0.3029.81 Safari/537.36, accept=text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8}
打印這個:[email protected]}
19
55667788
[email protected]
food1: é??è??
food2: 马é??è?¯
Host is: localhost:8080
or:localhost:8080
Method is: GET
JSESSIONID is: 62E8FAF608E7A23D82CE1ECD0EF32C12
my email is: [email protected]
[email protected]
name=%E7%8E%8B%E6%98%8E&age=19&qq=55667788&food=%E9%9D%92%E8%8F%9C&food=%E9%A9%AC%E9%93%83%E8%96%AF
王明
王明
數組:[Ljava.lang.String;@40803f51
music1
music3
music3
青花瓷
9、通過EL調用函數,你需要做的事情如下:
讓我們來寫一個擲骰子的JSP。(就是打開頁面,隨機出來一個1~6的數)
ttag library descriptor這部分內容好像有點舊了,費了一番功夫才跑出來。
首先要從oracal下載一個這樣的文件web-jsptaglibrary_2_0.xsd(google搜索一下就有了,或者點這裏),放在WEB-INF目錄下
創建 myFunctions.tld,同樣放在WEB-INF目錄下,內容如下
<?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 web-jsptaglibrary_2_0.xsd" version="2.0"> <tlib-version>1.2</tlib-version> <short-name>hi</short-name> <function> <name>rollIt</name> <function-class>service.DiceRoller</function-class> <function-signature> int rollDice() </function-signature> </function> </taglib>
在JSP中聲明這個函數,
<%@ taglib prefix="mine" uri="/WEB-INF/myFunctions.tld" %>
使用函數,
<p>${mine:rollIt()}</p>
關於它的參數
10、EL與數學運算
EL可以妥善的處理非法運算
<hr> <h3>Doing Math</h3> <% String num = "2"; request.setAttribute("num", num); Integer i = new Integer(3); request.setAttribute("integer", i); ArrayList list = new ArrayList(); list.add("true"); list.add("false"); list.add("2"); list.add("10"); request.setAttribute("list", list); %> <p>${num > 3}</p> <p>${integer le 12}</p> <p>${requestScope["nteger"] ne 4 and 6 le num || false}</p> <p>${list[0] || list["1"] and true}</p> <p>${num > integer}</p> <p>${num == integer-1}</p> <jsp:useBean class="po.Dog" id="myDog"> <jsp:setProperty name="myDog" property="name" value="${list[1]}" /> </jsp:useBean> <p>${myDog.name and true}</p> <p>${42 div 0}</p> <p>${mine:rollIt() le 0}</p>
Doing Math
false
true
false
true
false
true
false
Infinity
false
addDog.java
package service; import po.Dog; import po.Person; import javax.servlet.*; import javax.servlet.http.*; import java.io.IOException; import java.util.HashMap; import java.util.Map; import java.util.Random; public class addDog extends HttpServlet { @Override protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { req.setCharacterEncoding("utf-8"); Person p = new Person(); p.setName(new String(req.getParameter("name").getBytes("iso8859-1"),"UTF-8")); // 解決form提交中文的亂碼問題! p.setQq(req.getParameter("qq")); p.setDog(next()); req.setAttribute("person", p); // 為了 el [] 的演示需要 String[] music = {"music1", "music2", "music3"}; req.setAttribute("musicList", music); // 演示需要 Map musicMap = new HashMap(); musicMap.put("DJ", "BT"); musicMap.put("J CHOU", "青花瓷"); req.setAttribute("musicMap", musicMap); req.setAttribute("J", "J CHOU"); RequestDispatcher view = req.getRequestDispatcher("/result.jsp"); view.forward(req, resp); } @Override protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { doGet(req, resp); } private Random rand = new Random(47); // 47是一個無關緊要的數字 private Dog next() { switch (rand.nextInt(3)) { default: case 0: return new Dog("大黃"); case 1: return new Dog("富貴"); case 2: return new Dog("小黃"); } } }
【Head First Servlets and JSP】筆記23:Expression Language(EL) 完全攻略