request.getSession(false) - can be null!@@ -84,6 +91,7 @@ * * @author Guillaume Laforge * @author Christian Stein + * @author Tomasz Blachowicz */ public class ServletBinding extends Binding { @@ -138,6 +146,40 @@ } } binding.setVariable("params", params); + + /* + * If request is multipart its content is parsed. + * For each decoded part we check its type. + * - When it is an regular form field we treat it as + * request parameter and put in "params" implicit object. + * (NOTE: when request is multipart values of parameters + * aren't accessible via HttpServletRequest.getParameter* + * methods!) + * - Otherwise we create new object of uploaded file and + * put it in "uploads" implicit object. + */ + Map uploads = new HashMap(); + if(FileUpload.isMultipartContent(request)) { + DiskFileUpload parser = new DiskFileUpload(); + List /* FileItem */ items; + try { + items = parser.parseRequest(request); + } catch (FileUploadException e) { + //Ooops! Something gone bad while parsing request. + throw new RuntimeException(e); + } + for(int i = 0, n = items.size(); i < n; i++) { //iterate over decoded parts + FileItem item = (FileItem) items.get(i); + String itemName = item.getFieldName(); + if(item.isFormField()) { //is regular form field + params.put(itemName, item.getString()); + } else { //is uploaded file + UploadedFile uploadedFile = new UploadedFile(item); + uploads.put(itemName, uploadedFile); + } + } + } + binding.setVariable("uploads", uploads); /* * Bind request header key-value hash map. Index: src/main/groovy/servlet/UploadedFile.java =================================================================== RCS file: src/main/groovy/servlet/UploadedFile.java diff -N src/main/groovy/servlet/UploadedFile.java --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ src/main/groovy/servlet/UploadedFile.java 1 Jan 1970 00:00:00 -0000 @@ -0,0 +1,118 @@ +/* +$Id$ + +Copyright 2005 (C) Guillaume Laforge. All Rights Reserved. + +Redistribution and use of this software and associated documentation +("Software"), with or without modification, are permitted provided +that the following conditions are met: + +1. Redistributions of source code must retain copyright + statements and notices. Redistributions must also contain a + copy of this document. + +2. Redistributions in binary form must reproduce the + above copyright notice, this list of conditions and the + following disclaimer in the documentation and/or other + materials provided with the distribution. + +3. The name "groovy" must not be used to endorse or promote + products derived from this Software without prior written + permission of The Codehaus. For written permission, + please contact info@codehaus.org. + +4. Products derived from this Software may not be called "groovy" + nor may "groovy" appear in their names without prior written + permission of The Codehaus. "groovy" is a registered + trademark of The Codehaus. + +5. Due credit should be given to The Codehaus - + http://groovy.codehaus.org/ + +THIS SOFTWARE IS PROVIDED BY THE CODEHAUS AND CONTRIBUTORS +``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT +NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND +FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL +THE CODEHAUS OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, +INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR +SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) +HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, +STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED +OF THE POSSIBILITY OF SUCH DAMAGE. + +*/ +package groovy.servlet; + +import java.io.IOException; +import java.io.InputStream; +import java.io.Serializable; + +import org.apache.commons.fileupload.FileItem; + +/** + * Object of this class are accessible by "uploads" impicit object accross Groovlets. + * It wraps Jakarta Commons FileUpload interface of uploaded disk file. + * + * @author Tomasz Blachowicz + */ +public class UploadedFile implements Serializable { + + /** + * Wrapped uploaded file + */ + private final FileItem fileItem; + + /** + * Creates new instance of uploaded file + * + * @param fileItem uploaded file to wrap + */ + public UploadedFile(FileItem fileItem) { + this.fileItem = fileItem; + } + + /** + * @return Name of uploaded file, as provided by browser + */ + public String getName() { + return fileItem.getName(); + } + + /** + * @return Size of uploaded file + */ + public long getSize() { + return fileItem.getSize(); + } + + /** + * @return Content type of uploaded file. + * Type should by MIME compilant. + */ + public String getContentType() { + return fileItem.getContentType(); + } + + /** + * @return Stream from uploaded file. When IO problem + * occur we re-throw RTE. + */ + public InputStream getInputStream() { + try { + return fileItem.getInputStream(); + } catch (IOException e) { + throw new RuntimeException(e); + } + } + + /** + * @return Full content of uploaded file. Be careful + * invoking this method, content of file may be very big. + */ + public byte[] getContent() { + return fileItem.get(); + } + +}