Struts 2 File Download

Posted by Whitestripes9805 on Mon, 06 May 2019 06:05:02 +0200

1. File download path problem, when the project runs MyEclipse will load the project under Tomcat's webapps directory. So, about the path problem (we must set up relative road strength)

 

2. Relative paths are needed to download to the local server. It's better to use absolute path to upload to client

3. There must be a lot of packages needed to upload files.

 

1. Struts 2 support for file download

Struts 2 supports file downloading through the result type of org.apache.slruts2.dispatcher.Stream ResuIt.

It makes it easier to download programs that are easy to write.

StreamResuIt result type uses the ServletOutputStrcam object returned by the HttpServletResponse object
Output the binary data of the download file to the client, which has the following parameters:

 

  1. contentType
    The MIME type of the data stream sent to the Web browser (text/plain by default) is the content type of the downloaded file.
    When the client requests static resources from Tomcat, Tomcat automatically adds the "Content-Type" attribute to the Response Head and configures the list of specific attributes.
  2. contentLength
    The length of the data stream in bytes (the browser displays a progress bar), that is, the length of the downloaded file
  3. contentDisposition:
    This property configures the file name and other attributes of the download file, in which the file type is divided into inline and attachment:
    1. inline: The browser tries to open the file directly (default value)
    2. atachment: Browsers download directly as attachments
    It's not absolute either. This is true for downloads that browsers can display. For downloads that browsers don't support, even if inline selection is used.
    Items will still pop up the File Download dialog box. The default value for contentDispostion is inline.
     

  4. inputName
    The name of the attribute used to download a file in Action, which is of type InputStream. The default recognition is inputStream
     

    inputName: Used to specify the input stream entry for downloading files, which needs to be specified in Action. That is to say, action is required to define the corresponding attribute type InputStream. The default is inputStream.

    If the getInputStream() method is declared in Action, it is configured in the configuration file struts.xml as <param name="inputName">inputStream</param>.

    If the getTargetFile() method is declared in Action, the configuration file struts.xml is configured as <param name="inputName">targetFile </param>.

  5. bufferSize
    File data is copied from input to output buffer size, default 1024 bytes
  6. allowCaching
    Is caching allowed

The StreamResult result type has been defined in the struts-default file with the logical name stream.

<result name="success" type="stream">
				<param name="contentType">text/plain</param>
				<param name="inputName">inputStream</param>
                //The filename here is the name of the file to be downloaded.
				<param name="contentDisposition">attachment;filename="hello.txt"</param>
				<param name="bufferSize">1024</param>
			</result>


Attention

2. cases

  <body>
	<s:debug/>
	<s:a href="download?fileName=a.txt">download One way</s:a>
	<a href="download?fileName=a.txt">down Mode two</a>
  </body>
public class DownloadAction extends ActionSupport {

	private String fileName;

	public InputStream getInputStream() throws IOException {
		String path = ServletActionContext.getServletContext().getRealPath(fileName);
		/**
		 * Method 1 File file = new File (path); return new File InputStream (file);
		 * Method 2 FileUtils.openInputStream(file);
		 */
		File file = new File(path);
		return FileUtils.openInputStream(file);

	}

	public String getFileName() {
		return fileName;
	}

	public void setFileName(String fileName) {
		this.fileName = fileName;
	}

	@Override
	public String execute() throws Exception {

		return super.execute();
	}

	public void setInputStream(InputStream inputStream) {
	}

}
	    <action
			name="download"
			class="action.DownloadAction">
			<result name="success" type="stream">
				<param name="contentType">text/plain</param>
				<param name="inputName">inputStream</param>
				<param name="contentDisposition">attachment;filename="hello.txt"</param>
				<param name="bufferSize">1024</param>
			</result>
		</action>

At this point, do not forget to import the package, and FileUtils to which package is imported, look carefully at import org.apache.commons.io.FileUtils;

 

Disadvantage or improvement

shortcoming
 

  1. If you want to download files in any directory (not just Web application directories), you just need to modify the way in which the action returns the file input stream, such as return new FileInputStream(inputPath).
  2. In practical applications, downloaded files should not be configured in struts.xml files. If so, it would be equivalent to limiting FileDownloadAction's functionality to download only one file. The selection of download files should be realized by encoding. According to the download request from browser, the configuration file or database should be queried, the real download file data should be obtained, and the inputStream object should be constructed.
  3. For downloaded file names and downloaded file types, they are configured in struts.xml files. If there are many different types of files to be downloaded by users, this approach is obviously inflexible.
     

Improvement

  1. In order to dynamically set the file type and download the file name, we can write an interceptor that dynamically adds parameters of StreamResult before the Action is executed and the result is executed.
  2. In order to intercept the call before the result is executed, we need to use the PreResultListener interface, which can be registered through Action lnvocation and get a callback before the result is executed. PreResultListener needs to register in the interceptor, so we need to write an interceptor and then
    Register a PreResultListener instance in the interceptor method.

Errors in downloading files

  1. java.lang.IllegalArgumentException: Can not find a java.io.InputStream with the name [inputStream] in the invocation stack. 
    Check the <param name="inputName"> tag specified for this action.
    	at org.apache.struts2.result.StreamResult.doExecute(StreamResult.java:234)
    
    ERROR DefaultDispatcherErrorHandler Exception occurred during processing request: 
    
    java.lang.IllegalArgumentException: Can not find a java.io.InputStream with the name [inputStream] in the invocation stack.
     Check the <param name="inputName"> tag specified for this action.

This is because ServletActionContext.getServletContext().getResourceAsStream(path+fileName); the return value is null. That is to say, the path of the file is wrong.

This is because ServletActionContext.getServletContext().getResourceAsStream(path+fileName); the return value is null.
That is to say, the path of the file is wrong.

 

Topics: Struts Java xml Tomcat