关于提交数据绑定的分析
在使用S2Container+Cubby框架组合的应用中,一般的获取用户提交的数据都是直接通过命名绑定的。
这种绑定,与action的类或方法定义里的@Form注解有关。
当没有书写任何@Form注解或者为:@Form(bindingType = ONLY_SPECIFIED_PROPERTIES) 的时候,
只对标记了@RequestParameter注解的属性和字段进行绑定。如:
@RequestParameter
public BarDto barDto;
public ActionResult m01() {
}
@Form(bindingType = ONLY_SPECIFIED_PROPERTIES)
public ActionResult m02() {
}
如果@Form注解为:@Form(bindingType = ALL_PROPERTIES),则对action的所有属性进行匹配绑定,但是对字段不进行匹配绑定。如:
@Form(bindingType = ALL_PROPERTIES)
public ActionResult m03() {
}
如果@Form注解指定一个对象(这个对象是action类的成员)作为绑定对象,则对这个对象的属性进行匹配绑定,但是不对字段进行匹配绑定。
如下面代码,提交数据绑定到barDto对象中:
public BarDto barDto;
@Form("barDto")
public ActionResult m11() {
}
而如果定义成如下形式,则只对barDto对象中加了@RequestParameter注解的属性和字段进行批匹配绑定。
public BarDto barDto;
@Form("barDto", bindingType = ONLY_SPECIFIED_PROPERTIES)
public ActionResult m12() {
}
同理,下面的代码,则对barDto对象的所有属性进行匹配绑定,但是不对它的字段进行匹配绑定。
public BarDto barDto;
@Form(value = "barDto", bindingType = ALL_PROPERTIES)
public ActionResult m13() {
}
而如果指定@Form注解为NONE的话,则不做任何绑定。如:
@Form(bindingType = NONE)
public ActionResult m21() {
}
另外,可以在action类的定义中进行@Form注解的指定,这样的话,指定对action中的所有方法有效。
如果某方法中同时有不一样的@Form指定,则方法的@Form指定优先。如:
@Form("barDto")
// 统一指定barDto
public class Foo2Action {
public BarDto barDto;
public BazDto bazDto;
public ActionResult m01() {
}
@Form("bazDto")
// 优先指定bazDto
public ActionResult m02() {
}
}
自己手动获取提交数据的方法
对于一些复杂的应用(如表单数据是动态的情况),我们无法简单地通过绑定来获取提交数据,这时候,就要求我们自己手动获取数据了。
在action中,有一些定义以后就能使用的对象,叫做默认对象,包括:
S2Container container;
HttpServletRequest request;
HttpServletResponse response;
ServletContext application;
//ServletContext对应的Map
Map applicationScope;
//ServletContext的初期化参数对应的Map
Map initParam;
//HttpSession对应的Map
Map sessionScope;
//HttpServletRequestの对应的Map
Map requestScope;
//Cookie对应的Map
Map cookie;
//HttpServletRequest的header对应的Map。返回值是String。
Map header;
//HttpServletRequest的header对应的Map。返回值是String数组。
Map headerValues;
//HttpServletRequest的parameter对应的Map。返回值是String。
Map param;
//HttpServletRequest的parameter对应的Map。返回值是String数组。
Map paramValues;
很明显,我们可以通过熟悉的request对象获取数据,
当然,有兴趣的话也可以通过这个框架给出的requestScope获param对象获取数据。
这里需要注意一点的是,如果表单需要进行文件上传,即enctype="multipart/form-data"的时候,
表单是通过二进制上传的,此时就无法像普通表单那样从request里直接读取提交的数据,
这时候我们可以方便的通过框架给的对象来获取提交数据,如:requestScope。
示例代码:
......
// 定义框架的默认对象
public Map<String, Object> requestScope;
.....
public ActionResult anctioMethod() throws Exception {
......
// 获得提交数据的map
Map<String, Object[]> paramMap =
(Map<String, Object[]>)requestScope.get("org.seasar.cubby.params");
// 获得数据,注意这里取到的是Object数组,是为了应对有同名表单项的情况
Object[] nameTemp = paramMap.get("name");
// 获得真正的数据
String name = (String)nameTemp[0];
......
}
......
public String name;