1.普通的傳值方式html
UserActionForCommonParam類
java
Action類接收三個參數,分別是id,username,content.apache
- package com.struts.action;
-
- public class UserActionForCommonParam {
- private int id;
- private String username;
- private String content;
-
- public int getId() {
- return id;
- }
-
- public void setId(int id) {
- this.id = id;
- }
-
- public String getUsername() {
- return username;
- }
-
- public void setUsername(String username) {
- this.username = username;
- }
-
- public String getContent() {
- return content;
- }
-
- public void setContent(String content) {
- this.content = content;
- }
-
- // 從前臺頁面接收到參數後會在這個方法裏打印
- public String addUser() {
- System.out.println("ID: " + this.getId());
- System.out.println("Username: " + this.getUsername());
- System.out.println("Content: " + this.getContent());
- return "success";
- }
- }
對應的struts.xmlsession
- <?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.enable.DynamicMethodInvocation" value="true"/>
- <constant name="struts.devMode" value="true"/>
- <package name="default" namespace="/" extends="struts-default">
- <action name="UserActionForCommonParam" class="com.struts.action.UserActionForCommonParam" method="addUser">
- <result name="success">/UserPage.jsp</result>
- </action>
- </package>
- </struts>
前臺頁面UserPage.jsp數據結構
- <%@ page contentType="text/html;charset=UTF-8" language="java" %>
- <%@ taglib prefix="s" uri="/struts-tags" %>
- <html>
- <head>
- <title>UserPage</title>
- </head>
- <body>
- <%--下面的Table用於提交參數(id,username,content)--%>
- <form action="UserActionForCommonParam" method="POST">
- <table border="1">
- <tr>
- <td>ID:</td>
- <td><input type="text" name="id"/></td>
- </tr>
- <tr>
- <td>Username:</td>
- <td><input type="text" name="username"/></td>
- </tr>
- <tr>
- <td>Content:</td>
- <td><input type="text" name="content"/></td>
- </tr>
- <tr>
- <td colspan="2" align="center">
- <input type="submit" value="提交"/>
- </td>
- </tr>
- </table>
- </form>
- <br/>
- <%--下面的Table用於顯示傳遞回來id,username,content--%>
- <table border="1">
- <tr>
- <td>ID: </td>
- <td><input type="text" value="${id}"/></td>
- </tr>
- <tr>
- <td>Username: </td>
- <td><input type="text" value="${username}"/></td>
- </tr>
- <tr>
- <td>Content: </td>
- <td><input type="text" value="${content}"/></td>
- </tr>
- </table>
- <%--用於查看ValueStack中的傳遞的值--%>
- <s:debug/>
- </body>
- </html>
在實踐後會發現,若是遇到參數很是多的狀況,那麼就須要在Action類中寫很是多的屬性以及對應的get/set方法.因此這種方式不太可取.解決問題的方法必然是封裝一個JavaBean.這就用到了Strut2的第二種傳值方式--DomainModelapp
2.DomainModel傳值框架
首先要建立一個存儲的JavaBeanjsp
User類ide
把id,username,content封裝的到一個User類當中.
函數
- package com.struts.model;
-
- public class User {
- private int id;
- private String username;
- private String content;
-
- public int getId() {
- return id;
- }
-
- public void setId(int id) {
- this.id = id;
- }
-
- public String getUsername() {
- return username;
- }
-
- public void setUsername(String username) {
- this.username = username;
- }
-
- public String getContent() {
- return content;
- }
-
- public void setContent(String content) {
- this.content = content;
- }
- }
UserActionForDomainModel類
- package com.struts.action;
-
- import com.opensymphony.xwork2.ActionSupport;
- import com.struts.model.User;
-
- public class UserActionForDomainModel extends ActionSupport{
- private User user;
-
- public User getUser() {
- return user;
- }
-
- public void setUser(User user) {
- this.user = user;
- }
-
- public String addUser() {
- System.out.println("ID: " + user.getId());
- System.out.println("Username: " + user.getUsername());
- System.out.println("Content: " + user.getContent());
- return "success";
- }
- }
對應的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.enable.DynamicMethodInvocation" value="true"/>
- <constant name="struts.devMode" value="true"/>
- <package name="default" namespace="/" extends="struts-default">
- <action name="userForDomainModel" class="com.struts.action.UserActionForDomainModel" method="addUser">
- <result name="success">/UserPage.jsp</result>
- </action>
- </package>
- </struts>
前臺頁面UserPage.jsp
- <%@ page contentType="text/html;charset=UTF-8" language="java" %>
- <%@ taglib prefix="s" uri="/struts-tags" %>
- <html>
- <head>
- <title>UserPage</title>
- </head>
- <body>
- <%--要特別注意的是DomainModel的傳值方式必需要使用對象.參數方式進行賦值以及取值--%>
- <form action="userForDomainModel" method="POST">
- <table border="1">
- <tr>
- <td>ID:</td>
- <td><input type="text" name="user.id"/></td>
- </tr>
- <tr>
- <td>Username:</td>
- <td><input type="text" name="user.username"/></td>
- </tr>
- <tr>
- <td>Content:</td>
- <td><input type="text" name="user.content"/></td>
- </tr>
- <tr>
- <td colspan="2" align="center">
- <input type="submit" value="提交"/>
- </td>
- </tr>
- </table>
- </form>
- <br/>
- <%--下面的Table用於顯示傳遞回來id,username,content--%>
- <table border="1">
- <tr>
- <td>ID: </td>
- <td><input type="text" value="${user.id}"/></td>
- </tr>
- <tr>
- <td>Username: </td>
- <td><input type="text" value="${user.username}"/></td>
- </tr>
- <tr>
- <td>Content: </td>
- <td><input type="text" value="${user.content}"/></td>
- </tr>
- </table>
- <%--用於查看ValueStack中的傳遞的值--%>
- <s:debug/>
- </body>
- </html>
實際上User類不須要顯式的實例化,struts會自動幫你實例化,但前提條件是,傳值時須要使用對象.參數名的方式進行傳遞.
除了這種傳值方式外,struts2還提供另一種傳值方式.
3.ModelDriven傳值
依然要建立User的JavaBean
User類
- package com.struts.model;
-
- public class User {
- private int id;
- private String username;
- private String content;
-
- public int getId() {
- return id;
- }
-
- public void setId(int id) {
- this.id = id;
- }
-
- public String getUsername() {
- return username;
- }
-
- public void setUsername(String username) {
- this.username = username;
- }
-
- public String getContent() {
- return content;
- }
-
- public void setContent(String content) {
- this.content = content;
- }
- }
UserActionForModelDriven類
- package com.struts.action;
-
- import com.opensymphony.xwork2.ModelDriven;
- import com.struts.model.User;
-
- public class UserActionForModelDriven implements ModelDriven<User>{
- private User user;
-
- public String addUser() {
- System.out.println("ID: " + user.getId());
- System.out.println("Username: " + user.getUsername());
- System.out.println("Content: " + user.getContent());
- return "success";
- }
-
- @Override
- public User getModel() {
- if (user == null) {
- user = new User();
- }
- return user;
- }
- }
這種方式能夠不用在Action類中編寫對應的get/set方法,可是須要實例化User類.
前臺UserPage.jsp
- <%@ page contentType="text/html;charset=UTF-8" language="java" %>
- <%@ taglib prefix="s" uri="/struts-tags" %>
- <html>
- <head>
- <title>UserPage</title>
- </head>
- <body>
- <form action="userForModelDriven" method="POST">
- <table border="1">
- <tr>
- <td>ID:</td>
- <td><input type="text" name="id"/></td>
- </tr>
- <tr>
- <td>Username:</td>
- <td><input type="text" name="username"/></td>
- </tr>
- <tr>
- <td>Content:</td>
- <td><input type="text" name="content"/></td>
- </tr>
- <tr>
- <td colspan="2" align="center">
- <input type="submit" value="提交"/>
- </td>
- </tr>
- </table>
- </form>
- <br/>
- <%--下面的Table用於顯示傳遞回來id,username,content--%>
- <table border="1">
- <tr><span id="transmark"></span>
- <td>ID: </td>
- <td><input type="text" value="${id}"/></td>
- </tr>
- <tr>
- <td>Username: </td>
- <td><input type="text" value="${username}"/></td>
- </tr>
- <tr>
- <td>Content: </td>
- <td><input type="text" value="${content}"/></td>
- </tr>
- </table>
- <%--用於查看ValueStack中的傳遞的值--%>
- <s:debug/>
- </body>
- </html>
頁面仍是和普通傳值同樣.
能夠去ValueStack當中觀察參數的存儲,更透徹的理解Struts2的參數傳遞. : <s:debug/>
1.什麼是ValueStack
對於每個action的調用,Struts在執行相應的動做方法以前會先建立一個名爲ValueStack的對象。Value Stack用來保存該動做對象或者對象。因爲最終在執行Action類相應的action方法以前,攔截器須要先訪問ValueStack。視圖也須要訪問ValueStack。Struts框架將其保存在一個名爲struts.valueStack的請求屬性中。
2.獲取valueStack的三種方法:
ValueStack v1 = ActionContext.getContext().getValueStack()
打印其HashCode碼如出一轍。
說明:
一、 值是同樣的,說明只有一個對象
二、 由於有一種是從request域中獲取的,因此是一次請求
3.ValueStack的內容
valueStack分爲對象棧(Object Stack)和Map棧(Context Map).
Struts將把動做和相關對象壓入Object Stack,而把各類各樣的映射關係壓入Context Map。
一般說的ValueStack就是指Object Stack,它是一個真正數據結構意義的棧。Object Stack也經常被稱爲root(實際上是一個ArrayList)。Context Map咱們通常稱其爲context(是一個HashMap)它是整個OGNL其中包括了root
4.OGNL中的兩種對象
OGNL中包含兩種對象,即_root和_value.
_value即:request, session, application, parameters, attr等命名對象,但這些命名對象都不是根。
_root即:當前請求的Action實例等
「根」對象和普通命令對象的區別在於:
「根」對象(root) 對象棧: 其實是 CompoundRoot 類型, 是一個使用 ArrayList 定義的棧. 裏邊保存各類和當前 Action 實例相關的對象(若是這個Action實例包括域對象的話域對象會進root).是一個數據結構意義的棧.
1)訪問Context Map裏的對象須要在對象名以前添加 #
2)訪問Object Stack對象的屬性時,能夠省略#而直接經過屬性名來搜索
說明:
從上圖中也能夠看出valueStack總共分爲兩個部分:
對象棧:root (CompoundRoot類)
Map棧:_values和_root (OgnlContext 類)
5.Struts會把當前訪問的Action實例壓入值棧棧定
壓入時間點爲:
因爲Struts2最後終將調用Action類中的action方法。但在調用此方法以前:
*先建立一個StrutsActionProxy (ActionProxy默認實現的子類)
*在建立StrutsActionProxy以後,對其進行初始化,把Action對象壓入值棧
在調用該方法前該Action被壓入棧頂,若是在初始化的過程當中,在Action的構造函數中又初始化了其餘類,這這個類也會被壓入值棧。因此最後棧頂的元素會是這個新初始化的類。
6.ValueStack中對象的存取
Object Stack 的存放: push 或者 add:
將一個對象放入Object Stack的棧頂:
- 1
ActionContext.getContext().getValueStack().push(object)
- 2
Object Stack的提取: peek() 或 pop()
peek()取得的是棧頂元素:
- 1
Object object = ActionContext.getContext().getValueStack().peek();
Object Stack的元素的彈出:pop:
- 1
Object object = ActionContext.getContext().getValueStack().pop();
7.動態修改ValueStack中對象的屬性
說明:
能夠利用valueStack.setParameter方法改變對象棧中對象的屬性的值。至於匹配哪一個。則依次從對象棧的棧頂向下搜索,找到匹配的就修改