Struts2 如何接收頁面傳過來的參數

action中如何接受頁面傳過來的參數


第一種情況:(同名參數)

例如:
通過頁面要把id=****1 name=tom age=20這三個參數傳給action

action裏面定義三個成員變量id name age,這個三個變量的名字一定要和所傳變量的名字一致.

提供get/set方法
將來頁面把這三個參數傳過來的時候,struts2框架會自動的幫我們把這個三個參數值放action中的三個屬性裏面.(同時還做了類型的轉換)
注意:這個工作其實是由defaultStack這個攔截器棧裏面的攔截器來完成了.

傳值完成之後,我們只要在execute方法中去直接使用就可以了,不需要做其他事情.

第二種情況:(域模型)

在接收到頁面傳值的時候,還可以讓struts2框架直接幫我們把這些接收到的值封裝到一個javabean對象裏面.

action中定義一個User類型的變量user,User類中有三屬性值,id name age,同時User類中還有get/set方法
action中給這個user屬性提供get/set方法
頁面向action傳值的時候,參數的名字要寫成user.id=1 user.name=tom user.age=20

將來接收到這個參數值以後,struts2框架會幫我們去創建一個User對象,並且把所傳參數的三個值封裝到對象的三個屬性裏面,最後把這個封裝好的對象放到action的user屬性中

第三種情況:(模型驅動)

class TestAction implements ModelDriven<User>{
    @Override
    public User getModel() {
        if(user == null){
            user= new User();
        }
        return user;
    }
}

從action向頁面傳值


在action中依然可以像以前在servlet裏面一樣,
使用request、session、application向頁面傳送,除此之外,

action裏面還有倆個獨有的傳值方式:ValueStack ActionContext

ValueStack是一個接口:com.opensymphony.xwork2.util.ValueStack
ActionContext是一個類:com.opensymphony.xwork2.ActionContext

我們可以使用這個倆個類型的對象,從action裏面把值帶到頁面.

ActionContext context = ActionContext.getContext();
 ValueStack vs = context.getValueStack();

我們在頁面中,可以通過一個struts2的標籤來看到action傳到頁面中的值(這裏我們使用標籤庫需要導入兩個jar包):

 `<s:debug/>`  
 頁面引入標籤庫:`<%@taglib uri="/struts-tags" prefix="s" %>`
當前action進行跳轉的時候,struts2框架會自動的把當這個action對象本身分別放到ValueStackActionContext這個倆個對象,
<s:property value="customer.username"/>

然後struts2框架再把這個倆個對象傳給頁面,所以我們在頁面中只要通過這個倆個對象,就可以拿到之前放進去的值.(在頁面的debug標籤中,可以看到struts框架放到這倆個對象裏面的action)

除了struts框架自動的像ValueStack和ActionContext裏面放值以外,
我們還可以手動的向這倆個對象裏面放值.
(在execute方法中拿到這個倆個對象就可以向裏面放值了)

如何拿到ValueStack和ActionContext對象

獲得ActionContext對象:  
 `ActionContext ac = ActionContext.getContext();`

獲得ValueStack對象:      
 `ValueStack vs = ac.getValueStack();`
自己向ac和vs中主動放值

向ActionContext對象中放值:  

 ac.put(String,Object);
 ac.put("hello","world");

向ValueStack對象中放值:  

 User user = new User();
 vs.push(user);

ValueStack的特點(值棧)

  • 把一個對象放到vs裏面之後,我們從這個vs中是拿不到這個對象的,但是我們可以直接拿到這個對象裏面的屬性以及屬性值.

  • 從vs中拿值的時候,是從vs中的property name這一個列來拿的,拿到的是property value這一列的值.(在debug中的vs視圖可以看這些列)

  • 所以如果我們通過vs把一個值傳到頁面,我們不能直接把這個值放到vs裏,因爲這樣拿不到,我們該把這個值放到一個對象的屬性裏面,然後再把這個對象放vs中,這個時候就可以通過vs拿到這個對象的屬性了,也就是我們要傳的值.

  • 每次瀏覽器發送一個新的請求,都會生成一個新的ValueStack對象,上一次的ValueStack對象就沒了,找不到了.(類似之前學習的request對象的特點)

  • 每次創建一個新的ValueStack對象後,會把這個對象放到ActionContext裏面.

ActionContext的特點

  • 向ac裏面放值的時候是通過key-value的形式存放的,key是String類型,value是Object類型,取值的是同樣通過key拿到value.
  • struts框架默認向這個對象裏面存放的對象(數據)很多,包括request、session、application、ValueStack、parameters等
  • 每次請求都會創建一個新的ActionContext對象(每次請求打印出ac的地址值可以看出來)

  • 注意:使用vs和ac傳值的時候,要使用服務器內部跳轉的方式.

客戶端發送一個請求到action,struts2框架會創建倆個對象:
ValueStack對象和ActionContext對象,action執行完進行跳轉的的同時,struts2框架會這個當前執行的a**ction對象分別放到ValueStack對象和ActionContext對象裏面**,在頁面中通過debug標籤可以到放到這倆個對象裏面的action對象.所以最終我們在頁面就可以通過ValueStack對象或者ActionContext對象拿到action裏面的屬性值(get/set方法)


在action中訪問web元素(request session application)

  • 在struts2框架中,這三個對象分別都有倆個類型:原類型 Map類型(這個對象都在ActionContext裏面)

  • 原類型: (指的就是之前在servlet中使用的對象類型)

  HttpServletRequest request
  HttpSession      session
  ServletContext     application
  • Map類型:
  Map<String,Object> request
  Map<String,Object> session
  Map<String,Object> application
  • 在使用的時候,我們可以選擇使用原類型的request或者選擇使用Map類型的request.(session和application也是這樣的情況)
  • 不管是原類型的還是Map類型的對象,都是被struts2框架默認放到了ActionContext對象裏面.(使用debug標籤可以看到)
  • 原類型的和Map類型的關係.
Map<String,Object> session1 = ActionContext.getContext().getSession();

HttpSession session2 = ServletActionContext.getRequest().getSession();
  1. 使用Map類型的對象,可以降低代碼中對 servlet的API的依賴(降耦)
  2. 我們使用原類型大多時候也是存值和取值,而且原類型裏面本身也是封裝了Map對象。所以我們使用Map類型的對象也可以完成存值和取值.
  3. Map類型的request對象裏面的值(k-v),其實就是複製的原類型的request對象裏面的值(k-v),當然原類型的request對象裏面除了k-v類型的鍵值對以外,還有其他的屬性和方法,因爲它畢竟是HttpServletRequest類型的對象.
  4. 所以原類型的request和Map類型的request對象,我們可以理解爲他們裏面的值(k-v)是相通的,相通的意思是:這個對象裏面有什麼值,那個對象裏就也會什麼值.所以我們在action裏面向Map類型的對象中存放一個值(k-v),將來在頁面中同樣是可以使用原類型的request對象那這個值(k-v)取出來的.
    注:session和application的情況也是一樣的道理.

原類型和Map類型相當於下面這個例子:

張三手裏有一個錢包,我們平時都是把錢給張三,張三再把錢放到錢包裏面, 我們拿錢的時候也是通過張三,張三從錢包裏拿出錢,然後再把錢給我們.現在我們不想這麼做,覺得很麻煩,我們直接從張三手裏搶過來這個錢包,我們存錢和拿錢都直接操作這個錢包原類型的request就相當於這裏的張三,Map類型對象就相當於這個錢包


在action中如果拿到Map類型和原類型的對象

獲取Map類型對象

第一種方式:自己在方法中主動獲得

ActionContext ac = ActionContext.getContext();
//獲得Map類型request

  `Map<String,Object> request = (Map<String, Object>) ac.get("request");`
//獲得Map類型session

  `Map<String, Object> session = ac.getSession();`
//獲得Map類型application
Map<String, Object> application = ac.getApplication();

第二種方式:讓struts2框架把Map類型的對象自動的放到action裏(依賴注入)
第一種方式是自己主動拿到這個對象,第二種方式是自己被動接受這個對象.
實現三個接口,分別可以讓struts2框架把Map類型的request、session、application對象通過調用實現的接口中方法傳給我們的action,在action裏面我們只要接收這三個對象就可以了,那到後可以直接使用.三個接口依次爲:
RequestAware,SessionAware,ApplicationAware

例如:
    public class WebActionTest extends ActionSupport implements RequestAware,SessionAware,ApplicationAware{
        private Map<String, Object> request;
        private Map<String, Object> session;
        private Map<String, Object> application;

        @Override
        public String execute() throws Exception {
            //頁面中用原類型的對象去正常值就可以了
            request.put("MyName", "tom");
            session.put("YourName", "zhansan");
            application.put("HerName", "lily");
            return SUCCESS;
        }
        public void setRequest(Map<String, Object> request) {
            this.request = request;
        }

        public void setSession(Map<String, Object> session) {
            this.session = session;
        }

        public void setApplication(Map<String, Object> application) {
            this.application = application;
        }
    }

獲取原類型對象
第一種方式:自己主動獲得

獲得原類型request對象
HttpServletRequest req = ServletActionContext.getRequest();
獲得原類型response對象
HttpServletResponse res = ServletActionContext.getResponse();
獲得原類型session對象
HttpSession sess = req.getSession();
獲得原類型application對象
ServletContext app1 = sess.getServletContext();
或者
ServletContext app2 = ServletActionContext.getServletContext();

第二種方式:自己被動接收
struts2框架中提供了一個接口,可以用來獲得原類型的request對象,
因爲通過原類型的request對象就可以獲得原類型的session對象和原
類型的application對象

實現接口:ServletRequestAware,然後struts2框架會通過action所實現的抽  象方法,把原類型的request對象自動放到action裏面.  

類似的還有一接口:ServletResponseAware,和上面的效果、用法是一樣的。

頁面中獲得action傳過來的值

在struts2框架所提供的頁面取值方式中,需要使用到倆個東西:struts2框架的標籤、OGNL表達式
注意:同時我們也可以使用jsp內置對象取值已經使用jstl標籤+EL表達式取值.

struts2中可以使用的取值方式:

  • jsp內置對象取值
  • jstl標籤+EL表達式取值
  • struts2標籤+OGNL表達式

注意:OGNL表達式只能寫在struts2的標籤屬性中,在這裏面我們先使用一下struts2的這樣一個標籤:,這個標籤的作用就是向頁面輸出值.
例如:<s:property value=" OGNL表達式寫在這 "/>

從ValueStack和ActionContext中取值

從ValueStack中取值.
//注意這個value屬性中的值name,其實就是ongl表達式
//這個表示從valueStack中取一個名字叫做name的property值

<s:property value="name"/>
<s:property value="user"/>
<s:property value="user.id"/>
<s:property value="user.name"/>

注意:從ValueStack中取值的時候,如果Valuestack裏面有倆個名字相同的值,我們只能取到最上面的值(從debug標籤中看vs中最上面的值)(其實取值的方式特殊處理一下還是可以取到下面的屬性值的)

從ActionContext中取值.

要使用ognl表達式通過AC中的key來拿相對於的value值。取值的時候需要加上一個符號:#  

 <s:property value="#action.name"/><br>
 <s:property value="#msg"/><br>
 <s:property value="#user"/><br>
 <s:property value="#user.id"/><br>
 <s:property value="#user.name"/><br>
 <s:property value="#user.age"/><br>
ActionContext中的parameters、attr、request、session、application等key值.(這些都是AC中的key)

parameters對應的值中存放的是客戶端所傳過來的參數.

//接收客戶端傳來的名字爲name的參數值   
<s:property value="#parameters.name"/><br>

//獲得request中的值  
<s:property value="#request.MyName"/><br>
//獲得session中的值  
<s:property value="#session.MyName"/><br>  
//獲得application中的值  
<s:property value="#application.MyName"/><br>  

//默認依次從request、session、appliction中取值,取到了就直接輸出,取不到就算了.  
<s:property value="#attr.MyName"/><br>

還可以使用以前的方式從request、session、application中取值.

注意:如果我們用request通過key去取值的時候,會先在request裏面,request裏面找不到到ValueStack裏面找因爲**ValueStack默認也被放在request裏面.但是**session和application沒有像request的這樣的特點.

使用jsp腳本代碼取值

<%=request.getAttribute("name") %><br>
<%=session.getAttribute("name") %><br>
<%=application.getAttribute("name") %><br>

使用EL表達式取值:

 ${requestScope.MyName }<br>
 ${requestScope.name }  <br>
 ${sessionScope.MyName }  <br>
 ${applicationScope.MyName }  <br>
 ${MyName }  <br>
 ${name }  <br>
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章