Dev Zone
偏执狂才能生存,人生/事业的路上需要再坚持一下
但是又怎么说得清坚持的结果,道得尽坚持的含义

2006年3月15日

     发现一个问题,使用struts进行文件上传,如果有些参数没有完全定义在ActionForm中,需要从request.getParameter获取,在表单提交并且validate失败返回input页面时,这部分需要从request.getPrameter获取的参数数据都丢失了,即使再对request进行multipart解析也不能得到。

     经过分析,发现struts的ActionServlet在接收到multipart请求之后,在RequestProcessor中会对request进行封装:MultiRequestWrapper,然后在Action执行完之后,又将已经封装的request重新还原。以下是部分代码,截直RequestProcessor:

封装:
    protected HttpServletRequest processMultipart(HttpServletRequest request) {

        
if (!"POST".equalsIgnoreCase(request.getMethod())) {
            
return (request);
        }

        
        String contentType 
= request.getContentType();
        
if ((contentType != null&&
            contentType.startsWith(
"multipart/form-data")) {
            
return (new MultipartRequestWrapper(request));
        }
 else {
            
return (request);
        }


    }

还原:
   在doForward和doInclude中在forward和include之前都执行了下面的代码:
        if (request instanceof MultipartRequestWrapper) {
            request 
= ((MultipartRequestWrapper) request).getRequest();
        }


     问题就出现在这儿。在经过测试之后,发现request只能进行一次multipart解析,这或许和解析request的时候调用了request.inputStream有关,第一次调用之后再调用就不能获取其中的有效内容了。因此发现request在调用CommonsMultipartRequestHandler.handleRequest进行解析后并还原后,调用common-upload对request进行解析已经得不到任何得提交内容了,因此当Form验证失败,返回input页面时,即使再进行multpart解析,也不能通过request.getPrameter取到你想要的数据。而此时,表单中的数据却不会丢失(定义在ActionForm中的表单域),这是因为struts的html系列tag在redisplay时值都是从ActionForm获取的。

       在将RequestProcessor.doForward和doInclude中还原request的语句注释后,问题得到了解决。到目前还不清楚为什么struts要还原request,难道是因为chain的原因?

       webwork中应该不会出现这个问题,因为webwork中无论ServletDispatcher还是FilterDispatcher在对request wrap之后都没有再还原。
posted @ 2006-03-15 06:10 dev 阅读(3919) | 评论 (1)编辑 收藏