Cliché: Struct2 file Download (with click to cancel the exception to resolve the problem)

Source: Internet
Author: User
Tags try catch

There are too many articles on the internet to download Struts2 files, but for beginners, to access the full demo is very difficult, or to achieve "successful" download then ignored, but when the project into the production environment, the problem is not resolved, the author according to their own experience, Here's a more complete download demo of the Struts2 files available for the actual project.

1.Struts File Download Common configuration (basic configuration)

           <!--the action-->
           <action name= "filedownload" class= "my.pro.FileDownloadAction" > <!-for processing file download requests
               -For file downloads, the type must be stream-->
            <result type= "stream" Name= "DownLoad" >
                <!--document type, the following is a common type. Applicable to any document type-->
                  <param name= "ContentType" >application/octet-stream</param>
                  <!--input stream name The  corresponding method in the class My.pro.DownLoadFile is Gettarget () and the return value is InputStream-->
                  <param name= "InputName" > Targetfile</param>
                  <!--file name when downloading-->
                  <param name= "Contentdisposition" >attachment; Filename= "${filename}" </param>
                  <!--buffer size-->
                  <param name= "buffersize" >4096</param >
           </result>
        </action>


2. Download the type of filedownloadaction

public class Filedownloadaction  extends actionsupport{
	private static final long serialversionuid = 1L;
	This property is a dependency injection property that can be dynamically specified in the configuration file for the property value 
	private String fileName; 
	The setter method that relies on injecting the property value is public 
	void Setfilename (String fileName) {
		this.filename = filename;
	} 
	/* 
	Download action should return a InputStream instance, 
	the method corresponding to the InputName attribute value in result is targetfile/ 
	public 

	InputStream Gettargetfile () throws Exception 
	{/ 
		* can be put into business logic processing/return
		Servletactioncontext.getservletcontext (). getResourceAsStream (FileName); 
                 
	} 
	The Execute method that handles the user request, which returns the success string @Override public string
	execute () throws Exception 
	{ 
		return SUCCESS; 
	}
	Public String GetFileName () {return
		fileName;
	}
}

Here we have to introduce the Servletactioncontext.getservletcontext (). getResourceAsStream (), this is not used in this way depends on your file storage location, this is not the absolute path, Instead, the relative path to the CLASSPATH environment variable. In the development environment, the general SRC directory is contained under Classpath, under Tomcat, the general point to the Web-inf/classes directory, but often, developers do not want to download the documents to be downloaded in the site directory, but placed in a server path for easy management, This means that you must set the context parameter in Tomcat to point to this path. If the reader does not want to do this and instead wants to open the absolute path of the file on the server directly at the time of downloading, you must change the method, as follows:

Public InputStream Gettargetfile () throws Exception 
	{/ 
		* can be put into business logic processing/File File
                = new file ("Absolute path of File");
                /* Here you can consider the robustness of the algorithm, such as the file does not exist when the processing, of course, with a try catch the *  /return new FileInputStream (file);              
	} 


Through the above introduction, the reader can achieve the download, of course, many beginners to get this step is complacent. But waiting will be a headache of the abnormal, some people fought for a long time. What is that unusual, first sell a thing. We first say a user behavior, when we download the file, if we find that the speed is too slow or other circumstances, usually cancel the download. The following is the problem, the use of Struts2 to implement file download when the click of the cancellation caused by the exception (save or Open will not appear), as follows:

Serious: Servlet.service () for Servlet default threw exception
Java.lang.IllegalStateException
At Org.apache.catalina.connector.ResponseFacade.sendError (responsefacade.java:407)
At Javax.servlet.http.HttpServletResponseWrapper.sendError (httpservletresponsewrapper.java:108)
At Com.opensymphony.module.sitemesh.filter.PageResponseWrapper.sendError (pageresponsewrapper.java:176)

Or: Broken pipe

Why does this exception occur? The following principles (understanding principle, necessary to solve the problem), in the Struts2 configuration file, for the download configuration parameters are used stream, The corresponding class for the stream is Org.apache.struts2.dispatcher.StreamResult, and its process is:

(1) Configure the parameters under the result label, such as:

                  <param name= "ContentType" >application/octet-stream</param>
                  <!--input stream name  The corresponding method in the class My.pro.DownLoadFile is Gettarget () and the return value is InputStream-->
                  <param name= "InputName" >targetfile </param>
                  <!--file name when downloading-->
                  <param name= "contentdisposition" >attachment;filename= "${" FileName} "</param>
                  <!--buffer size-->
                  <param name=" buffersize ">4096</param>
(2) When the request file is downloaded, the server starts to obtain the input stream after the response, and establishes the output stream with the client at the same time, the server and the client link are connected through the socket.

(3) The data begins to transmit. In the transmission process, if clicked "Cancel", the representative closes all streams, but actually the socket is not disconnected, is the stream has not been closed, so before the JSP container obtains the output stream through the response, the front flow does not close, therefore appears the exception.

The solution is given below.

3. Struts2 download file Click to cancel the exception to solve the problem

(1) Avoidance methods

This is an exception blocking method, when the occurrence of clientabortexception exception, jump to the specified page, and this page does not need to output anything, in fact, the exception still occurs, but does not show, when invisible, a little "deceive" meaning, so called "escape method", I do not recommend this side, after all, the symptoms do not cure. Examples are as follows:

<package name= "Default" extends= "Struts-default" >
     <global-results>
        <result name= " Client-abort-exception ">err.jsp</result>
     </global-results>
</package>
< Package Name= "MYPCK" extends= "Struts-default" >
     <exception-mapping result= "Client-abort-exception" exception= "Org.apache.catalina.connector.ClientAbortException"/>
     <action name= "Download" My.pro.FileDownloadAction ">
       <result name=" Success "type=" Stream ">
         <para mname=" InputName "> targetfile</param>
         <param name= "contentdisposition" >filename= "" </param>
         <param Name= "buffersize" >4096</param>
       </result>
     </action>
</package>
(2) Radical Cure method

The previous analysis of the Tream corresponding class is the org.apache.struts2.dispatcher.StreamResult of the implementation process, to completely solve this problem, but also to start with it. If you replace it with a class that can be substituted, and this class does not appear this different, the reason is to click "Cancel" and then close the stream, will not report the exception, it can be cured. Instead of Struts2-sunspoter-stream-1.0.jar here, note that 1.0. The method is as follows:

The first step: Download the Struts2-sunspoter-stream-1.0.jar first, and copy it to the/web-inf/lib of the project. Download the address: http://download.csdn.net/detail/xiangchengguan/8010633

The second step: in the original struts.xml based on the corresponding configuration, first in the 〈package〉 package before the first node (otherwise error) insert <result-types>

<package name= "Default" namespace= "/" extends= "Struts-default" >  
    <!--Add the following-->  
    < result-types>  
       <result-type  name= "Streamx" class= " Com.sunspoter.lib.web.struts2.dispatcher.StreamResultX "/>  
    </result-types> ...
</package>

The next step is to replace the stream in the download class configuration with STREAMX, which he does not change, as follows:

So even if it is done, click "Cancel" also closes the stream, will not report the exception. If Log4j.properties is configured, when the user clicks "Cancel", the following warning appears, the socket is not properly interrupted, but the stream has been closed. As follows:

WARN Streamresult:45-streamresultx Warn:socket Write error



















Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.