之前用ssh架構,在action中總是將查詢出的資料存到session或者request中,然後傳到前台進行顯示;但後來我看到有些代碼 在action中聲明一個list或者其他的成員變數,然後將查詢到的資料賦給這個成員變數,然後再jsp頁面通過${list}或者 ${變數名} 就可以在前台顯示了。之前一直不明白,經過查閱資料,這樣做可行的原因:
用JSTL的${tip}可以訪問Action中定義tip屬性:private String tip,
${tip}實際上是訪問的request範圍中的tip,實際是調用了action中的getTip()方法,所以能訪問。
然後Struts2是把值棧儲存在 request 中的。你可以通過 request.getAttribute( "struts.valueStack" ); 得到它。
經過我的分析研究,結論如下:其實資料是被存放在requestContext中的,而request對象及其session等對象又被放入了ActionContext中,通過ognl運算式是從ActionContext中擷取requestContext裡面存放的對象,而用jstl是直接從request中擷取對象
即:用jstl是直接擷取,而用ognl是間接的從ActionContext中擷取request對象中的資料
ActionContext的解釋如下:ActionContext中包含了大量的環境資訊,包括:Locale、Application、Session、ValueStack等等。
查看該類源碼,發現它裝飾了getAttribute()方法:
Java code
?
123456789101112131415161718192021222324252627282930 |
public
Object getAttribute(String s) {
if
(s != null && s.startsWith(
"javax.servlet" )) {
// don't bother with the standard javax.servlet attributes, we can short-circuit this
// see WW-953 and the forums post linked in that issue for more info
return
super .getAttribute(s);
}
ActionContext ctx = ActionContext.getContext();
Object attribute =
super .getAttribute(s);
boolean
alreadyIn = false ;
Boolean b = (Boolean) ctx.get( "__requestWrapper.getAttribute" );
if
(b != null ) {
alreadyIn = b.booleanValue();
}
// note: we don't let # come through or else a request for
// #attr.foo or #request.foo could cause an endless loop
if
(!alreadyIn && attribute == null
&& s.indexOf( "#" ) == - 1 ) {
try
{
// If not found, then try the ValueStack
ctx.put( "__requestWrapper.getAttribute" , Boolean.TRUE);
ValueStack stack = ctx.getValueStack();
if
(stack != null ) {
attribute = stack.findValue(s);
}
}
finally {
ctx.put( "__requestWrapper.getAttribute" , Boolean.FALSE);
}
} |
結論:
EL能訪問到值棧中的內容。
之所以能訪問到,是因為EL可以訪問request的getAttribute()方法,而此方法被Sturts2進行了裝飾,可以訪問到ActionContext,進而可以訪問到值棧。
總結一下:
為什麼JSTL可以訪問Action中的屬性,如:
private String tip;
public String getTip(){
return this.tip;
}
在JSP頁面中可用${tip}訪問到tip屬性。
總結一下答案:
①JSTL能訪問Action中通過request.setAttribute("")設定的值。這是大家所熟悉的。
②JSTL能訪問Action中屬性(通過getXXX方法實現訪問)。
因為ValueStack存在於request,所以用${tip}訪問時的順序是:request先訪問ValueStack,ValueStack從中找出tip對應的值。