首先來了解一下ActionMessages類的結構:
在ActionMessages中包含著一個HashMap,其中的key就是add方法的property參數,然而他的值對應的是一個ActionMessageItem,ActionMessageItem是該類的一個內部類,當中包含了一個ArrayList。
由此可見,一個property中可以包含著多個ActionMessage,這些ActionMessage都將保存在ActionMessageItem的ArrayList中。
?1?public?void
?add(String?property,?ActionMessage?message)?{
?2?
?3?????????ActionMessageItem?item?=
?(ActionMessageItem)?messages.get(property);
?4?????????List?list?=?null
;
?5?
?6?????????if?(item?==?null
)?{
?7?????????????list?=?new
?ArrayList();
?8?????????????item?=?new?ActionMessageItem(list,?iCount++
,?property);
?9?
10?
????????????messages.put(property,?item);
11?????????}?else
?{
12?????????????list?=
?item.getList();
13?
????????}
14?
15?
????????list.add(message);
16?
17?????}
每次添加新的ActionMessage中,ActionMessages類會判斷HashMap中的get(property)是否存在,如果存在的話,就獲得該list?=?item.getList();并把ActionMessage添加到其中。如果不存在,就會創(chuàng)建一個新的list?=?new
?ArrayList();
再將內容添加到當中去。總的來說,ActionMessages就是一個保存信息的容器。通常ActionMessages是不會單獨使用的,和他相關的一些Struts組件會對其進行訪問和操作:
<html:errors>標簽
<html:errors>標簽是一個Struts組件,他的內部標簽類對ActionMessages類的子類ActionErrors進行訪問。通過在request和session中找到ActionErrors來獲得相關信息。在此之前,先來了解下<html:errors>標簽的幾個重要屬性:
name屬性:
指定ActionMessages在request和session范圍內的屬性key.默認值為Globals.ERROR_KEY。由此我們可以了解到Struts是如此保存和獲取ActionMessages的:
保存:
ActionErrors errors = new ActionErrors();
request.setAttribute(Globals.ERROR_KEY ,errors);或者
session.setAttribute(Globals.ERROR_KEY ,errors);
獲取:
ActionErrors errors = new ActionErrors();
errors = (ActionErrors)request.getAttribute(Globals.ERROR_KEY);或者
errors = (ActionErrors)session.getAttribute(Globals.ERROR_KEY);或者
該屬性通常我們不用設置和更改他,用默認值就可以啦。
property屬性:
用來指定消息的屬性,如果不設置該屬性,那么<html:errors>標簽將顯示ActionMessages中的所有屬性。如果設置了該屬性,則只顯示HashMap中Key為property屬性值的ArrayList集合。通常,我們在調用ActionMessages的add方法時,會指定add方法的property參數,也就是第一個參數,將相關信息添加到指定的property對應的ArrayList中。那么我們要顯示相關信息時,就可以指定輸出<html:errors>標簽的property屬性對應的ArrayList,這兩個property是相互對應的。
bundle屬性:
指定資源文件的key屬性。缺省的情況下調用的是默認的資源文件Application.properties。
如在struts-config.xml中聲明的資源文件信息如下:
? <
message
-
resources?parameter
=
"
com.kook.struts.ApplicationResources
"
?
/>
??
<
message
-
resources?key
=
"
ch
"
?parameter
=
"
com.kook.struts.ApplicationResources_ch
"
?
/>
??
<
message
-
resources?key
=
"
en
"
?parameter
=
"
com.kook.struts.ApplicationResources_en
"
?
/>
對應的add方法如下:
1?ActionErrors?errors?=?new
?ActionErrors();
2?if(name==null?||?name.length()<1
)
3?
{
4???????errors.add("name",new?ActionMessage("kong"
));
5?
?}
6??return?errors;
new
?ActionMessage(
"
kong
"
)對應在key="en"的資源文件中為:
kong=bu neng wei kong
JSP中的<html:errors>標簽:
1?<html:errors?property="name"?bundle="en"/>
這時候將會輸出key="en"的資源文件中的"kong"對應的信息:bu neng wei kong
<html:messages>標簽
<html:messages>標簽是用來在JSP頁面上輸出一條消息的。通常我們在做添加數據的時候,如果添加成功,通常會在前臺頁面反饋給用戶一條“添加成功”的信息,這時候我們就可以用到這個標簽。
name屬性:
是指ActionMessages對象保存在request或session中的屬性key,即request.setAttribute("heihei", messages);中的第一個參數。
message屬性:如果為true,表示是從request或session中取得key為Globals.MESSAGE_KEY的ActionMessages對象,此時該標簽設置的name屬性的無效的。如果為false,表示從該標簽的name屬性來獲得request或session的key值。缺省值就為false。
id屬性:這個屬性就不說了,檢索出ActionMessages集合中單個對象的標識,他和<logic:iterate>的id是同一個意思。
小實驗:
在action中的execute方法中添加如下代碼:
1?ActionMessages?messages?=?new?ActionMessages();
2?????????
3 messages.add("",?new?ActionMessage("haha",false));
4?????????
5?this.saveMessages(request,?messages);????????
6?
7?return?new?ActionForward("/form/hello.jsp");
表示往ActionMessages對象中添加一條信息new?ActionMessage("haha",false),并保存在request當中this.saveMessages(request,?messages);??那么在這個方法中,他是如何保存ActionMessage對象的呢?下面是?saveMessages?方法的源代碼:?
?1?protected?void?saveMessages(
?2?????????HttpServletRequest?request,
?3?????????ActionMessages?messages)?{
?4?
?5?????????//?Remove?any?messages?attribute?if?none?are?required
?6?????????if?((messages?==?null)?||?messages.isEmpty())?{
?7?????????????request.removeAttribute(Globals.MESSAGE_KEY);
?8?????????????return;
?9?????????}
10?
11?????????//?Save?the?messages?we?need
12?????????request.setAttribute(Globals.MESSAGE_KEY,?messages);
13?????}
觀察這段代碼不難發(fā)現(xiàn),他是將ActionMessages存放在key為Globals.MESSAGE_KEY當中的,因此我們在調用ActionMessages的add方法時,他的property參數(add方法的第一個參數)就沒有必要讓我們自己去手動指定了,因為不論你指定什么參數,只要調用了saveMessages方法(這是前提),他只會將信息保存在固定的常量key中。
這時前臺的hello.jsp頁面的顯示代碼為:
1?<html:messages?id="a"?message="true">
2?????<bean:write?name="a"/>
3?</html:messages>
上面代碼設置了message屬性,表示從Globals.MESSAGE_KEY中獲取信息,前面也有提到,此時指定name屬性是無效的。
那如果我想只顯示我自己指定的信息怎么辦呢?
我們可以不使用saveMessages方法而使用最原始的辦法,通常最原始的辦法也是最有效的,Struts其實是封裝了許多最原始的實現(xiàn)。我們先將action中的代碼改為:
ActionMessages?messages?
=
?
new
?ActionMessages();
????????
messages.add(
""
,?
new
?ActionMessage(
"
haha
"
,
false
));
????????
request.setAttribute(
"
show
"
,?messages);
return
?
new
?ActionForward(
"
/form/hello.jsp
"
);
然后在JSP頁面中指定name屬性,而將message設為false就可以了:
1?<html:messages?id="a"?name="show">
2?????<bean:write?name="a"/>
3?</html:messages>
這里是直接省略了message屬性,因為他的缺省值就是false。這樣就可以達到輸出自己指定屬性的信息啦!
?