你可以在 JSP 中將物件設定至 page
、request
、session
或 application
範圍中作為屬性,基本上是透過 setAttribute()
方法設定屬性,使用 getAttribute()
取得屬性,但這些方法呼叫必須在 Scriptlet 中進行。如果不想撰寫 Scriptlet,可以考慮使用 <jsp:useBean>
、<jsp:setProperty>
與 <jsp:getProperty>
。
不過 <jsp:getProperty>
在使用上,語法仍是較為冗長。如果只是要取得屬性,使用 EL 則可以更為簡潔。例如:
<h1><jsp:getProperty name="user" property="name"/>登入成功</h1>
如果使用 EL 來撰寫的話,則可以修改如下:
<h1>${user.name}登入成功</h1>
在 EL 中,可以使用 EL 隱含物件指定範圍來存取屬性,EL 隱含物件將在稍後介紹。
若不指定屬性的存在範圍,則預設是以 page
、request
、session
、application
的順序來尋找 EL 中所指定的屬性。以上例而言,就是在 page
範圍中找到了 user
屬性,點運算子後跟隨著 name
,表示利用物件的 getName()
方法取得值,而後顯示在網頁上。
如果 EL 存取的對象是個陣列物件,則可以使用 []
運算子來指定索引以存取陣列中的元素。例如若網頁的某處在請求範圍中設定了陣列作為屬性:
<%
String[] names = {"caterpillar", "momor", "hamimi"};
request.setAttribute("array", names);
%>
如果現在打算取出屬性,並存取陣列中的每個元素,則可以如下使用 EL:
名稱一 : ${array[0]} <br>
名稱二: ${array[1]} <br>
名稱三: ${array[2]} <br>
不僅僅是陣列物件可以在 []
中指定索引來存取元素,如果屬性是個 List
型態的物件,也可以使用 []
運算子指定索引來進行存取元素。
點運算子(.
)與 []
運算子需要特別說明。在某些情況下,可以使用點運算子(.
)的場合,也可以使用 []
運算子。以下先列點歸納:
- 如果使用點(
.
)運算子,則左邊可以是 JavaBean 或Map
物件。 - 如果使用
[]
運算子,則左邊可以是 JavaBean、Map
、陣列或List
物件。
所以你不只可以使用點(.
)運算子來取得 JavaBean 屬性,也可以使用 []
運算子。例如,你可以用點(.
)運算子取得 User
的 name
屬性:
${user.name}
也可以使用 []
運算子來取得取得 User
的 name
屬性:
${user["name"]}
如果想取得 Map 物件中的值,點(.
)運算子或[]運算子都可以使用。例如網頁中若有某個地方有以下的程式碼:
<%
Map<String, String> map = new HashMap<>();
map.put("user", "caterpillar");
map.put("role", "admin");
request.setAttribute("login", map);
%>
則你可以在網頁某處使用點運算子取得 Map
中的值:
User: ${login.user}<br>
Role: ${login.role}<br>
也可以在網頁某處使用 []
運算子取得 Map
中的值:
User: ${login["user"]}<br>
Role: ${login["role"]}<br>
基本上,當左邊是 Map
物件時,建議使用 []
運算子,因為如果設定 Map
時的鍵名稱有空白或點字元時,這是讓你可以正確取得值的方式。例如:
<%
Map<String, String> map = new HashMap<>();
map.put("user name", "caterpillar");
map.put("local.role", "admin");
request.setAttribute("login", map);
%>
...
User: ${login["user name"]}<br>
Role: ${login["local.role"]}<br>
[]
運算子的右邊,除了可以是 JavaBean、Map
外,也可以是陣列或 List
型態的物件。之前示範過陣列的例子,以下則是個 List
的例子:
<%
List<String> names = new ArrayList<>();
names.add("caterpillar");
names.add("momor");
request.setAttribute("names", names);
%>
...
User 1: ${names[0]}<br>
User 2: ${names[1]}<br>
你也可以在指定索引時使用雙引號,例如 ${names["0"]}
,不過一般指定索引不會這麼特別寫。事實上,當 []
運算子當是使用雙引號("
)指定時,就是作為鍵名稱或索引來使用。如果 []
運算子中不是使用雙引號,則會嘗試作運算,結果再給 []
來使用。例如:
<%
List<String> names = new ArrayList<>();
names.add("caterpillar");
names.add("momor");
request.setAttribute("names", names);
%>
...
User : ${names[param.index]}<br>
在這個範例的 EL 中,使用了 param.index
,param
是 EL 隱含物件,表示請求參數,這個範例會先尋找請求參數中 index
的值,然後再作為索引值給 []
使用。所以如果請求時使用了 index=0
,則顯示 "caterpillar"
,使用 index=1
,則顯示 "momor"
。所以,[]
中也可以進行巢狀。例如:
<%
List<String> names = new ArrayList<>();
names.add("caterpillar");
names.add("momor");
request.setAttribute("names", names);
Map<String, String> datas = new HashMap<>();
datas.put("caterpillar", "caterpillar's data");
datas.put("momor", "momor's data");
request.setAttribute("datas", datas);
%>
// ...
User data: ${datas[names[param.index]]}<br>
根據 EL,如果如果請求時使用了 index=0
,則會取得 names
中索引 0 的值 "caterpillar"
,然後用取得的值作為鍵,再從 datas
中取得對應的 "caterpillar's data"
。