动态调用方法:在运行时才知道请求的方法是什么
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