Home > Tech stuff > struts2 download file

struts2 download file

Here’s a scenario:
1. User select a directory, and you show him all the files in that directory as ‘downloadable’
2. User select a file to download and gets it.

First, you need to write a Action class, that sends back a list of files in that directory.

public class MyAction extends ActionSupport{

	private List FilesList;
        public List getFilesList() {
		return FilesList;
	}

	public void setFilesList(List FilesList) {
		this.FilesList = FilesList;
	}
        
        public String files() throws Exception {
		String dirPath = (String) getGlobal(Constants.DIRPATH);
		File dir = new File(dirPath);

		ArrayList filesList = new ArrayList();
		String[] children = dir.list();
		if (children == null) {
			// Either dir does not exist or is not a directory
		} else {
			for (int i = 0; i < children.length; i++) {
				// Get filename of file or directory
				String filename = children[i];
				File file = new File(dirPath + File.separator + filename);
				Files files= new Files();
				files.setFileSize(readableFileSize(file.length()));
				files.setFileName(filename);
				filesList.add(files);
			}
		}

		setFilesList(filesList);
		return Constants.SUCCESS;
	}
}

Your JSP needs to have this listing:

<%@ page language="java" contentType="text/html; charset=ISO-8859-1"
	pageEncoding="ISO-8859-1"%>
<%@ taglib prefix="s" uri="/struts-tags"%>

<s:if test="%{filesList!=null && filesList.size > 0}">
    <table border=0 cellspacing=1 cellpadding=1 width=60% align=center	class=tablebody>
	<s:iterator value="filesList" status="rownum">
	    <tr height=25>
		<td align=left style='font-family: verdana; font-size: 11pt' nowrap>
                    <s:url id="fileDownload" action="download">
			<s:param name="downloadFileName" value="{fileName}" />
		    </s:url> 
                    <s:a href="%{fileDownload}"><s:property value="fileName" /></s:a> 
                    <span style="font-family: verdana; font-size: 9pt"><s:property value="fileSize" /></span>
                </td>
	    </tr>
	</s:iterator>
</table>
</s:if>
<s:else test="%{filesList!=null && filesList.size == 0}">
			No files found
</s:else>

Couple of interesting things in the struts tags above:

<s:url id="fileDownload" action="download">
	<s:param name="downloadFileName" value="{fileName}" />
</s:url> 
<s:a href="%{fileDownload}"><s:property value="fileName" /></s:a> 

This specifying a URL with the parameter as the selected filename. If you want to see the filename being apprended to the URL,You can specify includeParams="get" to s:url.

Now, lets map the ‘download’ action in 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="basicstruts2" extends="struts-default">

		<interceptors>
			<interceptor-stack name="appDefaultStack">
				<interceptor-ref name="defaultStack">
					<param name="exception.logEnabled">true</param>
					<param name="exception.logLevel">ERROR</param>
				</interceptor-ref>
			</interceptor-stack>
		</interceptors>

		<default-interceptor-ref name="appDefaultStack" />

		<default-action-ref name="input" />

		<global-results>
			<result name="error">/error.jsp</result>
		</global-results>

		<global-exception-mappings>
			<exception-mapping exception="java.lang.Exception"
				result="error" />
		</global-exception-mappings>



		<action name="input"
			class="com......"
			method="prepare">
			<result name="success">/....jsp</result>
		</action>

		<action name="*Filter"
			class="com......"
			method="{1}">
			<result name="success">/.....jsp</result>
			<result name="error">/error.jsp</result>
			<result name="input">/mdt_viewer.jsp</result>
		</action>

		
		<action name="download" class="com.action.DownloadAction"
			method="download">
			<result name="success" type="stream">
				<param name="contentType">application/zip</param>
				<param name="inputName">fileInputStream</param>
				<!--param name="contentDisposition">attachment;filename="fileABC.txt"</param -->
				<param name="bufferSize">1024</param>
			</result>
		</action>
	</package>

</struts>

Lets check out the DownloadAction class,

public class DownloadAction extends ActionSupport{
	private InputStream fileInputStream;
	private String downloadFileName;

        /**
	 * Will override the default in struts.xml. 
	 * 
	 * @return
	 */
	public String getContentDisposition() {
		return "attachment;filename=" + getDownloadFileName();
	}

       
        	public InputStream getFileInputStream() {
		return fileInputStream;
	}

	public void setFileInputStream(InputStream fileInputStream) {
		this.fileInputStream = fileInputStream;
	}

	public String getDownloadFileName() {
		return downloadFileName;
	}

	public void setDownloadFileName(String downloadFileName) {
		this.downloadFileName = downloadFileName;
	}


        public String download() throws Exception {
		log.debug("Fetching for download:" + getDownloadFileName());
		String filesPath = (String) getGlobal(Constants.DIR_PATH);

		try {
			String file = filesPath 
					+ File.separator + getDownloadFileName();
			setFileInputStream(new FileInputStream(file));
			return Constants.SUCCESS;
		} catch (Exception e) {
			log.error(e);
			throw e;
		}
	}
}

Thats about it! Happy downloading.

  1. No comments yet.
  1. No trackbacks yet.

Leave a comment