struts2值栈,OGNL表达式,interceptor
struts2獲取servlet api
第一種獲取方式
獲得原生request
HttpServletRequest request = ServletActionContext.getRequest();
獲得原生response
HttpServletResponse response = ServletActionContext.getResponse();
第二種獲取方式
實現ServletRequestAware,獲取原生request
實現ServletResponseAware,獲取原生response
OGNL表達式
OGNL是對象圖導航語言的縮寫,它是一種功能強大的表達式語言,通過它簡單一致的表達式語法,可以存取對象的任意屬性,調用對象的方法,實現字段類型轉化等功能......
OGNL的作用:支持對象的操作,調用對象的方法,支持靜態成員訪問,支持靜態成員訪問,支持賦值操作與表達式串聯
OGNL三要素:表達式 OgnlContext(上下文) Root (根)
OGNL對象操作:
@Testpublic void test1() throws Exception {//獲取ognl對象OgnlContext context = new OgnlContext();//獲取根Object root = context.getRoot();Object value = Ognl.getValue("'hello'.length()", context, root);System.out.println(value);}OGNL靜態成員訪問
@Testpublic void test2() throws Exception {//獲取ognl對象OgnlContext context = new OgnlContext();//獲取根Object root = context.getRoot();Object value = Ognl.getValue("@java.lang.Math@random()", context, root);System.out.println(value);}如果不能成功執行,是因為struts默認靜態成員掉用是關閉的,需要在配置中打開;
<constant name="struts.ognl.allowStaticMethodAccess" value="true"></constant>訪問OGNL上下文
@Testpublic void test3() throws Exception {//獲取ognl對象OgnlContext context = new OgnlContext();//向上下文中存儲數據context.put("username", "jack");//獲取根Object root = context.getRoot();Object value = Ognl.getValue("#username", context, root);System.out.println(value);}ognl操作集合
@Testpublic void test4() throws Exception {//獲取ognl對象OgnlContext context = new OgnlContext();//獲取根Object root = context.getRoot();Object value = Ognl.getValue("{'111','222','333'}", context, root);//這里就相當于建立了一個list集合 System.out.println(value);//把list集合放入root根中 context.setRoot(value);//獲取list中的數據Object value2 = Ognl.getValue("[1]", context, context.getRoot());System.out.println(value2);}這里需要特別注意的是:這里的root不能用上面的root,用上面的root會取不到list中的值
在struts2框架中我們使用ognl表達式的作用是從valueStack中獲取數據,我們在struts2框架中可以使用
ognl+valueStack達到在頁面上來獲取數據,這就需要使用<s:property value="表達式">來使用
要使用<s:property value="表達式">就要導入核心標簽庫
<%@taglib prefix="s" uri="/struts-tags" %>下面就可以使用:
<s:property value="'hello'.length()"/> <s:property value="@java.lang.Math@random"/>下面介紹非常重要的值棧
我們使用valueStack的主要目的是將action中的數據帶到jsp頁面,它就是一個容器;
在struts2中它就是一個接口:com.opensymphony.xwork2.util.ValueStack
它的實現類是:com.opensymphony.xwork2.ognl.OgnlValueStack
struts2中的action是一個多例的,每一次請求都會有一個新的action對應,所以它不存在線程安全問題;
一個valueStack對應一個action,valueStack貫穿整個action;
request--action--actionContext--valueStack
所以valueStack保存在request中
valueStack由兩部分組成:
CompoundRoot:它就是一個arraylist,主要用于存儲action的相關數據
Map<String,Object> context:就是一個map,主要用于存儲一些引用,關于web開發中的相關信息
pameters :請求參數
request:請求對象中所有屬性
session:會話對象中所有屬性
application:application對象中的所有發展
struts2框架中使用ognl表達式來獲取valueStack中的數據,使用#就是從非root根中獲取數據
獲取valueStack的兩種方式
1.直接通過request獲取
@Testpublic void test1() {//通過request獲取ValueStack vs = (ValueStack) ServletActionContext.getRequest().getAttribute(ServletActionContext.STRUTS_VALUESTACK_KEY);}2.使用actionContext來獲取
@Testpublic void test2() {//通過actioncontext來獲取ActionContext context = ActionContext.getContext();ValueStack valueStack = context.getValueStack();}那么actionContext到底是什么呢:
它是action的上下文對象,struts2使用它來保存action在執行過程中所需要的一些對象,例如:session,application
它通過getContext()靜態方法得到
struts2會根據每一次的request請求創建actionContext,它是與線程綁定的,每一次請求就是每一個線程,每一個request
都會創建一個action,每個action對應一個actionContext,所以每一次請求也對應著一個valueStack
特別注意的是:valueStack存儲數據的時候,主要是向root中存儲;
對于繼承了ActionSupport類的action類,瀏覽器傳入的數據是存儲在model對象中;
使用了表達式也可以從value中獲取數據是因為struts2對request中的getAttribute進行了增強,,如果request域中找不到數據,就會
在valueStack中獲取
?
ognl中的特殊字符
#號:代表的是從飛root中獲取數據
%:用戶強制是否要解析ognl表達式
$:主要是從配置文件中來獲取valueStack中數據
一個展示商品信息的例子
在jsp頁面中點擊顯示商品的連接,然后封裝商品,保存然后跳轉到showProduct頁面
<a href="${pageContext.request.contextPath }/Demo3Action">顯示商品</a>跳轉到action中處理數據:
public class Demo3Action extends ActionSupport{//封裝product的數據public String show() throws Exception {List<Product> list = new ArrayList<>();//模擬數據Product p1 = new Product();p1.setName("電視");p1.setCount(100);p1.setPrice(2000);Product p2 = new Product();p2.setName("冰箱");p2.setCount(200);p2.setPrice(1000);//存儲到集合 list.add(p1);list.add(p2);//保存到值棧中ValueStack vs = ActionContext.getContext().getValueStack();System.out.println(list);vs.set("list", list);return "show";}}跳轉到顯示頁面
<s:iterator value="list"><tr><td><s:property value="name"/></td><td><s:property value="count"/></td><td><s:property value="price"/></td></tr></s:iterator>攔截器
struts2的攔截器主要是攔截action的操作,在action的執行前或后進行一些其它功能的操作
執行過程
當我們發送請求訪問Action時,會被StrutsPrepareAndExecuteFilter攔截
在其doFilter方法內執行了
execute.executeAction(request, response, mapping);
這個代碼執行后
dispatcher.serviceAction(request, response, mapping);
serviceAction方法執行
在這個方法執行過程中會創建Action代理對象
ActionProxy proxy = getContainer().getInstance(ActionProxyFactory.class).createActionProxy(namespace, name, method, extraContext, true, false); 通過proxy去執行了proxy.execute();
在execute方法內return invocation.invoke();
invocation它是ActionInvocation一個對象
在invoke方法內,會去加載我們的配置文件,將配置文件中所有的interceptor得到進行遍歷。
在struts-default.xml文件中定義了默認加載的攔截器棧 defaultStack
在每一個攔截器的interceptor方法內,又調用了DefaultActionInvocation的invoke方法,其實就是遞歸調用。
自定義interceptor
所有的Interceptor都要實現一個接口
在配置文件中聲明Interceptor
我們也可以將多個interceptor封裝成一個stack
<interceptors><interceptor name="interceptor1" class=""></interceptor><interceptor name="interceptor2" class=""></interceptor><interceptor-stack name="myStack"><interceptor-ref name="interceptor1"></interceptor-ref><interceptor-ref name="interceptor2"></interceptor-ref></interceptor-stack> </interceptors>注意:當我們顯示的引入了一個自定義的Interceptor,那么默認的defaultStack就不會在導入,需要手動導入。
?
轉載于:https://www.cnblogs.com/learnjfm/p/7090759.html
總結
以上是生活随笔為你收集整理的struts2值栈,OGNL表达式,interceptor的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 从西刺网获取可用的代理IP
- 下一篇: 联想小新潮5000 完美黑苹果 EFI文