This tutorial will help you understanding how to create a Strust action class that allows users to download files from server to their local computer. Typically, the users will click on hyperlinks in a web page, and the server will dynamically pick up the requested files (either from file system or from database) and send them to the user for downloading.

The following diagram describes workflow of the file download functionality implemented in Struts:

Struts2 download file workflow

Struts provides a custom result type called “stream” that performs file download by “streaming” an InputStream of a file to the client through the HttpServletResponse. Here’s an example that shows how to define this result type inside an <action> element in struts.xml:

<result name="success" type="stream">
  <param name="contentType">application/octet-stream</param>
  <param name="inputName">inputStream</param>
  <param name="contentDisposition">attachment;filename="project.zip"</param>
  <param name="bufferSize">4096</param>
</result>

As we can see, unlike regular result types which map view names to JSP pages, this stream result type needs some parameters to control the file download. The following table lists all the available parameters:

Parameter name

Meaning

Default value

contentType

Sets content MIME type for the response header.

text/plain

contentLength

Sets content length for the response header.

 

contentDisposition

Sets content disposition for the response header.

inline

inputName

Specifies name of the InputStream which must be defined in the action class.

inputStream

bufferSize

Specifies size of the buffer (in bytes) used for copying data from input stream to output stream.

1024

allowCaching

Enables or disables caching (by setting “Pragma” and “Cache-Control” attribute of the response header.

true

contentCharSet

Specifies character set for the content by adding “;charset=value” to the Content-Type header.

 

 

Most of these parameters are to set equivalent HTTP headers of the response, except the inputStream and bufferSize, and the last two parameters, allowCaching and contentCharSet are rarely used. Beside specifying fixed values for these parameters in struts.xml file, it’s possible to override these parameters in the action class. For example, the contentLength parameter should not be fixed, because it varies from file to file. Here’s an example of the download action class that overrides the contentLength parameter and sets its value dynamically:

public class DownloadFileAction extends ActionSupport {

	private InputStream inputStream;

	// getter for the inputStream
	
	private long contentLength;
	
	public long getContentLength() {
		return contentLength;
	}	

	public String execute() throws FileNotFoundException {
			
		File fileToDownload = new File("C:/path/to/the/file.zip");
		inputStream = new FileInputStream(fileToDownload);

		contentLength = fileToDownload.length();
		

		return SUCCESS;
	}
}

Remember that, in the action class we must define an InputStreamobject which has the same name as the name specified by the inputName parameter. All the variables must have appropriate getter methods.

Similarly, the file name specified in the contentDisposition parameter should be also dynamic. To do so, declare this parameter as follows:

<param name="contentDisposition">attachment;filename="${fileName}"</param>

Note that we declare a property placeholder called “fileName” which will be dynamically updated by Struts. Now in the action class, declare a variable with the same name along with its getter method as follows:

public class DownloadFileAction extends ActionSupport {

	// input stream object and its getter method
	
	
	
	private String fileName;
	

	public String getFileName() {
		return fileName;
	}

	public String execute() throws FileNotFoundException {
				
		File fileToDownload = new File("C:/path/to/the/file.zip");

		fileName = fileToDownload.getName();

		
		return SUCCESS;
	}
}

Okay, that’s enough for the configuration of stream result type. Let’s see a complete sample application now.

The application consists of the following files:

    • Download.jsp: simply displays a hyperlink on which the users click to download the file.
    • DownloadFileAction.java: implements code to send a file on the server to the client for downloading.
    • struts.xml: configures the download action class and parameters for the stream result type.
    • web.xml: configures Struts2 dispatcher filter.

And following is source code of each file:

 

1. Code of the download page (JSP)

<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" 
	"http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>Download File</title>
</head>
<body>
	<h1 align="center">Struts2 File Download Demo</h1>
	<h3 align="center">
		<a href="/downloadFile">Download this file</a>
	</h3>	
</body>
</html>

This page has a hyperlink that points to relative URL of the Struts action.

 

2. Code of the Struts Action class 

package net.codejava.struts;

import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.InputStream;

import com.opensymphony.xwork2.ActionSupport;

public class DownloadFileAction extends ActionSupport {

	private InputStream inputStream;
	private String fileName;
	private long contentLength;

	public String execute() throws FileNotFoundException {
		
		File fileToDownload = new File("E:/Download/struts-2.3.12-src.zip");

		inputStream = new FileInputStream(fileToDownload);
		fileName = fileToDownload.getName();
		contentLength = fileToDownload.length();
		
		return SUCCESS;
	}
	
	public long getContentLength() {
		return contentLength;
	}

	public String getFileName() {
		return fileName;
	}

	public InputStream getInputStream() {
		return inputStream;
	}	
}

The execute() method of this action class picks a file from an absolute path and put it into the input stream. The file name and content length (file size) are also set accordingly.

 

3. Code of the Struts configuration file (struts.xml)

<?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>
	<package name="Struts2FileDownload" extends="struts-default">
		
		<action name="downloadFile" class="net.codejava.struts.DownloadFileAction">
			<result name="success" type="stream">
				<param name="contentType">application/octet-stream</param>
				<param name="inputName">inputStream</param>
				<param name="contentDisposition">attachment;filename="${fileName}"</param>
				<param name="bufferSize">4096</param>
			</result>
		</action>
		
	</package>
</struts>

Note that in this configuration we fix the contentTypeto application/octet-stream which means binary type. In your application, you may override this parameter in the action class to return content type that exactly matches your file type.

 

4. Code of the web deployment descriptor file (web.xml) 

<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
	xmlns="http://java.sun.com/xml/ns/javaee" 
	xmlns:web="http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd" 
	xsi:schemaLocation="http://java.sun.com/xml/ns/javaee 
		http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd" 
	id="WebApp_ID" version="3.0">
  <display-name>Struts2FileDownload</display-name>

	<filter>
	  <filter-name>struts2</filter-name>
	  <filter-class>
	  	org.apache.struts2.dispatcher.ng.filter.StrutsPrepareAndExecuteFilter
	  </filter-class>
	</filter>
	
	<filter-mapping>
	  <filter-name>struts2</filter-name>
	   <url-pattern>/*</url-pattern>
	</filter-mapping>
	
</web-app>

 

5. Required libraries

At least, the following jar files are required to run this application:

    • commons-fileupload-1.2.2.jar
    • commons-io-2.0.1.jar
    • commons-lang3-3.1.jar
    • commons-logging-1.1.1.jar
    • commons-logging-api-1.1.jar
    • freemarker-2.3.19.jar
    • javassist-3.11.0.GA.jar
    • ognl-3.0.6.jar
    • struts2-core-2.3.14.2.jar
    • xwork-core-2.3.14.2.jar


6. Test the Struts File download application

Suppose the application is deployed on local Tomcat under context path /Struts2FileDownload, type the following URL in browser:

http://localhost:8080/Struts2FileDownload/Download.jsp

The download page would appear as follows:

test Struts2 download page

Click on the link “Download this file”, the browser will automatically download the file, or ask for download (Firefox):

Firefox asks for file download

Depending on the value you set for the contentType parameter, the browser behaves differently. For example, if the contentType is set to image/jpeg then the browser will display the image.

You can download an Eclipse-based project of this application in the attachments section.

 

Related Java File Download Tutorials:

 

Other Struts Tutorials:


About the Author:

is certified Java programmer (SCJP and SCWCD). He began programming with Java back in the days of Java 1.4 and has been passionate about it ever since. You can connect with him on Facebook and watch his Java videos on YouTube.



Attachments:
Download this file (Struts2FileDownload.zip)Struts2FileDownload.zip[Eclipse project]3433 kB

Add comment

   


Comments 

#5ERP2023-09-05 05:28
Testing needs to be compleletd
Quote
#4Lily2020-03-17 09:41
This is a great example!! Thank you so much for sharing this.
Quote
#3subhash2018-07-09 00:43
this article is useful for creating the downloading of the files.
Quote
#2sachin2018-06-26 07:43
nice tutorial and the way it is explain is very well
Quote
#1enrique marmolejo2014-12-19 16:15
very useful example, thanks!
Quote