今天剛學習了struts2的valueStack,在這里把自己學到的做個分享,說道valueStack就不得不提OGNL表達式===
struts2工作流程

1.OGNL(Object Graph Navigation Language)對象導航圖語言
Struts2框架使用OGNL作為默認的表達式語言,OGNL(Object Graph Navigation Language),是一種表達式語言,目的是為了在不能寫Java代碼的地方執行java代碼;主要作用是用來存數據和取數據的。
2 valueStack
valueStack是struts2的值棧空間,是struts2存儲數據的空間
Strut2的Action類通過屬性可以獲得所有請求相關的值,要在Action類中聲明與參數同名的屬性或者以類名小寫加屬性名如:user.name,就可以獲得這些參數值,在Struts2調用Action類的Action方法(默認是execute方法)之前,就會為相應的Action屬性賦值。這項功能Struts2要依賴於ValueStack對象來實現,每個Action類的對象實例會擁有一個ValueStack對象,這個對象貫穿整個Action的生命周期,
當Struts2接收到一個請求后,會先建立Action類的對象實例,但並不會立即調用Action方法,而是先將Action類的相應屬性放到ValueStack實現類ONGLValueStack對象root對象的頂層節點。只是所有的屬性值都是默認的值,如String類型的屬性值為null,int類型的屬性值為0等。在處理完上述工作后,Struts 2就會調用攔截器鏈中的攔截器,這些攔截器會根據用戶請求參數值去更新ValueStack對象頂層節點的相應屬性的值,最后會傳到Action對象,並將ValueStack對象中的屬性值,賦給Action類的相應屬性。當調用完所有的攔截器后,才會調用Action類的Action方法。ValueStack會在請求開始時被創建,請求結束時消亡。
3.valueStack底層相關的數據結構

CompoundRoot是繼承了Arraylist的集合,里面存放Action的實例、代理對象、自定義對象(Student)等數據
5 代碼展示valueStack
需求:通過頁面跳轉到指定的Action的方法中,在方法中通過
創建student實體類
package com.xsh.pojo; public class Student { private String name; public Student(String name) { super(); this.name = name; } public String getName() { return name; } public void setName(String name) { this.name = name; } }
struts.xml配置文件
<?xml version="1.0" encoding="UTF-8" ?> <!DOCTYPE struts PUBLIC "-//Apache Software Foundation//DTD Struts Configuration 2.3//EN" "http://struts.apache.org/dtds/struts-2.3.dtd"> <struts> <constant name="struts.devMode" value="true"/> <package name="default" namespace="/user" extends="struts-default"> <action name="login" class="com.xsh.test.LoginAction" method="execute"> <result>/success.jsp</result> </action> </package> </struts>
Action類
package com.xsh.test; import java.util.Map; import com.opensymphony.xwork2.ActionContext; import com.opensymphony.xwork2.ActionSupport; import com.opensymphony.xwork2.util.ValueStack; import com.xsh.pojo.Student; public class LoginAction extends ActionSupport { public String execute(){ System.out.println("進入方法====="); Map<String, Object> session = ActionContext.getContext().getSession(); session.put("sessionName", "sessionName"); Map<String, Object> request = (Map<String, Object>) ActionContext.getContext().get("request"); request.put("requestName", "requestName"); Map<String, Object> application = ActionContext.getContext().getApplication(); application.put("applicationName", "applicationName"); ValueStack valueStack = (ValueStack) request.get("struts.valueStack");//通過request對象獲得valueStack對象
System.out.println("valueStack的值======"); valueStack.getRoot().add(new Student("小白白"));//向valueStack的root屬性中添加自定義值
System.out.println(valueStack); return SUCCESS; } }
strut2的底層getroot()是接口ValueStack 定義的方法,返回CompoundRoot繼承了Arraylist的集合
/** * Get the CompoundRoot which holds the objects pushed onto the stack * * @return the root */ public abstract CompoundRoot getRoot();
/** * A Stack that is implemented using a List. * * @author plightbo * @version $Revision$ */ public class CompoundRoot extends ArrayList { public CompoundRoot() { } public CompoundRoot(List list) { super(list); } public CompoundRoot cutStack(int index) { return new CompoundRoot(subList(index, size())); } public Object peek() { return get(0); } public Object pop() { return remove(0); } public void push(Object o) { add(0, o); } }
登錄實現跳轉頁面login.jsp
<%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%> <% String path = request.getContextPath(); String basePath = request.getScheme()+"://"+request.getServerName()+":"+request.getServerPort()+path+"/"; %> <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"> <html> <head> <base href="<%=basePath%>"> <title>My JSP 'login.jsp' starting page</title> <meta http-equiv="pragma" content="no-cache"> <meta http-equiv="cache-control" content="no-cache"> <meta http-equiv="expires" content="0"> <meta http-equiv="keywords" content="keyword1,keyword2,keyword3"> <meta http-equiv="description" content="This is my page"> <!-- <link rel="stylesheet" type="text/css" href="styles.css"> --> </head> <body> <h1><a href="user/login">Check ValueStack</a></h1> </body> </html>
跳轉成功頁面success.jsp
String basePath = request.getScheme()+"://"+request.getServerName()+":"+request.getServerPort()+path+"/"; %> <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"> <html> <head> <base href="<%=basePath%>"> <title>My JSP 'success.jsp' starting page</title> <meta http-equiv="pragma" content="no-cache"> <meta http-equiv="cache-control" content="no-cache"> <meta http-equiv="expires" content="0"> <meta http-equiv="keywords" content="keyword1,keyword2,keyword3"> <meta http-equiv="description" content="This is my page"> <!-- <link rel="stylesheet" type="text/css" href="styles.css"> --> <%@ taglib prefix="s" uri="/struts-tags" %> </head> <body> <h1><s:debug/></h1> </body> </html>
點擊查看ValueStack,標題進入旋轉狀態(前提在代碼內打好斷點),查看斷電是的valueStack的狀態,如圖


在debug模式中,f6,繼續查看變化,通過getRoot()方法獲得的集合對象的add方法添加的Student方法已經添加到

5.運輸處結果

打印ValueStack對象的hash碼是OnglValueStack,查看ObglValueStack類
可知:
a.OgnlValueStack實現了ValueStack的接口
b.屬性root是 CompoundRoot類型,CompoundRoot繼承了Arraylist的集合
c.context是一個Map<String, Object>類型的集合
d.通過Context的get(key)方法獲得的Session、request、Application對象還是還是一個Map<String, Object>類型的集合
/** * Ognl implementation of a value stack that allows for dynamic Ognl expressions to be evaluated against it. When evaluating an expression, * the stack will be searched down the stack, from the latest objects pushed in to the earliest, looking for a bean with a getter or setter * for the given property or a method of the given name (depending on the expression being evaluated). * * @author Patrick Lightbody * @author tm_jee * @version $Date$ $Id$ */ public class OgnlValueStack implements Serializable, ValueStack, ClearableValueStack, MemberAccessValueStack { public static final String THROW_EXCEPTION_ON_FAILURE = OgnlValueStack.class.getName() + ".throwExceptionOnFailure"; private static final long serialVersionUID = 370737852934925530L; private static final String MAP_IDENTIFIER_KEY = "com.opensymphony.xwork2.util.OgnlValueStack.MAP_IDENTIFIER_KEY"; private static final Logger LOG = LoggerFactory.getLogger(OgnlValueStack.class); CompoundRoot root; transient Map<String, Object> context; Class defaultType; Map<Object, Object> overrides; transient OgnlUtil ognlUtil; transient SecurityMemberAccess securityMemberAccess; private boolean devMode;
