欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  IT编程

struts2 18拦截器详解(十二)

程序员文章站 2023-08-26 21:27:10
checkboxinterceptor      该拦截器处于defaultstack第十一的位置,看这个拦截器的名称应该就是对checkbox进行处理的。要理解这个拦...
checkboxinterceptor

 

   该拦截器处于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[]返回  

}