0.struts2文件下载
>文件下载只要将action返回的视图类型修改为stream就可以了
<result name="success" type="stream">
<param name="contentType">image/gif</param>
<param name="inputName">inputStream</param>
<param name="contentDisposition">filename="struts.gif"</param>
<param name="bufferSize">4096</param>
</result>
//contentType-发送给web浏览器的字节流镜像类型(默认为普通文本类型)
//contentLength-在二进制数组中字节流的长度 (可以让浏览器展示一个进度条)
//contentDisposition
//struts2的contentDisposition参数表示文件下载的方式,
//包括内联(inline)和附件(attachment)2种方式。
//默认就是inline,表示在浏览器中打开文件,
//若想用附件下载的话就得设置为:attachment;filename="this.txt";
//inputName-在action中输入流的属性名字(默认为inputStream)
//bufferSize-从输入流到输出流的缓冲长度(默认为1021)
//allowCaching-如果设置为false这将会设置头pragma和cache-control为no-cache,并且阻止客户端缓存内容默认为true
//contentCharSet-设置字符编码
>*****************************************************************************************************************<
>源码分析
>*****************************************************************************************************************<
//public class org.apache.struts2.dispatcher.StreamResult extends StrutsResultSupport-->这个视图类型用于文件下载
//public StreamResult(InputStream in)
//{
// contentType = "text/plain";-->默认类型
// contentDisposition = "inline";
// inputName = "inputStream";
// bufferSize = 1024;
// allowCaching = true;
// inputStream = in;
//}
//protected void doExecute(String finalLocation, ActionInvocation invocation)//invocation这个重要的参数可以得到很多有用的东西
// throws Exception
// {
// OutputStream oOutput;//输出流
// resolveParamsFromStack(invocation.getStack(), invocation);//在堆栈中寻找设置好的配置信息将属性重新设置一次
// oOutput = null;
// if(inputStream == null)
// //得到当前请求执行上下文堆栈找到
//public InputStream getInputStream() throws Exception {
//return ServletActionContext.getServletContext().getResourceAsStream(inputPath);}
//这段在action中返回的字节流
//inputName就是在配置文件设置好的名字
// inputStream = (InputStream)invocation.getStack().findValue(conditionalParse(inputName, invocation));
// if(inputStream == null)
// {
// String msg = (new StringBuilder()).append("Can not find a java.io.InputStream with the name [").
append(inputName).append("] in the invocation stack. ").
append("Check the <param name=\"inputName\"> tag specified for this action.")
.toString();
// LOG.error(msg, new String[0]);
// throw new IllegalArgumentException(msg);
// }
// //得到响应对象
// HttpServletResponse oResponse = (HttpServletResponse)invocation.getInvocationContext().
get("com.opensymphony.xwork2.dispatcher.HttpServletResponse");
// if(contentCharSet != null && !contentCharSet.equals(""))
// oResponse.setContentType((new StringBuilder()).append(conditionalParse(contentType, invocation)).
append(";charset=").append(contentCharSet).toString());
// else
// oResponse.setContentType(conditionalParse(contentType, invocation));
// if(contentLength != null)
// {
// String _contentLength = conditionalParse(contentLength, invocation);
// int _contentLengthAsInt = -1;
// try
// {
// _contentLengthAsInt = Integer.parseInt(_contentLength);
// if(_contentLengthAsInt >= 0)
// oResponse.setContentLength(_contentLengthAsInt);//设置响应类型
// }
// catch(NumberFormatException e)
// {
// LOG.warn((new StringBuilder()).append("failed to recongnize ").
append(_contentLength).append(" as a number, contentLength header will not be set").toString(), e, new String[0]);
// }
// }
//
// if(contentDisposition != null)
// oResponse.addHeader("Content-Disposition", conditionalParse(contentDisposition, invocation));
// //设置响应头contentDisposition在配置文件中配置好的字符窜赋值
// if(!allowCaching)//设置是否需要缓存
// {
// oResponse.addHeader("Pragma", "no-cache");
// oResponse.addHeader("Cache-Control", "no-cache");
// }
// oOutput = oResponse.getOutputStream();//得到输出流
// if(LOG.isDebugEnabled())
// LOG.debug((new StringBuilder()).append("Streaming result [").append(inputName).append("] type=[").
append(contentType).append("] length=[").append(contentLength).append("] content-disposition=[").
append(contentDisposition).append("] charset=[").append(contentCharSet).append("]").toString(), new String[0]);
// LOG.debug("Streaming to output buffer +++ START +++", new String[0]);
// byte oBuff[] = new byte[bufferSize];//将字节流存放到字节数组中
// int iSize;
// while(-1 != (iSize = inputStream.read(oBuff))) //循环读取出
// oOutput.write(oBuff, 0, iSize);//不断输出
// LOG.debug("Streaming to output buffer +++ END +++", new String[0]);
// oOutput.flush();//刷出
// if(inputStream != null)
// inputStream.close();//关闭流
// if(oOutput != null)
// oOutput.close();
// break MISSING_BLOCK_LABEL_573;
// Exception exception;
// exception;
// if(inputStream != null)
// inputStream.close();
// if(oOutput != null)
// oOutput.close();
// throw exception;
// }
>*****************************************************************************************************************<
//在堆栈中寻找设置好的配置信息
protected void resolveParamsFromStack(ValueStack stack, ActionInvocation invocation)
{
String disposition = stack.findString("contentDisposition");
if(disposition != null)
setContentDisposition(disposition);
String contentType = stack.findString("contentType");
if(contentType != null)
setContentType(contentType);
String inputName = stack.findString("inputName");
if(inputName != null)
setInputName(inputName);
String contentLength = stack.findString("contentLength");
if(contentLength != null)
setContentLength(contentLength);
Integer bufferSize = (Integer)stack.findValue("bufferSize", java/lang/Integer);
if(bufferSize != null)
setBufferSize(bufferSize.intValue());
if(contentCharSet != null)
contentCharSet = conditionalParse(contentCharSet, invocation);
else
contentCharSet = stack.findString("contentCharSet");
}
>*****************************************************************************************************************<
>*****************************************************************************************************************<
>示例代码
>*****************************************************************************************************************<
public class FileDownLoadAction extends ActionSupport {
//<s:url action="fileDownLoadAction" namespace="filedownload" var="url" />
//在上面使用url这个属性指定了action的空间以及路径相当于定义了一个名字为url的局部变量
//然后再下面使用%{url}进行了引用
//<s:a href="%{url}">download file</s:a>
//这个方法名字必须和inputName中配置的一样只是将get后的第一个字母小写其余不变就行
public InputStream getFileInputStream(){
//这里得到的是绝对路径也就是当前web应用所在的虚拟上下文的路径
//F:\apache-tomcat-6.0.30\apache-tomcat-6.0.30\apache-tomcat-6.0.30\webapps\struts2
String path = ServletActionContext.getServletContext().getRealPath("")+File.separator+"china.txt";
// 这里就直接是相对路径不要用绝对路径就可以了
InputStream is =ServletActionContext.getServletContext().getResourceAsStream("china.txt");
return is;
}
@Override
public String execute() throws Exception {
//struts2首先执行这个方法然后发现返回类型是流之后又回来执行了上面的getInputStream方法得到了想要下载的文件
return this.SUCCESS;
}
}
>*****************************************************************************************************************<
struts2 文件下载
最新推荐文章于 2021-06-08 10:04:30 发布