1. 程式人生 > >struts2-動態呼叫方法&接受請求引數

struts2-動態呼叫方法&接受請求引數

動態呼叫方法:在執行時才知道請求的方法是什麼

struts2中動態呼叫方法有如下三種:
1、直接在action中指定方法名

<action name="dosome" class="com.test.testAction" method="dosome">

後面兩種因為struts2-2.5後的版本問題,除了原有的< constant name=”struts.enable.DynamicMethodInvocation” value=”true” />(設定動態方法呼叫常量為true),還要在< action>前配置< global-allowed-methods>doFirst,doSecond(方法名)< /global-allowed-methods>


2、在請求時通過action.name!method(如:some!doFirst)呼叫方法

 <action name="some" class="com.test.testAction" >

3、通過萬用字元的形式,請求時如:some_doFirst呼叫

 <action name="some_*" class="com.test.testAction" method="{1}">

接受請求引數
除了直接在action中加入簡單屬性外,還可通過域驅動和模型驅動來接受請求引數。
域(物件)驅動(demo):
1、Student.java(這裡的System.out.println();是為了分析其引數處理過程)

public class Student {

    private String name;
    private int age;
    public Student(){}
    public Student(String name,int age) {
        this.name = name;
        this.age = age;
    }
    public String getName() {
        System.out.println("getName()");
        return name;
    }
    public
void setName(String name) { System.out.println("setName()"); this.name = name; } public int getAge() { System.out.println("getAge()"); return age; } public void setAge(int age) { System.out.println("setAge()"); this.age = age; } @Override public String toString() { return "Student [name=" + name + ", age=" + age + "]"; } }

2、testAction.java

public class testAction  {
    private Student student;

    public Student getStudent() {
        System.out.println("getStudent()");
        return student;
    }

    public void setStudent(Student student) {
        System.out.println("setStudent()");
        this.student = student;
    }

    public String execute(){    
        System.out.println("doFirst");
        return "success";
    }

}

3、接著在表單頁面和跳轉頁面加如下:

   name : <input name="student.name" type="text"><br>
    age:   <input name="student.age" type="text"><br>

(action物件及其屬性值直接放入值棧,以下通過< s:property >標籤獲取)

student.name = <s:property value="student.name"/>

4、最後執行這個demo,可看到控制檯輸出如下


getStudent()  //第一次呼叫物件
setStudent()  //因為物件為null,所以初始化設定物件
setAge()      //開始執行int的賦值(age)
getStudent()  //要進行name的賦值,先獲取物件
setName()     //執行字串name的賦值
doFirst       //action執行完成
getStudent()  //頁面顯示student.name值,先獲取student物件
getName()     //再獲取name值顯示

模型驅動:
1、testAction實現ModelDriven這個攔截器(struts2預設的攔截器之一)

public class testAction  implements ModelDriven<Student>{
    private Student student;

    public String execute(){    
        System.out.println("doFirst");
        return "success";
    }


    @Override
    public Student getModel() {
        if(student == null){
            student = new Student();
        }
        return student;
    }

}

2、這裡頁面中不用加student物件名字首

name : <input name="name" type="text"><br>
    age:   <input name="age" type="text"><br>
<s:debug></s:debug>
student.name = <s:property value="name"/>

3、執行時,檢視< s:debug>下內容:
這裡寫圖片描述
通過這裡的顯示看出,action中model屬性的值為student物件,而在棧頂的就是這個student物件。這是因為,模型驅動最後會將接受到的模型最後載入到值棧棧頂


接受集合資料(demo):
1、testAction.java

public class testAction  {
    private List<Student> student;

    public List<Student> getStudent() {
        return student;
    }

    public void setStudent(List<Student> student) {
        this.student = student;
    }
    public String execute(){    
        System.out.println("doFirst");
        return "success";
    }
}

2、表單頁面:

name : <input name="student[0].name" type="text"><br>
    age:   <input name="student[0].age" type="text"><br>
      name : <input name="student[1].name" type="text"><br>
    age:   <input name="student[1].age" type="text"><br>

3、跳轉頁面:

<s:debug></s:debug>
student.name = <s:property value="student[1].name"/>

最後對比下servlet和action:
servlet是單例多執行緒的,不能設定屬性
action是多例的,每個請求就新建一個action,每個action都有單獨的ValueSatck