Struts 2 download file example

A Struts 2 example to show the use of custom result type to allow user to download file.

1. Action

In Action class, declared an InputStream data type and its getter method.

DownloadAction.java

package com.mkyong.common.action;
 
import java.io.File;
import java.io.FileInputStream;
import java.io.InputStream;
import com.opensymphony.xwork2.ActionSupport;
 
public class DownloadAction extends ActionSupport{
 
	private InputStream fileInputStream;
 
	public InputStream getFileInputStream() {
		return fileInputStream;
	}
 
	public String execute() throws Exception {
	    fileInputStream = new FileInputStream(new File("C:\\downloadfile.txt"));
	    return SUCCESS;
	}
}

2. View page

A normal page, with a download link to download a file.

downloadPage.jsp

<%@ taglib prefix="s" uri="/struts-tags" %>
<html>
 
<body>
<h1>Struts 2 download file example</h1>
 
<s:url id="fileDownload" namespace="/" action="download" ></s:url>
 
<h2>Download file - <s:a href="%{fileDownload}">fileABC.txt</s:a>
</h2>
 
</body>
</html>

3. struts.xml

Define the download file detail, self-explanatory. The <param name=”inputName”> value is the name of the InputStream property from the Action.

Read this Struts 2 Stream Result documentation for more detail explanation.

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>
 
<constant name="struts.devMode" value="true" />
 
<package name="default" namespace="/" extends="struts-default">
   <action name="">
	<result name="success">pages/downloadPage.jsp</result>
   </action>
 
   <action name="download" class="com.mkyong.common.action.DownloadAction">
	<result name="success" type="stream">
	  <param name="contentType">application/octet-stream</param>
	  <param name="inputName">fileInputStream</param>
	  <param name="contentDisposition">attachment;filename="fileABC.txt"</param>
	  <param name="bufferSize">1024</param>
	</result>
   </action>
</package>
 
</struts>

4. Run it

http://localhost:8080/Struts2Example/

Struts2 download file example

Reference

  1. http://struts.apache.org/2.x/docs/stream-result.html
  2. http://www.iana.org/assignments/media-types/
  3. http://www.mkyong.com/struts/struts-download-file-from-website-example/
  4. http://www.mkyong.com/java/how-to-download-file-from-website-java-jsp/
  5. http://struts.apache.org/2.x/docs/how-can-we-return-a-text-string-as-the-response.html
Tags :

About the Author

mkyong
Founder of Mkyong.com and HostingCompass.com, love Java and open source stuff. Follow him on Twitter, or befriend him on Facebook or Google Plus. If you like my tutorials, consider make a donation to these charities.

Comments

  • Palanirajan

    Hi,

    your all examples are very helpful..
    it’s possible redirect page once streaming done? and how to handle the exception during download process in struts 2?

    Thanks in advance

  • Vrushali

    Good one, Worked for me….

  • http://none victor

    Debo reconocer que me ayudo mucho tu codigo, muchas gracias……

  • anand

    is it possible to make the downloadable file dynamic? In the xml we give the name of the file, can it be passed through action to the xml?

    • anand

      did it using getter in the action class.

      public String getContentDisposition() {
      return contentDisposition;
      }

      contentDisposition = “attachment;filename=\”IMG_1448.JPG\””;

  • anand

    all the questions I had today are answered by you.

  • manu

    Hi
    if i use the same program for display by changing the content type, i cant resize the image.
    can u tell me how to view all the images in a folder and resize them to my requirements.

  • http://þÿ Gema Luhring

    A person necessarily help to make severely articles I might state. This is the very first time I frequented your web page and so far? I amazed with the analysis you made to make this particular post extraordinary. Wonderful job!

  • Dipak C

    Hi,
    I am getting following error. Please help

    my java action

    File tempfile=File.createTempFile(&quot;testfile&quot;, &quot;.xls&quot;);
    						FileOutputStream xlsStream = new FileOutputStream(tempfile);
    						if(Constants.DEBUG) System.out.println(&quot;tempfile:&quot;+tempfile.getAbsolutePath());
    					Json2Excel.build(xlsStream, json, 
    							colStr.split(&quot;,&quot;), 
    							colStr.split(&quot;,&quot;) 
    		            		);
     
    		            	//  bos.close();
    		            	  xlsStream.close();
     
     
    		            	  fileInputStream =new FileInputStream(tempfile);
    return &quot;export&quot;;

    NOTE: check manually that file is created with the required data at temp location.

    My struts result xml

     &lt;action name=&quot;lectureAttendanceListJson&quot; class=&quot;com.cypruss.elearning.webapp.action.ReportsAction&quot; method=&quot;lectureAttendanceListJson&quot;&gt;
               &lt;result name=&quot;success&quot; type=&quot;json&quot;&gt;  
                    &lt;param name=&quot;ignoreHierarchy&quot;&gt;false&lt;/param&gt;  
                    &lt;param name=&quot;excludeNullProperties&quot;&gt;false&lt;/param&gt;  
           		&lt;/result&gt; 
           	 &lt;result name=&quot;export&quot; type=&quot;stream&quot;&gt;
    		  &lt;param name=&quot;contentType&quot;&gt;application/octet-stream&lt;/param&gt;
    		  &lt;param name=&quot;inputName&quot;&gt;fileInputStream&lt;/param&gt;
    		  &lt;param name=&quot;contentDisposition&quot;&gt;attachment;filename=&quot;testjqgrid.xls&quot;&lt;/param&gt;
    		  &lt;param name=&quot;bufferSize&quot;&gt;1024&lt;/param&gt;
    		&lt;/result&gt;
            &lt;/action&gt;

    my HTML Javascript calling the action as Ajax

    function exportData( griddata)
    		    {
     
    		    	//var params = $.toJSON(this.p.postData);
    		    	$.ajax({
    		    	type:&quot;GET&quot;
    		    	,url: 'lectureAttendanceListJson.html'
    		    	,data:'export=xls'
    		    	,cache:false
    		    	,success: function(data,status) {
    		    		if($(&quot;#iframeX&quot;)) $(&quot;#iframeX&quot;).remove();
    		    		alert(data);
    		    		  var elemIF = document.createElement(&quot;iframe&quot;);
    		    		  elemIF.src = data;
    		    		  elemIF.id = &quot;iframeX&quot;;
    		    		  elemIF.style.display = &quot;none&quot;;
    		    		  document.body.appendChild(elemIF); 
     
    		    	}
    		    	,error:function (xhr, ajaxOptions, thrownError){
    		    	alert(xhr.status);
    		    	alert(xhr.statusText);
    		    	alert(thrownError);
    		    	}
    		    	,complete: function (XMLHttpRequest, textStatus) {
    		    	 var headers = XMLHttpRequest.getAllResponseHeaders();
    		    	}
    		    	,beforeSend: function(xhr){
    		    	//xhr.setRequestHeader('Accept', 'text/html');
    		    	//xhr.setRequestHeader('Access-Control-Allow-Origin', '*');
    		    	//xhr.setRequestHeader('Access-Control-Allow-Methods', 'POST');
    		    	}
    		    	}
    		    	);
    		    }

    NOTE: line ‘alert(data);’ in javascript show the response in alert box, which is xls file. but it not showing download file dialog.
    and in Eclipse console shows the following error.. Please Help

    error Console:

    tempfile:C:\DOCUME~1\dipak\LOCALS~1\Temp\testfile5760271600544776200.xls
    2012-04-17 08:29:41.492::WARN: EXCEPTION
    java.io.IOException: The filename, directory name, or volume label syntax is incorrect
    at java.io.WinNTFileSystem.canonicalize0(Native Method)
    at java.io.Win32FileSystem.canonicalize(Win32FileSystem.java:396)
    at java.io.File.getCanonicalPath(File.java:559)
    at org.mortbay.resource.FileResource.getAlias(FileResource.java:189)
    at org.mortbay.jetty.servlet.DefaultServlet.getResource(DefaultServlet.java:286)
    at org.mortbay.jetty.servlet.DefaultServlet.doGet(DefaultServlet.java:356)
    at javax.servlet.http.HttpServlet.service(HttpServlet.java:707)
    at javax.servlet.http.HttpServlet.service(HttpServlet.java:820)
    at org.mortbay.jetty.servlet.ServletHolder.handle(ServletHolder.java:487)
    at org.mortbay.jetty.servlet.ServletHandler$CachedChain.doFilter(ServletHandler.java:1093)
    at com.cypruss.webapp.filter.SessionFilter.doFilter(SessionFilter.java:60)
    at org.mortbay.jetty.servlet.ServletHandler$CachedChain.doFilter(ServletHandler.java:1084)
    at org.apache.struts2.dispatcher.ng.filter.StrutsExecuteFilter.doFilter(StrutsExecuteFilter.java:85)
    at org.mortbay.jetty.servlet.ServletHandler$CachedChain.doFilter(ServletHandler.java:1084)
    at com.cypruss.webapp.filter.StaticFilter.doFilterInternal(StaticFilter.java:107)
    at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:76)
    at org.mortbay.jetty.servlet.ServletHandler$CachedChain.doFilter(ServletHandler.java:1084)
    at com.opensymphony.sitemesh.webapp.SiteMeshFilter.obtainContent(SiteMeshFilter.java:129)
    …..

  • http://trigent.com anudeep

    Hi,

    with the above example , how do we close the fileInputStream opened during the response.

    we are not closing the fileInputStream here , this will create problems . fileInputStream holds the lock to the file untill the next download of different file is rquested or the any other strem opens this file .
    also we cannot delete the file .

    • http://www.mkyong.com mkyong

      Is this caused locked at your end? Struts2 should handle it automatically.

      • http://trigent.com anudeep

        will the strus2 release the fileInputStream instance once the streaming is done?

  • Pingback: Struts2 Jasper Rerports Plugin « Track 4 J()