Struts 2 Annotation File Upload Example: Single and Multiple
August 10, 2014
Struts 2 provides efficient way to support file uploads. There are tag library to write view in JSP. Errors can be displayed on UI which is required by the user. Struts 2 provides interceptor to apply required constraints for file upload. We can restrict user to upload certain content types, certain file extensions and maximum size of files. In our example, we are not using strut.xml, we are using annotation to give demo. In this example we will see multiple and single file upload. First we are describing how to do multiple file upload and then we will see how to do single file upload.
Required Software to Run Example
To run the example, we need software as below.1. JDK 6
2. Eclipse
3. Tomcat 7
4. Maven
Project Structure in Eclipse
Before starting the code walk through, it is beneficiary that first check all the files and their location in project structure. We are not using struts.xml. We are performing our file upload task annotation based.File Upload Interceptor : @interceptorRef Annotation
In file upload, we need to apply some constraints. Struts 2 provides below parameters using which we can set constraints on file upload individually.maximumSize: Sets maximum size (in bytes) which is allowed by interceptor.
allowedTypes: The value for this parameter can be comma separated content types.
allowedExtensions: The value can be comma separated extensions.
Uisng @interceptorRef we can set parameter values as below.
@InterceptorRef( params={"allowedTypes","image/jpeg,application/zip","maximumSize","1000000"}, value="fileUpload" )
Write Page for Multiple File Upload and Success Message
Struts 2 provides tag library to write views in jsp. Find the JSP how to write code for multiple file upload. We need to take care that name attribute must be same for all File tag.multiUpload.jsp
<%@ taglib prefix="s" uri="/struts-tags" %> <html> <body> <h1> Struts 2 File Upload Example </h1> <s:form method="post" enctype="multipart/form-data" action="multiUploadFile"> <s:file label="File One" name="uploads" /> <s:file label="File Two" name="uploads" /> <s:file label="FIle Three" name="uploads" /> <s:submit /> </s:form> </body> </html>
success.jsp
<%@ taglib prefix="s" uri="/struts-tags" %> <html> <body> You have successfully uploaded the files<br/> <s:property value="desc"/> </body> </html>
How to Define File Parameter in Struts 2 Action Class for Multiple Upload
Before writing action class we must understand what convention we must follow to get uploaded file values. Struts 2 interceptor automatically defines the properties which we should use in our action class to fetch the uploaded File.[File Name] : File: java.io.File type object that provides uploaded file data as byte stream.
[File Name]FileName: File name of the File which has been uploaded.
[File Name]ContentType: Content type of File which has been uploaded.
In multiUpload.jsp, file name is "uploads" and we are doing multiple file upload. So we will create List for the property and name in action class will be as below
private List<File> uploads = new ArrayList<File>(); private List<String> uploadsFileName = new ArrayList<String>(); private List<String> uploadsContentType = new ArrayList<String>();
Multiple File Upload Action Class
Now find the action class. We have created a method that will be called when file uploaded page will be submitted. Finally we will save all the uploaded files in a location.FileUploadAction.java
package com.concretepage.action; import java.io.File; import java.io.FileInputStream; import java.io.FileOutputStream; import java.io.IOException; import java.util.ArrayList; import java.util.List; import org.apache.struts2.convention.annotation.Action; import org.apache.struts2.convention.annotation.InterceptorRef; import org.apache.struts2.convention.annotation.Namespace; import org.apache.struts2.convention.annotation.Result; import org.apache.struts2.convention.annotation.ResultPath; import com.opensymphony.xwork2.ActionSupport; @Namespace("/upload") @ResultPath(value="/upload/") public class FileUploadAction extends ActionSupport{ private static final long serialVersionUID = 1L; private List<File> uploads = new ArrayList<File>(); private List<String> uploadsFileName = new ArrayList<String>(); private List<String> uploadsContentType = new ArrayList<String>(); private String desc=""; @Action( value = "/multiUploadFile", results={@Result(name="success",location="success.jsp"), @Result(name="input",location="error.jsp") }, interceptorRefs={ @InterceptorRef( params={"allowedTypes","image/jpeg,application/zip", "maximumSize","1000000"}, value="fileUpload" ), @InterceptorRef("defaultStack"), @InterceptorRef("validation") } ) public String multiUploadFile() { int i=0; for(File file : uploads){ try { FileInputStream fis = new FileInputStream(file); String fileName = uploadsFileName.get(i); String contentType = uploadsContentType.get(i); System.out.println(contentType); FileOutputStream fos = new FileOutputStream("D:/cp/"+fileName); byte[] b = new byte[1024]; while(fis.read(b) != -1){ fos.write(b); } desc += fileName +", "; fos.close(); fis.close(); } catch (IOException e) { e.printStackTrace(); } i++; } return SUCCESS; } public List<File> getUploads() { return uploads; } public void setUploads(List<File> uploads) { this.uploads = uploads; } public List<String> getUploadsFileName() { return uploadsFileName; } public void setUploadsFileName(List<String> uploadsFileName) { this.uploadsFileName = uploadsFileName; } public List<String> getUploadsContentType() { return uploadsContentType; } public void setUploadsContentType(List<String> uploadsContentType) { this.uploadsContentType = uploadsContentType; } public String getDesc() { return desc; } public void setDesc(String desc) { this.desc = desc; } }
Display Error in Struts 2 File Upload : Use <s:fielderror/>
If upload fails, because of file validation like size, content type or extension, the we can catch error. Define input result in action annotation.@Result(name="input",location="error.jsp")
and use <s:fielderror/> in error.jsp as below.
error.jsp
<%@ taglib prefix="s" uri="/struts-tags" %> <html> <body> <s:fielderror/> </body> </html>
Struts 2 web.xml
Find the web.xml which we are using in the demo.web.xml
<web-app> <display-name>Struts 2 File Upload Annotation Example</display-name> <filter> <filter-name>struts2</filter-name> <filter-class>org.apache.struts2.dispatcher.ng.filter.StrutsPrepareAndExecuteFilter</filter-class> <init-param> <param-name>actionPackages</param-name> <param-value>com.concretepage.action</param-value> </init-param> </filter> <filter-mapping> <filter-name>struts2</filter-name> <url-pattern>/*</url-pattern> </filter-mapping> </web-app>
Maven Dependency
Find the maven dependency for struts 2 Jar.pom.xml
<dependencies> <dependency> <groupId>org.apache.struts</groupId> <artifactId>struts2-core</artifactId> <version>2.3.16</version> </dependency> <dependency> <groupId>org.apache.struts</groupId> <artifactId>struts2-convention-plugin</artifactId> <version>2.3.8</version> </dependency> </dependencies>
Output of File Upload Example
This is Upload page with multiple file upload option.Struts 2 Single File Upload
For single file upload there are minor changes. Jsp will like<s:form method="post" enctype="multipart/form-data" action="singleUploadFile"> <s:file label="File One" name="upload" /> <s:submit /> </s:form>
private File upload; private String uploadsFileName; private String uploadsContentType;