5

I am trying to send a picture to my java servlet (hosted on amazon ec2) to later transfer it to amazon s3 and wonder how to retrieve the Image from the post request.

Upload Code

The request is sent through iOS RestKit API like this (pic.imageData is a NSData type):

RKParams* params = [RKParams params];

[params setValue:pic.dateTaken forParam:@"dateTaken"];
[params setValue:pic.dateUploaded forParam:@"dateUploaded"];

[params setData:pic.imageData MIMEType:@"image/jpeg" forParam:@"image"];

[RKClient sharedClient].username = deviceID;
[RKClient sharedClient].password = sessionKey;

[RKClient sharedClient].authenticationType = RKRequestAuthenticationTypeHTTPBasic;

uploadPictureRequest = [[RKClient sharedClient] post:kUploadPictureServlet params:params delegate:self];

Parsing Code Stub

This is how I parse the other 2 parameters on the Java servlet:

double dateTaken = Double.parseDouble(req.getParameter("dateTaken"));
double dateUploaded = Double.parseDouble(req.getParameter("dateUploaded"));

Question

The question is: how do I retrieve and parse the image on my server?

haylem
  • 22,460
  • 3
  • 67
  • 96
Pochi
  • 13,391
  • 3
  • 64
  • 104

2 Answers2

4

Servlet 3.0 has support for reading multipart data. MutlipartConfig support in Servlet 3.0 If a servelt is annotated using @MutlipartConfig annotation, the container is responsible for making the Multipart parts available through

HttpServletRequest.getParts()
HttpServletRequest.getPart("name");

References:

Community
  • 1
  • 1
Ramesh PVK
  • 15,200
  • 2
  • 46
  • 50
  • It seems i cant use this approach because im running tomcat 6 and according to this site: http://tomcat.apache.org/whichversion.html I only have 2.x serlvets – Pochi Jul 12 '12 at 05:35
  • then you should use commons apache file upload – Ramesh PVK Jul 12 '12 at 05:51
  • @Lion: it's also the way that works only on recent containers :) Not everybody is that lucky, whereas the lib-way is relatively easy and backward- and forward-compatible. If you have a Servlet 3+ capable container, then I'd definitely go for that then. – haylem Jul 13 '12 at 15:08
3

Something along the lines of this, using Apache Commons FileUpload:

 // or @SuppressWarnings("unchecked")
 @SuppressWarnings("rawtypes")
 public void doPost(HttpServletRequest request, HttpServletResponse response) 
         throws ServletException, IOException {
     if (ServletFileUpload.isMultipartContent(request)) {
         final FileItemFactory   factory = new DiskFileItemFactory();
         final ServletFileUpload upload  = new ServletFileUpload(factory);

         try {
             final List items = upload.parseRequest(request);

             for (Iterator itr = items.iterator(); itr.hasNext();) {
                 final FileItem item = (FileItem) itr.next();

                 if (!item.isFormField()) {
                    /*
                     * TODO: (for you)
                     *  1. Verify that file item is an image type.
                     *  2. And do whatever you want with it.
                     */
                 }
             }
         } catch (FileUploadException e) {
             e.printStackTrace();
         }
     }
 }

Refer to the FileItem API reference doc to determine what to do next.

Pochi
  • 13,391
  • 3
  • 64
  • 104
haylem
  • 22,460
  • 3
  • 67
  • 96
  • Thanks for your reply, the apache commons fileupload says the specifies the following: if an HTTP request is submitted using the POST method, and with a content type of "multipart/form-data", then FileUpload can parse that request, and make the results available in a manner easily used by the caller. I my request compliant with this? – Pochi Jul 12 '12 at 03:45
  • @LuisOscar: Try and you shall find the answer. – haylem Jul 12 '12 at 03:46
  • @LuisOscar: Your request is indeed a `POST`. From what I gather from [RestKit](http://restkit.org/)'s [RKParams reference documentation](http://restkit.org/api/0.10.0/Classes/RKParams.html), it should be a multi-part message. – haylem Jul 12 '12 at 03:50
  • thanks, im trying to install the commons fileupload to java so i can test it ill get back to you in a bit. – Pochi Jul 12 '12 at 03:55
  • Ok i managed to import the commons but im getting the following warnings: List is a raw type. References to generic type List should be parameterized. Iterator is a raw type. References to generic type Iterator should be parameterized. – Pochi Jul 12 '12 at 05:38
  • @LuisOscar: it's a warning, not an errror (so you can live with it, if you understand it) and that's because the Apache Commons File Upload library does not support generics and returns raw types. If you want to not have this warning, add the annotation `@suppresswarnings("rawtypes")` to the method. – haylem Jul 12 '12 at 07:53
  • @LuisOscar: if this one doesn't work (depends on your exact Java compiler version), use `@SuppressWarnings("unchecked")` instead. – haylem Jul 12 '12 at 08:04
  • that did remove the warning, but when i run it on my server i get this exception java.lang.NoClassDefFoundError: org/apache/commons/io/output/DeferredFileOutputStream. So i thing im not getting the class to the server... would happen to know the solution for this? thanks – Pochi Jul 12 '12 at 08:35
  • @nevermind that last message, turns out i need to add the commons.io since its a dependency... lol java is so weird – Pochi Jul 12 '12 at 09:08
  • @LuisOscar: Define weird? You expect it to know auto-magically what you need? If you import a class from a package, it may request to import other classes from other packages, but it's up to your build to have all the required bundles on the classpath. Seems pretty common and similar to every other language to me: compiled languages with static libraries, C# with the Java equivalent, etc... – haylem Jul 12 '12 at 10:12
  • well the problem was more like i didnt know because eclipse didnt say it needed it and when runing from eclipse to the server the library was not being exported. But no i ran into another problem. I do find the image like this if ("image/jpeg".equals(item.getContentType())) but the item.get() gives me a byte[] type or a InputStream, SHould i convert to a File type to pass to s3? or get the lenght and input stream and pass it like that to s3? thanks – Pochi Jul 13 '12 at 01:09
  • haha sorry again, just figured it out, i can simply pass the inputstream along with the content lenght to the amazon request constructor method. thanks for all your help – Pochi Jul 13 '12 at 02:06