struts拦截器详解十二
该拦截器处于defaultStack第十一的位置,看这个拦截器的名称应该就是对checkbox进行处理的。要理解这个拦截器的作用有一点必须知道:当一个form表单中存在一个checkbox的时候,假设这个checkbox的name属性值为married,当我们选上这个checkbox的时候请求参数命令里有一个married=true参数,而当我们没有选上这个checkbox的时候,请求参数里面根本就没有这个married参数,就相当于form表单中根本就没有这个checkbox,而大多数情况下我们想要的结果是,当没有选上这个checkbox的时候请求参数集合里有这个married参数,只不过它的值为"false"。问题引出来了,而该拦截器就可以用来解决这个问题。下面是该拦截器的intercept方法源码:
publicStringintercept(ActionInvocationai)throwsException{Mapparameters=ai.getInvocationContext().getParameters();//获取请求参数MapMapString,String[]newParams=newHashMapString,String[]();//创建一个新参数MapSetMap.Entryentries=parameters.entrySet();for(IteratorMap.Entryiterator=entries.iterator();iterator.hasNext();){//迭代请求参数MapMap.Entryentry=iterator.next();Stringkey=(String)entry.getKey();//获取当前迭代的请求参数的key,即form表单字段的name属性值if(key.startsWith("__checkbox_")){//判断key是否以__checkbox_开头Stringname=key.substring("__checkbox_".length());//获取当前key__checkbox_后面部分字符串//获取当前entry的值Objectvalues=entry.getValue();iterator.remove();//从请求参数Map中移除当前entryif(values!=nullvaluesinstanceofString[]((String[])values).length1){//如果进入该if语句,则说明同一个checkbox设置了两次,则直接进入下一个entryLOG.debug("Bypassingautomaticcheckboxdetectionduetomultiplecheckboxesofthesamename:#1",name);continue;}//判断名为name变量值的checkbox是否被选中,没有选中则不会有相应的参数if(!parameters.containsKey(name)){//没有选中则向新参数Map中添加一个key为name变量值的长度为1的字符串数组newParams.put(name,newString[]{uncheckedValue});}}}//把新的参数Map加入到请求参数Map中parameters.putAll(newParams);//调用下一个拦截器returnai.invoke();}
为了更好的理解该拦截器的功能,下面列举一个表单:
formaction="xtayfjpk.do"method="post"inputtype="checkbox"name="married"value="3"/已婚/brinputtype="hidden"name="__checkbox_married"//brinputtype="submit"value="提交"//form
当进入到该拦截器之后,判断当前迭代的name属性值是否以__checkbox_开头,如果不是以__checkbox_开头则没有任何操作,如果以__checkbox_开头则把__checkbox_后面的部分截取出来,这里即得到married,然后获取_checkbox_married参数值,再将该参数从请求参数Map中移除(因为这个参数只是一个标记而已),然后获取__checkbox_married的值,正常情况应该是为null的,但如果有值则说明相同意义的checkbox被设置了两次这样就会打印一个debug信息不再执行下面的操作。正常情况为null则去判断marriedcheckbox有无被选中,选中了married参数就会在request参数Map中,如果没有选中则不会,但通过newParams.put(name,newString[]{uncheckedValue});这句代码给married赋值了一个长度为1的字符串数组其值为uncheckedValue,该值是可以设置的,默认值为"false",最后把newParams中的数据全部添加到request请求参数Map中,完成逻辑,再调用下一个拦截器。
不知道大家有没有发现获取的请求参数值返回的是String[],而不是一个字符串,就拿checkbox举个例子,如果用多个checkbox让用户选爱好,这样就可能出现多个爱好,所以要用一个String[]去接收,为了统一参数接收,即是一个值的返回的也是一个String[],只不过数组长度为1。
既然一个参数名可以接收多个参数值,那为什么上面例子当__checkbox_married有值的时候却不再执行下面的代码了呢?这是因为__checkbox_married这个参数只是用来标识当marriedcheckbox没有选中的时候该拦截器要不要对其进行处理,而正常情况下是不应该有值的。要使该拦截器有效则必须在form表单中添加一个名为"__checkbox_"+要处理的checkbox的name属性值的字段。
这里呢再讲一下关于request对象取参数值方法的一点细节:当调用request.getParameter(key)返回的是一个字符串,调用request.getParameterMap.get(key)返回的是一个字符串数组,一开始觉得有点迷惑,觉得返回值应该是相同的,这里却出现了不一样的结果(key相同),后来去翻了Tomcat的源码才弄明白。request.getParameter(key),实际调用的是org.apache.tomcat.util.
转载请注明:http://www.sonphie.com/jbby/14411.html