The Struts 2 framework provides built-in support for processing file uploads that conform to RFC 1867, "Form-based File Upload in HTML". When correctly configured the framework will pass uploaded file(s) into your Action class. Support for individual and multiple file uploads are provided. When a file is uploaded it will typically be stored in a temporary directory. Uploaded files should be processed or moved by your Action class to ensure the data is not lost. Be aware that servers may have a security policy in place that prohibits you from writing to directories other than the temporary directory and the directories that belong to your web application.
Table of Contents | ||
---|---|---|
|
Dependencies
The Struts 2 framework leverages add-on libraries to handle the parsing of uploaded files. These libraries are not included in the Struts distribution, you must add them into your project. The libraries needed are:
...
Code Block | ||||
---|---|---|---|---|
| ||||
<dependency>
<groupId>commons-fileupload</groupId>
<artifactId>commons-fileupload</artifactId>
<version>1.1.1</version>
</dependency>
<dependency>
<groupId>commons-io</groupId>
<artifactId>commons-io</artifactId>
<version>1.0</version>
</dependency>
|
Code Block | ||||
---|---|---|---|---|
| ||||
<dependency>
<groupId>commons-fileupload</groupId>
<artifactId>commons-fileupload</artifactId>
<version>1.2.1</version>
</dependency>
<dependency>
<groupId>commons-io</groupId>
<artifactId>commons-io</artifactId>
<version>1.3.2</version>
</dependency>
|
...
Example action mapping:
Code Block | ||
---|---|---|
| ||
<action name="doUpload" class="com.example.UploadAction">
<result name="success">good_result.jsp</result>
</action>
|
...
Example Action class:
Code Block | ||
---|---|---|
| ||
package com.example;
import java.io.File;
import com.opensymphony.xwork2.ActionSupport;
public class UploadAction extends ActionSupport {
private File file;
private String contentType;
private String filename;
public void setUpload(File file) {
this.file = file;
}
public void setUploadContentType(String contentType) {
this.contentType = contentType;
}
public void setUploadFileName(String filename) {
this.filename = filename;
}
public String execute() {
//...
return SUCCESS;
}
}
|
...
The Struts 2 default.properties
file defines several settings that affect the behavior of file uploading. You may find in necessary to change these values. The names and default values are:
Code Block | ||
---|---|---|
| ||
struts.multipart.parser=jakarta
struts.multipart.saveDir=
struts.multipart.maxSize=2097152
|
...
In order to change theses settings you define a constant in your applications struts.xml
file like so:
Code Block | ||
---|---|---|
| ||
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE struts PUBLIC
"-//Apache Software Foundation//DTD Struts Configuration 2.0//EN"
"http://struts.apache.org/dtds/struts-2.0.dtd">
<struts>
<constant name="struts.multipart.maxSize" value="1000000" />
...
</struts>
|
Additionally the fileUpload
interceptor has settings that can be put in place for individual action mappings by customizing your interceptor stack.
Code Block | ||
---|---|---|
| ||
<action name="doUpload" class="com.example.UploadAction">
<interceptor-ref name="basicStack"/>
<interceptor-ref name="fileUpload">
<param name="allowedTypes">text/plain</param>
</interceptor-ref>
<interceptor-ref name="validation"/>
<interceptor-ref name="workflow"/>
<result name="success">good_result.jsp</result>
</action>
|
...
There are two separate file size limits. First is struts.multipart.maxSize
which comes from the Struts 2 default.properties
file. This setting exists for security reasons to prohibit a malicious user from uploading extremely large files to file up your servers disk space. This setting defaults to approximately 2 megabytes and should be adjusted to the maximum size file (2 gigs max) that your will need the framework to receive. If you are uploading more than one file on a form the struts.multipart.maxSize
applies to the combined total, not the individual file sizes. The other setting, maximumSize
, is an interceptor setting that is used to ensure a particular Action does not receive a file that is too large. Notice the locations of both settings in the following example:
Code Block | ||
---|---|---|
| ||
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE struts PUBLIC
"-//Apache Software Foundation//DTD Struts Configuration 2.0//EN"
"http://struts.apache.org/dtds/struts-2.0.dtd">
<struts>
<constant name="struts.multipart.maxSize" value="1000000" />
<action name="doUpload" class="com.example.UploadAction">
<interceptor-ref name="basicStack"/>
<interceptor-ref name="fileUpload">
<param name="maximumSize">500000</param>
</interceptor-ref>
<interceptor-ref name="validation"/>
<interceptor-ref name="workflow"/>
<result name="success">good_result.jsp</result>
</action>
</struts>
|
...
There are two ways to limit the uploaded file type, declaratively and programmatically. To declaratively limit the file type a comma separated list of allowedTypes can be specified as a fileUpload interceptor param as shown in the following example:
Code Block | ||
---|---|---|
| ||
<action name="doUpload" class="com.example.UploadAction">
<interceptor-ref name="basicStack"/>
<interceptor-ref name="fileUpload">
<param name="allowedTypes">image/jpeg,image/gif</param>
</interceptor-ref>
<interceptor-ref name="validation"/>
<interceptor-ref name="workflow"/>
<result name="success">good_result.jsp</result>
</action>
|
...
The struts.multipart.parser
used by the fileUpload interceptor to handle HTTP POST requests, encoded using the MIME-type multipart/form-data, can be changed out. Currently there are two choices, jakarta and pell. The jakarta parser is a standard part of the Struts 2 framework needing only its required libraries added to a project. The pell parser uses Jason Pell's multipart parser instead of the Commons-FileUpload library. The pell parser is a Struts 2 plugin, for more details see: http://cwiki.apache.org/S2PLUGINS/pell-multipart-plugin.html. There was a third alternative, cos, but it was removed due to licensing incompatibilities.
As from Struts version 2.3.18 a new implementation of MultiPartRequest
was added - JakartaStreamMultiPartRequest
. It can be used to handle large files, see WW-3025 for more details, but you can simple set
<constant name="struts.multipart.parser" value="jakarta-stream" />
in struts.xml to start using it.