4

I am using DropZone.js

My configuration is

Dropzone.options.myAwesomeDropzone = {
                        url: 'UploadImages',
                        previewsContainer: ".dropzone-previews",
                        uploadMultiple: true,
                        parallelUploads: 5,
                        maxFiles: 20,
                        addRemoveLinks: true,
                        init: function() {
                            this.on("success", function(file, response) {
                                $('.dz-progress').hide();
                                console.log(response);
                                console.log(file);
                            });
                        }
                    }
                });

This code is working perfectly with my local host. I am uploading files to UploadImages url. I have entered one message in that url method that is working properly.

My problem is I am not getting which name should i use to get the content in server. Like what is name of imageFile variable, imageName variable, imageContent Type that should i access in my server side implementation.

Edit : Server side implementation of DropZone

Dropzone does not provide the server side implementation of handling the files, but the way files are uploaded is identical to simple file upload forms like this:

<form action="" method="post" enctype="multipart/form-data">
  <input type="file" name="file" />
</form>

I got it includes

<input type="file" name="file" /> 

automatically in form so we can access it using file

If

<input name="file" type="file" multiple />

then we can access it using file[] in server side I tried

  public class ImageAction extends ActionSupport {
         private List<File> file;
         private List<String> fileContentType;
         private List<String> fileFileName;

         System.out.println("Inside Image upload ");
        System.out.print("\n\n---------------------------------------\n");
        int i = 0;
        for (File f : file) {
            System.out.print("\nFile [" + i + "] ");
            System.out.print(" length: " + f.length());
            System.out.print(" name:" + getFileFileName().get(i));
            System.out.print(" contentType: " + getFileContentType().get(i));

            i++;
        }
        System.out.println("\n---------------------------------------\n");
       }
       //getter setter  
       }

It is printing Inside Image upload.

How to make access fields of file on Action class.

Andrea Ligios
  • 49,480
  • 26
  • 114
  • 243
xrcwrn
  • 5,339
  • 17
  • 68
  • 129

2 Answers2

3

Problem

When you use

<input type="file" name="file" multiple /> 

the files will all be sent with name="file", eg:

Content-Disposition: form-data; name="file"; filename="foo.jpg"
Content-Type: image/jpeg
...........
. ...
.......
Content-Disposition: form-data; name="file"; filename="bar.jpg"
Content-Type: image/jpeg
....
.
..
.......

and this is the right parameter Struts2 FileUpload Interceptor is expecting to receive, to work with a List<File> and the related List<String> for fileName and contentType.

When you use dropzone.js, instead, the filename will be altered to handle the multiple input client-side, by appending [] to it:

paramName: The name of the file param that gets transferred. Defaults to file. NOTE: If you have the option uploadMultiple set to true, then Dropzone will append [] to the name.

eg.

Content-Disposition: form-data; name="file[0]"; filename="foo.jpg"
Content-Type: image/jpeg
...........
. ...
.......
Content-Disposition: form-data; name="file[1]"; filename="bar.jpg"
Content-Type: image/jpeg
....
.
..
.......

Struts2 doesn't like it at all.

Solution

Instead of messing with custom Interceptors and Converters, do a simple adjustment on the dropzone.js library you use for your Struts2 projects:

  1. Rename your dropzone.js to dropzone-struts2.js;
  2. Open the file and search "[" + n + "]" (line 866 in latest version)
  3. Change this line

    return "" + this.options.paramName + (this.options.uploadMultiple ? "[" + n + "]" : "");
    

    to this one

    return "" + this.options.paramName; //+ (this.options.uploadMultiple ? "[" + n + "]" : "");
    

Now it is Struts2 compliant, and will work with multiple uploads.

Andrea Ligios
  • 49,480
  • 26
  • 114
  • 243
  • Inside loop it is printing first two statements then it is showing `java.lang.NullPointerException social.action.ImageAction.insertToDir(ImageAction.java:51) ` for `System.out.print(" name:" + getFileFileName().get(i));` – xrcwrn Sep 30 '14 at 05:44
  • It is working in my SSCCE. You need to ensure that you are not hitting any cap (max file size for dropzone.js, max file size for File Upload Interceptors, max request size). Please try with one small file (some Kb), then with two, then more, and report here what happens. Also make sure the js file is not cached (inspect with firebug, otherwise CTRL+F5). If you still have problems, please post here your real code, struts config, jsp code. – Andrea Ligios Sep 30 '14 at 10:48
  • 1
    **UPDATE**: now the line is 1246 and the code to modify is a bit different: `return \`${this.options.paramName}${this.options.uploadMultiple ? \`[${n}]\` : ""}\`;` – Andrea Ligios Apr 19 '18 at 12:43
  • **UPDATE**: for version 6.0.0-beta2, the line is 1178: `return "".concat(this.options.paramName).concat(this.options.uploadMultiple ? "[".concat(n, "]") : "");`, remove this part: `.concat(this.options.uploadMultiple ? "[".concat(n, "]") : "")` – Edu Castrillon May 13 '22 at 08:29
1

The accepted answer explanation is right but there's a simpler way to handle that than modifying the original source code.

According to the following comment from the _getParamName function :

// @options.paramName can be a function taking one parameter rather than a string.

so you can override the default behavior by simply setting the option paramName to:

paramName: (index) => 'file',

simply ignoring the index and returning 'file' for every file, 'file' being the param name you want to send to the server.

Ultraspider
  • 156
  • 1
  • 3