(1)Struts1.x 对于客户端的请求参数,如果<action>上配有name属性,且对应有formbean,那么struts1.x会按照请求参数名与formbean的成员变量名匹配,相同的则调用其setter方法,为其赋值,没有匹配的,则可以通过request.getParameter("paramName")取得参数值。注意,填充formbean时,struts是按照formbean的成员变量名与请求参数名匹配的,而不是按照setter方法匹配的,这一点,我认为Struts1.x做的不是很好。
如:http://localhost:8080/Struts_01/login.do?userName=itcast&userPass=4444&birth=1978-9-23&score=100
LoginForm.java
public class LoginForm extends ActionForm{
private String name;
private String userPass;
public void setUserName(String userName){
System.out.println("setter userName is invoked...");//不会被调用
this.name = userName;
}
public void setUserPass(String userPass){
System.out.println("setter userPass is invoked...");//会被调用
this.userPass= userPass;
}
}
由此可以证明Struts1.x是匹配请求参数名来填充formBean的,而不是匹配请求参数名对应的setter方法
另外注意:ActionForm中的Date必须是java.sql.Date,不能是java.util.Date;而pojo类都可以。
(2)Struts2 是根据匹配请求参数名的setter方法,如userName=xxx,struts2是在Action中寻找setUserName方法并调用,与Action中是否有userName成员变量无关。
Struts2提供了两种方法处理客户端请求:
- 采用基本类型接收请求参数(get/post).如:http://localhost:8080/Struts2_03/request/regist.action?userName=itstar&userPass=huahua
- 采用复合类型接收请求参数(get/post).如:http://localhost:8080/Struts2_03/request/regist.action?userName=itstar&product.productId=11 Struts2首先通过反射技术调用Product的默认构造器创建product对象,然后再通过反射技术调用product中与请求参数想匹配的setter方法来获取请求参数值。
解决所有疑惑的例子:
Product.java
RegistProductAction.java
struts-request.xml
registProduct.jsp
showRequestParam.jsp
浏览器上输入: http://localhost:8080/Struts2_03/page/registProduct.jsp
点击regist按钮
控制台:
总结:
(1)对于请求参数,struts2是用request的请求参数匹配Action的setter方法,如对于userName=xxx,struts2是在Action中匹配并调用setUserName()方法,而不管Action中是否有userName成员变量。这一点与struts1不一样,struts1填充formbean是用request的请求参数匹配ActionForm中的成员变量,而不是setter方法,这一点struts1设置的不好。
(2)对于操作Action中的成员变量的值,struts2提供了三种方式,并且当同时操作Action中的成员变量时候,其顺序如下:
一、在<action>的<param>中指定要赋值的属性名,这里也是根据setter方法赋值的,如:<param name="userPass">param of userPass</param>则在Action中匹配并调用setUserPass()方法。
二、从客户端传来的参数,struts2根据request的参数名匹配Action中的setter方法并调用。
三、调用<action>的method属性对应的方法时,为其设值。
(3) struts2中的Date型参数,struts2既可以用java.sql.Date接收,也可以用java.util.Date接收,这与strut1不一样,struts1填充formbean时,对于Date型数据,formbean只能用java.sql.util处理,java.util.Date不能处理。
(4)struts2在响应客户端请求时,会根据getter方法,将Action中的属性保存在requestScope作用域中,jsp页面中可以通过EL表达式取得Action中的属性。
(5)对于采用复合类型接收请求参数的方式,应用"product.id"这种格式作为参数名传递给服务器,以及通过${requestScope.product.id}这张方法取得requestScope作用域的id值。
(6)对于采用复合类型接收请求参数的方式,复合对象必须有无参构造方法,否则会抛出java.lang.InstantiationException: edu.action.Product异常
(7)补充:struts1.x中Action是单实例,只会被实例化一次,在第一次请求到来时实例化,所以是非线程安全的;而struts2中Action不是单实例,对于用户的每一次请求,都会被实例化,所以是线程安全的。