原文链接:http://sunspot.blog.51cto.com/372554/474983/
jar包中添加了类继承自 StreamResult
在struts的配置文件中,需要添加如下配置
<span style="white-space:pre"><result-types>
<result-type name="streamx" class="</span>....<span style="white-space:pre">.StreamResultX" />
</result-types>
<action name="*" class="" method="{1}">
<result name="toDowloadFile" type="streamx">
<param name="contentType"></span>.....<span style="white-space:pre"></param>
<param name="inputName">inputStream</param>
<param name="bufferSize">4096</param>
<param name="contentDisposition">filename="${filename}"</param>
</result>
</action> </span>
jar文件反编译后的代码如下
/**
* struts2 type="stream" 流文件下载,
* 修改:处理"点击下载,取消"的操作步骤,出现的异常问题
* 与源文件主要区别: line 86 行,源文件没有捕获处理取消操作所抛出的异常(取消,文件流未关闭)
*/
import java.io.InputStream;
import java.io.OutputStream;
import javax.servlet.http.HttpServletResponse;
import org.apache.struts2.dispatcher.StreamResult;
import com.opensymphony.xwork2.ActionInvocation;
public class StreamResultX extends StreamResult {
private static final long serialVersionUID = -8275283556955657976L;
protected void doExecute(String finalLocation, ActionInvocation invocation)
throws Exception {
resolveParamsFromStack(invocation.getStack(), invocation);
OutputStream oOutput = null;
try {
if (this.inputStream == null) {
this.inputStream = ((InputStream) invocation.getStack()
.findValue(conditionalParse(this.inputName, invocation)));
}
if (this.inputStream == null) {
String msg = "StreamResultX : Can not find a java.io.InputStream with the name ["
+ this.inputName
+ "] in the invocation stack. "
+ "Check the <param name=\"inputName\"> tag specified for this action.";
LOG.error(msg, new String[0]);
throw new IllegalArgumentException(msg);
}
HttpServletResponse oResponse = (HttpServletResponse) invocation.getInvocationContext()
.get("com.opensymphony.xwork2.dispatcher.HttpServletResponse");
if ((this.contentCharSet != null)
&& (!this.contentCharSet.equals(""))) {
oResponse.setContentType(conditionalParse(this.contentType,
invocation) + ";charset=" + this.contentCharSet);
} else {
oResponse.setContentType(conditionalParse(this.contentType,invocation));
}
if (this.contentLength != null) {
String _contentLength = conditionalParse(this.contentLength,invocation);
int _contentLengthAsInt = -1;
try {
_contentLengthAsInt = Integer.parseInt(_contentLength);
if (_contentLengthAsInt >= 0)
oResponse.setContentLength(_contentLengthAsInt);
} catch (NumberFormatException e) {
LOG.warn("StreamResultX warn : failed to recongnize "
+ _contentLength+ " as a number, contentLength header will not be set",e, new String[0]);
}
}
if (this.contentDisposition != null) {
oResponse.addHeader("Content-Disposition",conditionalParse(this.contentDisposition, invocation));
}
if (!this.allowCaching) {
oResponse.addHeader("Pragma", "no-cache");
oResponse.addHeader("Cache-Control", "no-cache");
}
oOutput = oResponse.getOutputStream();
if (LOG.isDebugEnabled()) {
LOG.debug("StreamResultX : Streaming result [" + this.inputName
+ "] type=[" + this.contentType + "] length=["
+ this.contentLength + "] content-disposition=["
+ this.contentDisposition + "] charset=["
+ this.contentCharSet + "]", new String[0]);
}
byte[] oBuff = new byte[this.bufferSize];
try {
LOG.debug("StreamResultX : Streaming to output buffer +++ START +++",new String[0]);
int iSize;
while (-1 != (iSize = this.inputStream.read(oBuff))) {
oOutput.write(oBuff, 0, iSize);
}
LOG.debug("StreamResultX : Streaming to output buffer +++ END +++",new String[0]);
oOutput.flush();
86 } catch (Exception e) {// -- 主要变更地方:源文件没有捕获异常(取消,文件流未关闭)
LOG.warn("StreamResultX Warn : socket write error",new String[0]);
if (oOutput != null)
try {
oOutput.close();
} catch (Exception e1) {
oOutput = null;
}
} finally {
if (this.inputStream != null)
this.inputStream.close();
if (oOutput != null)
oOutput.close();
}
} finally {
if (this.inputStream != null)
this.inputStream.close();
if (oOutput != null)
oOutput.close();
}
}
}