Apache Struts 2 Documentation > Home > FAQs > Cookbook > Handling File Uploads |
The framework comes with built in file upload support. Uploading a file is simple. When FilterDispatcher receives a request, it checks to see if the request contains multipart content. If it does the dispatcher creates a MultipartWrapperRequest. This wrapper handles receiving the file and saving to disk. It is important for the Action programmer to check to see if any errors occured during processing. Three properties can be set that effect file uploading.
Properties can be set by putting a struts.properties file in WEB-INF/classes. Any property found in the properties file will override the default value.
If you're happy with the defaults, there is no need to put any of the properties in struts.properties.
# put the uploaded files in /tmp. My application will move them to their
# final destination
struts.multipart.saveDir=/tmp
Note, while you can set these properties to new values at runtime the MultiPartRequestWrapper is created and the file handled before your Action code is called. So if you want to change values you must do so before this Action.
<%@ taglib uri="action2" prefix="saf" %> <html> <head> <title>File Upload Test</title> </head> <body> <h1>File Upload</h1> <form action="FileUpload.action" method="POST" enctype="multipart/form-data"> <center> <table width="350" border="0" cellpadding="3" cellspacing="0"> <tr> <td colspan="2"><input type="file" name="FileName" value="Browse..." size="50"/></td> </tr> <tr> <td colspan="2" align="center"> <input type="submit" value="Submit"> </td> </tr> </table> </center> </form> </body> </html>
That's all you have to do to upload a file. No coding required, the file will be placed in the default directory. However, that leaves us with no error checking among other things. So let's add some code to the Action.
Before the Action method is called the dispatcher will upload the file. Then we can get access to information about the file from MultiPartRequestWrapper.
MultiPartRequestWrapper multiWrapper = (MultiPartRequestWrapper) ServletActionContext.getRequest();
The first thing you should always do is check for errors. If there were any, there's no point in continuing, most methods will return null. Unfortunately, currently there is no easy way to distinguish what error occured making it more difficult to route to different error pages.
if (multiWrapper.hasErrors()) { Collection errors = multiWrapper.getErrors(); Iterator i = errors.iterator(); while (i.hasNext()) { addActionError((String) i.next()); } return ERROR; }
Now get the input tag name for the uploaded file and use that to get information on the transfer. Since you can upload multiple files (just add multiple input tags) at a time getFileNames returns an Enumeration of the names.
Enumeration e = multiWrapper.getFileNames(); while (e.hasMoreElements()) { // get the value of this input tag String inputValue = (String) e.nextElement(); // get the content type String contentType = multiWrapper.getContentType(inputValue); // get the name of the file from the input tag String fileName = multiWrapper.getFilesystemName(inputValue); // Get a File object for the uploaded File File file = multiWrapper.getFile(inputValue); // If it's null the upload failed if (file == null) { addActionError("Error uploading: " + multiWrapper.getFilesystemName(inputValue)); } // Do additional processing/logging... }
Code above may be packed into one nice reusable component (Interceptor) that handles 90% of all typical file upload tasks. And Action does not know anything about web-app and just gets its files. Neat.
For more, see the File Upload Interceptor