分享知識-快樂自己:Struts2(動態方法、動態結果、萬用字元、方法內部跳轉、action跳轉、OGNL 的使用及注意事項)
這裡主要以案例演示:涵蓋以下知識點
1、動態方法呼叫:使用關鍵 符號 ! 進行操作 例如:/名稱空間 ! 方法名
2、動態結果集:就是說,通過後臺返回的結果 ${} 獲取,重定向到符合預期的頁面。
3、萬能萬用字元:*_* :第一個 * 為 類名、第二個 * 為方法名;{1}是第一個 *
4、內部方法的呼叫:就是說 Action 類中的 A() 呼叫 B() A方法返回B()的結果集
5、跳轉Action:就是說訪問一個方法,根據返回的結果匹配 result中的 name 值 跳入下一個action (result type=chain)
6、OGNL:(不過多講述相關概念,這裡以程式碼為核心)
值棧的內部結構分為兩部分:
第一部分:root,結構是 list 集合一般操作的都是 root 裡面的資料
第二部分:context,結構為 Map 集合
使用經歷:
root 單列集合下的 前臺獲取的時候不需要寫 #
context 雙列集合 前臺獲取的時候需要寫 #
1、往 單列集合中推送 集合型別的資料時,不能觸碰到集合的引用名稱。
將泛型集合推送到值棧中:
使用 <s:debug/> 標籤檢視 值棧的資訊:
2、值棧的訪問順序為 從上往下 定址。如有同名的屬性名,則定址離值棧頂端最近的
核心程式碼擷取:推送到root 也就是單列集合下
使用 <s:debug/> 標籤檢視 值棧的資訊:
3、在我們實現 Action 介面 或 繼承ActionSupport 的類中的成員屬性都是放在 root 單列集合下的
4、往值棧 context 推送 key那一列會有我們指定的引用名稱(需要獲取的時候需要 #)
以上為可能會遇到的問題。
完整Demo展示:
案例結構:
為演示萬用字元需要方法名與jsp名稱一致,add.jsp 與 list.jsp 建立在 CoordinAction檔案下
POM:
<properties> <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding> <maven.compiler.source>1.7</maven.compiler.source> <maven.compiler.target>1.7</maven.compiler.target> </properties> <dependencies> <!--測試JAR--> <dependency> <groupId>junit</groupId> <artifactId>junit</artifactId> <version>4.11</version> </dependency> <!--javaee.jar包是支援javaweb程式設計的基礎jar包,跟javase程式設計需要jre一樣!--> <dependency> <groupId>javaee</groupId> <artifactId>javaee-api</artifactId> <version>5</version> </dependency> <!--Struts2-core核心--> <dependency> <groupId>org.apache.struts</groupId> <artifactId>struts2-core</artifactId> <version>2.3.4.1</version> </dependency> <!--xwork 的核心包,最主要的功能是 支援了過濾器(interceptor)。--> <dependency> <groupId>org.apache.struts.xwork</groupId> <artifactId>xwork-core</artifactId> <version>2.3.4.1</version> </dependency> </dependencies>View Code
CoordinAction:
package com.gdbd.action; import com.opensymphony.xwork2.ActionContext; import com.opensymphony.xwork2.ActionSupport; import java.util.Map; /** * @author asus */ public class CoordinAction extends ActionSupport { private String message; private String mess; ...省略 Get Set /*** * 動態方法的呼叫 * @return */ public String list() { this.setMessage("通過呼叫 add 方法拿到返回的name定址,再次排程 Action 中的list"); return "list"; } public String add() { this.setMessage("動態方法排程!!!!"); return "add"; } public String get() { Map<String, Object> session = ActionContext.getContext().getSession(); if (this.message != null) { session.put("message", "動態結果集呼叫成功!!!"); this.setMess("demo2"); } else { session.put("message", "動態結果集呼叫失敗!!!"); this.setMess("error"); } return "get"; } /*** * 內部方法的呼叫 * @return */ public String demo1() { Map request = (Map) ActionContext.getContext().get("request"); request.put("message", "測試資料Action內部排程!!!"); return "demo2"; } public String demo2() { return demo1(); } }View Code
OgnlAction:
package com.gdbd.action; import com.gdbd.bean.UserInfo; import com.opensymphony.xwork2.ActionContext; import com.opensymphony.xwork2.ActionSupport; import com.opensymphony.xwork2.util.ValueStack; import java.util.List; import java.util.ArrayList; /** * @author asus */ public class OgnlAction extends ActionSupport { private List<UserInfo> List; ...省略 Get Set /*** * OGNL:儲存到單列集合 */ public String demo1() { ActionContext context = ActionContext.getContext(); //獲取值棧 ValueStack valueStack = context.getValueStack(); //偽造資料 UserInfo userInfo=new UserInfo(); userInfo.setUserName("MLQ"); userInfo.setUserPwd("MLQ"); UserInfo userInfo1=new UserInfo(); userInfo1.setUserName("FKX"); userInfo1.setUserPwd("FKX"); List<UserInfo> infoList=new ArrayList<UserInfo>(); infoList.add(userInfo); infoList.add(userInfo1); /*** * 將資料推送到單列集合中 * 缺點:對集合型別進行操作的時候,沒有辦法觸碰到集合的引用名稱 * 例如:新增一個 泛型List<UserInfo> 集合 沒有 */ valueStack.push(userInfo); valueStack.push(userInfo1); valueStack.push(infoList); return "demo1"; } /*** * OGNL:儲存到雙列集合 */ public String demo2() { ActionContext context = ActionContext.getContext(); //獲取值棧 ValueStack valueStack = context.getValueStack(); //偽造資料 UserInfo userInfo=new UserInfo(); userInfo.setUserName("MLQ"); userInfo.setUserPwd("MLQ"); UserInfo userInfo1=new UserInfo(); userInfo1.setUserName("FKX"); userInfo1.setUserPwd("FKX"); List<UserInfo> infoList=new ArrayList<UserInfo>(); infoList.add(userInfo); infoList.add(userInfo1); /*** * 將資料推送到雙列集合中 */ //valueStack.push(infoList);將泛型集合推送到值棧中,沒有引用地址 this.List=infoList; valueStack.getContext().put("infoList",infoList); return "demo1"; } }View Code
UserInfo:
package com.gdbd.bean; import java.io.Serializable; /** * user 實體類 * @author asus */ public class UserInfo implements Serializable { private String userName; private String userPwd; ...省略 Get Set }View Code
struts.xml:
<?xml version="1.0" encoding="UTF-8" ?> <!DOCTYPE struts PUBLIC "-//Apache Software Foundation//DTD Struts Configuration 2.0//EN" "http://struts.apache.org/dtds/struts-2.0.dtd"> <struts> <!-- 是否開啟動態方法呼叫 --> <constant name="struts.enable.DynamicMethodInvocation" value="true"/> <!--更改 Struts.xml的 節點不需要重啟--> <constant name="struts.devMode" value="true"></constant> <!--動態--> <package name="default" namespace="/" extends="struts-default"> <!--動態方法排程 使用( ! ) --> <action name="demo" class="com.gdbd.action.CoordinAction"> <result name="add">/error.jsp</result> </action> <!-- *_*: 第一個 * 為 類名 第二個 * 為 方法名 --> <!--萬能萬用字元--> <action name="*_*" class="com.gdbd.action.{1}" method="{2}"> <result name="{2}">{1}/{2}.jsp</result> </action> </package> <!--內部方法的呼叫--> <package name="demo" namespace="/demo1" extends="struts-default"> <!-- action 內部方法排程 --> <action name="mo" class="com.gdbd.action.CoordinAction" method="demo1"> <result name="demo2">/demo2.jsp</result> </action> <!-- action 內部方法排程 重定向頁面 --> <action name="mo1" class="com.gdbd.action.CoordinAction" method="demo1"> <result name="demo2" type="redirect">/demo2.jsp</result> </action> </package> <!--排程 action 中的方法,在根據結果集再次跳轉到 action 方法 --> <package name="demo2" namespace="/demo2" extends="struts-default"> <action name="listdemo" class="com.gdbd.action.CoordinAction" method="list"> <result name="list">/demo2.jsp</result> </action> <action name="mo" class="com.gdbd.action.CoordinAction" method="add"> <result name="add" type="chain"> <!--預設是轉發--> <param name="actionName">listdemo</param> <param name="namespace">/demo2</param> </result> </action> </package> <!--動態結果:重定向頁面(轉發無效)--> <package name="demo3" namespace="/demo3" extends="struts-default"> <action name="mo" class="com.gdbd.action.CoordinAction" method="get"> <result name="get" type="redirect">${mess}</result> </action> <action name="demo2"> <result>/demo2.jsp</result> </action> <action name="error"> <result>/error.jsp</result> </action> </package> <!--OGNL 測試--> <package name="demo4" namespace="/demo4" extends="struts-default"> <!--推送到單列集合中--> <action name="mo" class="com.gdbd.action.OgnlAction" method="demo1"> <result name="demo1">/demo1.jsp</result> </action> <!--推送到雙列集合中--> <action name="mo1" class="com.gdbd.action.OgnlAction" method="demo2"> <result name="demo1">/demo1.jsp</result> </action> </package> </struts>View Code
add.jsp:
<%-- Created by IntelliJ IDEA. User: asus Date: 2018/11/17 Time: 9:33 To change this template use File | Settings | File Templates. --%> <%@ page contentType="text/html;charset=UTF-8" language="java" %> <html> <head> <title>Title</title> </head> <body> <h1>add==========</h1> </body> </html>View Code
list.jsp:
<%-- Created by IntelliJ IDEA. User: asus Date: 2018/11/17 Time: 9:33 To change this template use File | Settings | File Templates. --%> <%@ page contentType="text/html;charset=UTF-8" language="java" %> <html> <head> <title>Title</title> </head> <body> <h1>list==========</h1> </body> </html>View Code
demo1.jsp:
<%@ taglib prefix="s" uri="/struts-tags" %> <%-- Created by IntelliJ IDEA. User: asus Date: 2018/11/17 Time: 9:33 To change this template use File | Settings | File Templates. --%> <%@ page contentType="text/html;charset=UTF-8" language="java" isELIgnored="false" %> <html> <head> <title>Title</title> </head> <body> <fieldset> <legend>OGNL:獲取的結果(值棧單列集合)</legend> 姓名為:<s:property value="userName"></s:property> <br/> 密碼為:<s:property value="userPwd"></s:property> </fieldset> <br/><br/> <fieldset> <legend>OGNL:獲取的結果(值棧Root 單列集合)</legend> 姓名為:<s:property value="List[0].userName"></s:property> <br/> 密碼為:<s:property value="List[1].userPwd"></s:property> </fieldset> <br/><br/> <fieldset> <legend>OGNL:獲取的結果(值棧雙列集合)</legend> 姓名為:<s:property value="#infoList[0].userName"></s:property> <br/> 密碼為:<s:property value="#infoList[1].userPwd"></s:property> </fieldset> <br/><br/> <fieldset> <legend>OGNL:獲取的結果(值棧雙列集合,便利讀取)</legend> <s:iterator value="infoList" id="info"> <s:property value="#info.userName"/> </s:iterator> </fieldset> <br/><br/> <s:debug/> </body> </html>View Code
demo2.jsp:
<%-- Created by IntelliJ IDEA. User: asus Date: 2018/11/17 Time: 9:33 To change this template use File | Settings | File Templates. --%> <%@ page contentType="text/html;charset=UTF-8" language="java" isELIgnored="false" %> <html> <head> <title>Title</title> </head> <body> <h1>${message}</h1> </body> </html>View Code
error.jsp:
<%-- Created by IntelliJ IDEA. User: asus Date: 2018/11/17 Time: 9:33 To change this template use File | Settings | File Templates. --%> <%@ page contentType="text/html;charset=UTF-8" language="java" isELIgnored="false" %> <html> <head> <title>Title</title> </head> <body> <h1>${message}</h1> </body> </html>View Code
index.jsp:
<%-- Created by IntelliJ IDEA. User: asus Date: 2018/11/17 Time: 10:34 To change this template use File | Settings | File Templates. --%> <%@ page contentType="text/html;charset=UTF-8" language="java" %> <html> <head> <title>Title</title> </head> <body> <fieldset> <legend>動態方法排程</legend> <a href="/demo!add">動態方法排程</a> </fieldset> <br/><br/> <fieldset> <legend>萬能萬用字元</legend> <a href="/CoordinAction_list">萬能萬用字元</a> <a href="/CoordinAction_add">萬能萬用字元</a> </fieldset> <br/><br/> <fieldset> <legend>內部方法排程返回的資訊</legend> <a href="/demo1/mo">內部方法排程返回的資訊:預設是轉發</a> <a href="/demo1/mo1">內部方法排程返回的資訊:使用重定向</a> </fieldset> <br/><br/> <fieldset> <legend>排程 action 中的方法,在根據結果集再次跳轉到 action 方法</legend> <a href="/demo2/mo">跳轉 add 方法 根據結果再次 指向list:轉發操作</a> <a href="#">###</a> </fieldset> <br/><br/> <fieldset> <legend>動態結果排程</legend> <a href="/demo3/mo?message=123">動態結果排程:重定向</a> <a href="#">###</a> </fieldset> <br/><br/> <fieldset> <legend>OGNL</legend> <a href="/demo4/mo">OGNL:儲存到值棧的單列集合</a> <a href="/demo4/mo1">OGNL:儲存到值棧的單列集合</a> </fieldset> <br/><br/> </body> </html>View Code
web.xml:
<!DOCTYPE web-app PUBLIC "-//Sun Microsystems, Inc.//DTD Web Application 2.3//EN" "http://java.sun.com/dtd/web-app_2_3.dtd" > <web-app> <display-name>Archetype Created Web Application</display-name> <!--核心過濾器--> <filter> <filter-name>struts2</filter-name> <filter-class>org.apache.struts2.dispatcher.ng.filter.StrutsPrepareAndExecuteFilter</filter-class> </filter> <filter-mapping> <filter-name>struts2</filter-name> <url-pattern>/*</url-pattern> </filter-mapping> </web-app>View Code