1

When trying to upload multiple files with Struts 2 using ArrayList, how to identify each field?

For example, if I have two file fields, File1 and File2 and on the client side, I choose to upload only File2, Struts 2 only creates one element in the list and I am not able to correctly map File1 as empty and File2 with the uploaded file.

Is there any identifier I can use here?

Roman C
  • 49,761
  • 33
  • 66
  • 176
user2475448
  • 155
  • 1
  • 8

2 Answers2

0

Name each field with different names and create corresponding accessors to action properties. Then each of them will handle the name by OGNL and set corresponding properties. Try with different approach create list or map for the files indexed by iterator tag.

<iterator begin="0" end="50" status="status"> 
  <s:file label="%{File + #status.index}" name="fileUpload[%{#status.index}]" size="40" />
</iterator>

<s:submit value="submit" name="submit" />

in action

private List<File> fileUpload = new ArrayList<File>();

also accessors should be for each property

then you will know which of them uploaded by checking the file at the list index. You could also try with the Map.

<iterator begin="0" end="50" status="status"> 
  <s:file label="%{File + #status.index}" name="fileUpload['%{#status.index}']" size="40" />
</iterator>

<s:submit value="submit" name="submit" />

in action

private Map<String, File> fileUpload = new HashMap<String, File>();

what is better suits your needs

Roman C
  • 49,761
  • 33
  • 66
  • 176
  • Thanks for the response Roman, but the problem is that I am creating the form dynamically based on a value from database. So, I might generate a form with 2 file fields or 50 file fields and I won't be able to define getters and setters for each one. – user2475448 Jun 11 '13 at 19:47
  • 1
    The Map option works and I am able to identify based on the Map's key. However, I am not able to get the fileName and contentType using Map or for that matter using List (with key) as it gives out a warning as follows. "WARNING: Parameter [fileUpload[2]FileName] didn't match acceptedPattern pattern!" – user2475448 Jun 11 '13 at 21:32
  • I found this link with the same problem. But that answer didn't work either. [link]http://stackoverflow.com/questions/5477877/struts2-multiple-file-upload-with-map. I wonder why Struts 2 documentation doesn't include this Map option for uploading files. – user2475448 Jun 11 '13 at 21:34
  • @user2475448 You may try to combine all three fields in the custom class and use it as an element of the collection. A few changes required then in the names to populate the indexed property. – Roman C Jun 12 '13 at 08:30
  • @RomanC , I also want to implement the same, but not able to map in my Action, plz, **guide** me for the same. I have `File []` **not** `List`, and **I don't want to miss Indexing of uploaded file** – Shantaram Tupe Nov 14 '16 at 13:26
  • @shantaram You can try to send an index value with the name. – Roman C Nov 22 '16 at 19:21
0

Use a List (or Map) of a custom object, containing your File, the fileName and the contentType (and eventually other fields). An JSP row corresponding element, to be clear.

I did like that (because I had many other fields too) and it works like a charm.

(this is not the only way, it is just one of the working ways that will become even more handy when you will need to handle additional fields too)

POJO

public class MyCustomRow implements Serializable {

    private File   fileUpload;
    private String fileUploadFileName; 
    private String fileUploadContentType;

    private String otherField1;
    private String otherField2;

    /* All Getters and Setters here */
}

in Action

private List<MyCustomRow> rows;
/* Getter and Setter ... */

in JSP

<s:iterator value="rows" status="row">

    <s:file      name="rows[%{#row.index}].fileUpload" />

    <s:textfield name="rows[%{#row.index}].otherField1"/>
    <s:textfield name="rows[%{#row.index}].otherField2"/>

</s:iterator>

File name and content-type will be automatically detected and populated by Struts2 (ensure you have FileUploadInterceptor in your stack).

Andrea Ligios
  • 49,480
  • 26
  • 114
  • 243