Got it! One has been tracing through the Struts 1.1 source to see how it does its thing and one has worked out why Daniel and oneself are having difficulties.
The problem lies in the way multipart forms are handled differently by the RequestProcessor. One of the first calls in RequestProcessor.process() is to processMultipart(). This will determine whether it is necessary to wrap the request with a MultipartRequestWrapper. It will NOT however initialise the parameters of the MultipartRequestWrapper instance yet. The RequestProcessor will then call other processXXX methods(): processPath, processLocale, processContent, processNoCache, processPreProcess, processMapping, processActionForm(*). These calls get passed the request - for a multipartform this is the MultipartRequestWrapper. This wrapper however has not at this stage had its parameters initialised - if one overrides these RequestProcessor methods in ones own RequestProcessor subclass then one cannot make use of request.getParameter() when one has a multipart request - it will just return null. For non-multipart requests however, it will work as expected. After this, processPopulate is called. If form==null (ie: one does not have any ActionForm associated with this request) then the method will return immediately , doing nothing. Otherwise it will delegate to RequestUtils.populate where it checks if a multipart form is being used. If this is the case it will get the MultipartRequestHandler (implementing class instance) and use it to process the request's input stream. THIS is the point when the parameters in the MultipartRequestWrapper get populated. After this, the action form is populated from the request using BeanUtils.populate as per normal. This logic has certain implications, the most obvious being that if one submits from a multipart form and one is not using any ActionForm then one will not have any request parameters, as they will not never be populated.(**) We are not amused ;-) We find this to be a rather odd way of doing things and think it would surely be much better and more transparent if the parameters in the MultipartRequestWrapper were initialised immediately in the call to processMultipart() and thus available to all the other overrideable methods in RequestProcessor that get called before processPopulate() when using multipart forms in the same way they already are when using non-multipart forms. Such a change should also include making population of parameters in the MultipartRequestWrapper independent of the ActionForm. That way one would not be forced to use an ActionForm should one desire to read properties in a multipart request. --- (*) This is a darn nuisance for us as we need to get a certain parameter value in my processActionForm(). (**) My problem was that because my code couldnt read that parameter in processActionForm(), I couldnt actually get my ActionForm instance, and thus when I got to my DispatchAction had no parameters to specify which method to be called... -----Original Message----- From: Andrew Hill [mailto:[EMAIL PROTECTED]] Sent: Tuesday, July 16, 2002 12:53 To: Struts Users Mailing List Subject: RE: MultipartRequestWrapper.getParameter() not returning anything Daniel could have written this a wee bit clearer. It is indeed the struts request processor and not us that is doing the wrapping. The resulting HttpServletRequest (with implementing class of org.apache.struts.upload.MultipartRequestWrapper) is always returning null for getParameter() and an empty enumeration for getParameterNames(). (We ARE treating it like any other request - or would be if the code even got as far as calling our action methods) This of course kills our dispatch actions <!--Our dispatch action class is actually a copy&paste job as I wanted to add some convienience methods to all actions and got sick and tired trying to keep them synced between my ActionBase and DispatchActionBase. It is just a copy of the dispatch action in struts but inherits from my GTActionBase class which inherits from Action, instead of inheriting directly from Action as the original does.--> as they cannot find their method parameter... (It would also kill a lot of our own code if execution could even get that far...) Switch the form back to a normal form (as opposed to a multipart/form-data) enctype, and the parameters will start working again. btw: We *have* overridden the RequestProcessor with our own class that inherits from the struts supplied RequestProcessor, but our class only overrides the processActionForm() method (and even that delegates to the super().processActionForm()) when it doesnt have to perform special handling. In the process of disagnosing this problem I have overriden processMultipart() by copying and pasting the method into my request processor class, and have added two println so I can see it detecting the multipart nature of the request and choosing to use the wrapper (also moved the {} to a _readable_ position ;->): protected HttpServletRequest processMultipart(HttpServletRequest request) { System.out.println("processRequest():Request class=" + request.getClass().getName()); //<--Added if (!"POST".equals(request.getMethod())) { return (request); } String contentType = request.getContentType(); if ((contentType != null) && contentType.startsWith("multipart/form-data")) { System.out.println("Wrapping request with MultipartRequestWrapper"); // <-- Added return (new MultipartRequestWrapper(request)); } else { System.out.println("Request is not for multipart/form-data"); // <-- Added return (request); } } I added the following method to my DispatchAction superclass (yes - the copy&pasted clone with funny inheritance): private void dumpRequest(HttpServletRequest request) { System.out.println("Request Class=" + request.getClass().getName()); System.out.println("Request parameter dump:-----------------------------"); Enumeration params = request.getParameterNames(); while(params.hasMoreElements()) { String param = (String)params.nextElement(); System.out.println(param + "=" + request.getParameter(param)); } System.out.println("----------------------------------------------------"); } I call this in the first line of perform() before the code (which is identical to the _real_ dispatch action as its copied and pasted) excutes. It is showing the request as having no parameters, a fact backed up by the dispatch action code which fails as it cant find the method parameter, so doesnt know which method in the subclass to call... The full method is below: As you can see, only the dumpRequest() line is different from the _real_ struts dispatch action. The if(name==null) check returns true, thus causing the response.sendError() to be called. If the form is not enctype="multipart/form-data" this check returns false, and the appropriate method in the subclass will get called... /** * Process the specified HTTP request, and create the corresponding HTTP * response (or forward to another web component that will create it). * Return an <code>ActionForward</code> instance describing where and how * control should be forwarded, or <code>null</code> if the response has * already been completed. * * @param mapping The ActionMapping used to select this instance * @param actionForm The optional ActionForm bean for this request (if any) * @param request The HTTP request we are processing * @param response The HTTP response we are creating * * @exception IOException if an input/output error occurs * @exception ServletException if a servlet exception occurs */ public ActionForward perform(ActionMapping mapping, ActionForm form, HttpServletRequest request, HttpServletResponse response) throws IOException, ServletException { dumpRequest(request); // Identify the request parameter containing the method name String parameter = mapping.getParameter(); if (parameter == null) { String message = messages.getMessage("dispatch.handler", mapping.getPath()); log.error(message); response.sendError(HttpServletResponse.SC_INTERNAL_SERVER_ERROR, message); return (null); } // Identify the method name to be dispatched to String name = request.getParameter(parameter); if (name == null) { String message = messages.getMessage("dispatch.parameter", mapping.getPath(), parameter); log.error(message); response.sendError(HttpServletResponse.SC_BAD_REQUEST, message); return (null); } // Invoke the named method, and return the result return dispatchMethod(mapping,form,request,response,name); } -----Original Message----- From: Martin Cooper [mailto:[EMAIL PROTECTED]] Sent: Tuesday, July 16, 2002 12:11 To: 'Struts Users Mailing List' Subject: RE: MultipartRequestWrapper.getParameter() not returning anything You shouldn't be doing any wrapping yourself - the use of the wrapper is internal to Struts, and should be transparent to you. If you remove any of your own code that's trying to use the wrapper (i.e. just assume it's a normal request), things should start working. -- Martin Cooper > -----Original Message----- > From: Daniel J. D'Cotta [mailto:[EMAIL PROTECTED]] > Sent: Monday, July 15, 2002 8:58 PM > To: Struts Users List > Subject: MultipartRequestWrapper.getParameter() not returning anything > > > Hi, > > I am using Struts 1.1-B1 with Tomcat 4.0.3. > > When I change my form enctype to 'multipart/form-data' and > wrap the request > into a MultipartRequestWrapper, the getParameter() and > getParameterNames() > are not returning any values at all. > > Has anyone encountered this problem before. Is there any work around? > > > Regards, > Daniel D'Cotta > > Ext: 212 > > > -- > To unsubscribe, e-mail: <mailto:[EMAIL PROTECTED]> For additional commands, e-mail: <mailto:[EMAIL PROTECTED]> -- To unsubscribe, e-mail: <mailto:[EMAIL PROTECTED]> For additional commands, e-mail: <mailto:[EMAIL PROTECTED]> -- To unsubscribe, e-mail: <mailto:[EMAIL PROTECTED]> For additional commands, e-mail: <mailto:[EMAIL PROTECTED]> -- To unsubscribe, e-mail: <mailto:[EMAIL PROTECTED]> For additional commands, e-mail: <mailto:[EMAIL PROTECTED]>

