1. 程式人生 > >Struts2框架之ActionContext

Struts2框架之ActionContext

context map的概念介紹:

每次請求時都會建立一個context map的物件, value stack和context map的資料是可以相互轉換的

key value 說明
value stack List集合 以棧的方式來儲存
request Map<String,Object>結構 以鍵值對的方式儲存請求範圍的資料
session Map<String,Object>結構 以鍵值對的方式儲存會話範圍的資料
application Map<String,Object>結構 以鍵值對的方式儲存應用範圍的資料
action Object型別 當前訪問的動作類物件
parameters Map<String,Object>結構 儲存請求的引數
attr Map<String,Object>結構 根據key從page/request/session/application範圍依次查詢屬性的值

我們存取的資料採用兩種結構, 一種是valueStack(值棧), 採用set<map>的形式, 另一種是contextMap(map)的形式

在contextMap中存取資料:

在請求範圍內存取資料:

success.jsp:

<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<%@ taglib uri="/struts-tags" prefix="s"%>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
</head>
<body>
    <!-- 需要使用#key的方式來取資料
     -->
    <s:property value="#name"/>
    <s:debug></s:debug>
</body>
</html>

動作類程式碼:

package com.rl.action;

import org.apache.struts2.ServletActionContext;

import com.opensymphony.xwork2.ActionContext;
import com.opensymphony.xwork2.ActionSupport;

public class PersonAction extends ActionSupport {
    
    private String username;

    public String getUsername() {
        return username;
    }

    public void setUsername(String username) {
        this.username = username;
    }

    
    @Override
    public String execute() throws Exception {
        System.out.println(username);
        //獲取動作類的上下文ActionContext(包含了contextMap和valueStack)
        ActionContext context = ServletActionContext.getContext();
        //在contextMap中儲存資料, 預設相當於儲存在request(並非儲存在request中, 但是生命週期跟request一樣, 就是一次請求)
        context.put("name", "zhangsan");
        return super.execute();
    }
}

struts.xml的配置我就不貼上來了.

debug展示:

從圖中可以看出資料並非儲存在request中, 但是生命週期跟request一樣(在一次請求的範圍內)

在會話範圍內存取資料:

動作類部分程式碼:

@Override
    public String execute() throws Exception {
        System.out.println(username);
        //獲取動作類的上下文ActionContext(包含了contextMap和valueStack)
        ActionContext context = ServletActionContext.getContext();
        //在contextMap中儲存資料, 預設相當於儲存在request(並非儲存在request中, 但是生命週期跟request一樣, 就是一次請求)
        context.put("name", "zhangsan");
        
        //獲取session
        Map<String, Object> session = context.getSession();
        //將資料儲存在session中
        session.put("user", "李四");
        return super.execute();
    }

success.jsp部分程式碼:

<body>
    <!-- 需要使用#key的方式來取資料
     -->
     <!-- 在請求的範圍內 -->
    <s:property value="#name"/>
    <!-- 在會話的範圍內 -->
    <s:property value="#session.user"/>
    <s:debug></s:debug>
</body>

debug展示:

訪問結果:

從圖中可以看出, 跨在同一個session內是可以拿到到"user"的值, 但是拿不到"name"的值

在application範圍內儲存資料:

動作類部分程式碼:

//獲取application
        Map<String, Object> application = context.getApplication();
        //將資料儲存在application中
        application.put("pv", "12345");

success.jsp部分程式碼:

<!-- 在應用範圍內 -->
    <s:property value="#application.pv"/><br>

只有伺服器不關閉, application範圍內都能去到該資料.

在valueStack(值棧)中存取資料:

請求的引數會儲存在值棧中, 也可以手動儲存

自動儲存:

動作類部分程式碼:

public String execute() throws Exception {
        System.out.println(username);
        return super.execute();
    }

success.jsp部分程式碼:

<s:debug></s:debug>
    
    <hr>
    <!-- 在值棧中取值直接使用變數名即可 -->
    <s:property value="username"/>

debug展示:

從上圖可以看出, 此時的"username"的值儲存於valueStack(值棧)中

新建一個model類Person:

package com.rl.model;

public class Person {

    private int personId;
    
    private String personName;
    
    private int gender;
    
    public Person() {
        
    }

    public Person(int personId, String personName, int gender) {
        super();
        this.personId = personId;
        this.personName = personName;
        this.gender = gender;
    }

    public int getPersonId() {
        return personId;
    }

    public void setPersonId(int personId) {
        this.personId = personId;
    }

    public String getPersonName() {
        return personName;
    }

    public void setPersonName(String personName) {
        this.personName = personName;
    }

    public int getGender() {
        return gender;
    }

    public void setGender(int gender) {
        this.gender = gender;
    }
}

success.jsp部分程式碼:

<s:property value="personId"/><br>
    <s:property value="personName"/><br>
    <s:property value="gender"/><br>
    <hr><br>第二種從valueStack中取值的方法<br>
    <s:property value="person.personId"/><br>
    <s:property value="person.personName"/><br>
    <s:property value="person.gender"/><br>

debug展示:

訪問結果:

手動儲存(一般都是手動放在contextMap中):

動作類部分程式碼:

public String execute() throws Exception {
        
        ActionContext context = ServletActionContext.getContext();
        Person person1 = new Person(2, "王五", 2);
        //獲取值棧
        ValueStack stack = context.getValueStack();
        //手動壓棧
        stack.push(person1);
        return super.execute();
    }

success.jsp部分程式碼:

<s:property value="personId"/><br>
    <s:property value="personName"/><br>
    <s:property value="gender"/><br>
    <hr>
    <!-- 取棧中的值 -->
    <s:property value="[1].personId"/><br>
    <s:property value="[1].personName"/><br>
    <s:property value="[1].gender"/><br>
    <hr>
    <s:property value="person.personId"/><br>
    <s:property value="person.personName"/><br>
    <s:property value="person.gender"/><br>

debug展示:

訪問結果: