struts2 18拦截器详解(十二)
该拦截器处于defaultstack第十一的位置,看这个拦截器的名称应该就是对checkbox进行处理的。要理解这个拦截器的作用有一点必须知道:当一个form表单中存在一个checkbox的时候,假设这个checkbox的name属性值为married,当我们选上这个checkbox的时候请求参数命令里有一个married=true参数,而当我们没有选上这个checkbox的时候,请求参数里面根本就没有这个married参数,就相当于form表单中根本就没有这个checkbox,而大多数情况下我们想要的结果是,当没有选上这个checkbox的时候请求参数集合里有这个married参数,只不过它的值为"false"。问题引出来了,而该拦截器就可以用来解决这个问题。下面是该拦截器的intercept方法:
[java]
public string intercept(actioninvocation ai) throws exception {
map parameters = ai.getinvocationcontext().getparameters();//获取请求参数map
map<string, string[]> newparams = new hashmap<string, string[]>();//创建一个新参数map
set<map.entry> entries = parameters.entryset();
for (iterator<map.entry> iterator = entries.iterator(); iterator.hasnext();) {//迭代请求参数map
map.entry entry = iterator.next();
string key = (string)entry.getkey();//获取当前迭代的请求参数的key,即form表单字段的name属性值
if (key.startswith("__checkbox_")) {//判断key是否以__checkbox_开关
string name = key.substring("__checkbox_".length());//获取当前key __checkbox_后面部分字符串
//获取当前entry的值
object values = entry.getvalue();
iterator.remove();//从请求参数map中移除当前entry
if (values != null && values instanceof string[] && ((string[])values).length > 1) {
//如果进入该if语句,则说明同一个checkbox设置了两次,则直接进入下一个entry
log.debug("bypassing automatic checkbox detection due to multiple checkboxes of the same name: #1", name);
continue;
}
// 判断名为 name变量值 的checkbox是否被选中,没有选中则不会有相应的参数
if (!parameters.containskey(name)) {
// 没有选中则向新参数map中添加一个key为 name变量值 的长度为1的字符串数组
newparams.put(name, new string[]{uncheckedvalue});
}
}
}
//把新的参数map加入到请求参数map中
parameters.putall(newparams);
//调用下一个拦截器
return ai.invoke();
}
为了更好的理解该拦截器的功能,下面列举一个表单:
[html]
<form action="xtayfjpk.do" method="post">
<input type="checkbox" name="married" value="3"/>已婚<br/>
<input type="hidden" name="__checkbox_married"/><br/>
<input type="submit" value="提交"/>
</form>
当进入到该拦截器之后,判断当前迭代的name属性值是否以__checkbox_开头,如果不是以__checkbox_开关则没有任何操作,如果以__checkbox_开头则把__checkbox_后面的部分截取出来,这里即得到married,然后获取_checkbox_married参数值,再将该参数从请求参数map中移除(因为这个参数只是一个标记而已),然后获取__checkbox_married的值,正常情况应该是为null的,但如果有值则说明相同意义的checkbox被设置了两次这样就会打印一个debug信息不再执行下面的操作。正常情况为null则去判断married checkbox有无被选中,选中了married参数就会在request参数map中,如果没有选中则不会,但通过newparams.put(name, new string[]{uncheckedvalue});这句代码给married赋值了一个长度为1的字符串数组其值为uncheckedvalue,该值是可以设置的,默认值为"false",最后把newparams中的数据全部添加到request请求参数map中,完成逻辑,再调用下一个拦截器。
不知道大家有没有发现获取的请求参数值返回的是string[],而不是一个字符串,就拿checkbox举个例子,如果用多个checkbox让用户选爱好,这样就可能出现多个爱好,所以要用一个string[]去接收,为了统一参数接收,即是一个值的返回的也是一个string[],只不过数组长度为1。
既然一个参数名可以接收多个参数值,那为什么上面例子当__checkbox_married有值的时候却不再执行下面的代码了呢?这是因为__checkbox_married这个参数只是用来标识当married checkbox没有选中的时候该拦截器要不要对其进行处理,而正常情况下是不应该有值的。要使该拦截器有效则必须在form表单中添加一个名为"__checkbox_"+要处理的checkbox的name属性值的字段。
这里呢再讲一下关于request对象取参数值方法的一点细节:
当调用request.getparameter(key)返回的是一个字符串,调用request.getparametermap.get(key)返回的是一个字符串数组,一开始觉得有点迷惑,觉得返回值应该是相同的,这里却出现了不一样的结果(key相同),后来去翻了tomcat的源码才弄明白。
request.getparameter(key),实际调用的是org.apache.tomcat.util.http.parameters类中的getparameter(string name)方法:
[java]
public string getparameter(string name) {
handlequeryparameters();
arraylist values = (arraylist)this.paramhashvalues.get(name);
if (values != null) {
if (values.size() == 0)
return "";
return ((string)values.get(0));//返回index为0的元素
}
return null;
}
request.getparametermap.get(key),实际调用的是org.apache.tomcat.util.http.parameters类中的getparametermap方法:
[java]
public map getparametermap() {
if (parametermap.islocked())
return parametermap;
enumeration enumeration = getparameternames();
while (enumeration.hasmoreelements()) {
string name = enumeration.nextelement().tostring();
string[] values = getparametervalues(name);//获取值数组
parametermap.put(name, values);//放入了parametermap中
}
parametermap.setlocked(true);
return parametermap;
}
public string[] getparametervalues(string name) {//该方法获取值数组
handlequeryparameters();
arraylist values = (arraylist)this.paramhashvalues.get(name);
if (values == null)
return null;
return ((string[])values.toarray(new string[values.size()]));//将values arraylist转成了string[]返回
}
上一篇: 对Python 内建函数和保留字详解
下一篇: 有关Oracle数据库的备份情况