1. 程式人生 > >【Head First Servlets and JSP】筆記23:Expression Language(EL) 完全攻略

【Head First Servlets and JSP】筆記23:Expression Language(EL) 完全攻略

首部 基本 light == 命名 shm sign pack index

基本上是《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有存在的意義嗎?

  1. 防止命名沖突,在多個作用域存在同名屬性能夠正確引用。
  2. 解決一種特殊情況,比如我們在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) 完全攻略