Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

File upload support #8

Open
hakunin opened this issue Sep 24, 2010 · 3 comments
Open

File upload support #8

hakunin opened this issue Sep 24, 2010 · 3 comments

Comments

@hakunin
Copy link
Contributor

hakunin commented Sep 24, 2010

I had the need for file uploads support.

My solution uses appache commons jar (that is not included in Dubious) and it seesms Dubious itself doesn't have support for file uploads (other than blobstore which is a paid feature of appengine if I'm correct)

I would like my solution to be included in dubious or other solution for file uploads.

@hakunin
Copy link
Contributor Author

hakunin commented Sep 24, 2010

Here is the article I used to implement my file uploads http://shogi-software.blogspot.com/2009/04/google-app-engine-and-file-upload.html

@hakunin
Copy link
Contributor Author

hakunin commented Sep 24, 2010

Here is my awesome solution for this problem:

Don't forget to add apache commons to jars.
package dubious;
import java.util.Map;
import java.util.HashMap;
import java.util.Iterator;
import javax.servlet.http.HttpServletRequest;

// for reading form data when posted with multipart/form-data
import java.io.*;
import javax.servlet.ServletException; 
import org.apache.commons.fileupload.FileItemStream;
import org.apache.commons.fileupload.FileItemIterator;
import org.apache.commons.fileupload.servlet.ServletFileUpload;
import com.google.appengine.api.datastore.Blob; 


// Fetch the attributes for a given model using rails conventions.
// We need to do this in Java because getParameterMap uses generics.
// We currently only support one lever: foo[bar] but not foo[bar][baz].
// We currently only pull the first value, so no support for checkboxes
public class ScopedParameterMap {
    public static Map params(HttpServletRequest req, String model) 
      throws ServletException, IOException {        

      Map<String, Object> scoped = new HashMap<String, Object>();      

      if (req.getHeader("Content-Type").startsWith("multipart/form-data")) {
        try { 
          ServletFileUpload upload = new ServletFileUpload();
          FileItemIterator iterator = upload.getItemIterator(req);

          while (iterator.hasNext()) {
            FileItemStream item = iterator.next(); 
            InputStream stream = item.openStream(); 

            String attr = item.getFieldName();

            if (attr.startsWith(model + "[") && attr.endsWith("]")) {
              int len = 0;
              int offset = 0;
              byte[] buffer = new byte[8192];
              ByteArrayOutputStream file = new ByteArrayOutputStream();

              while ((len = stream.read(buffer, 0, buffer.length)) != -1) {
                offset += len;
                file.write(buffer, 0, len);
              }

              String key = attr.split("\\[|\\]")[1];

              if (item.isFormField()) {
                scoped.put(key, file.toString());
              } else {
                scoped.put(key, file.toByteArray());
              }
            }
          }
        } catch (Exception ex) { 
          throw new ServletException(ex); 
        }
      } else {
        Map params = req.getParameterMap();
        Iterator i = params.keySet().iterator();
        while (i.hasNext()) {
            String attr = (String) i.next();
            if (attr.startsWith(model + "[") && attr.endsWith("]")) {
                String key = attr.split("\\[|\\]")[1];
                String val = ((String[]) params.get(attr))[0];
                scoped.put(key, val);
                // TODO: when multiple values, set a List instead
            }
        }
      }

      return scoped;
    }
}

@hakunin
Copy link
Contributor Author

hakunin commented Sep 24, 2010

Add this so that blobs don't get overriden when not sending any file.

            if (file.size() > 0) {
              scoped.put(key, file.toByteArray());
            }

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant