查了下资料,看了下书。下载代码如下:package com.learn.web.action;import java.io.ByteArrayInputStream;
import java.io.InputStream;import com.opensymphony.xwork2.Action;public class FileDownloadAction implements Action { 

public InputStream getInputStream() throws Exception { 

return new ByteArrayInputStream("Struts 2 下载示例".getBytes());
}

public String execute() throws Exception { 

return SUCCESS;
}
}struts.xml<action name="download" class="com.learn.web.action.FileDownloadAction">
<result name="success" type="stream">
<param name="contentType">text/plain</param>
<param name="inputName">inputStream</param>
<param name="contentDisposition">attachment;filename=${fileName}</param>
<param name="bufferSize">4096</param>
</result>
</action>
我想不通,为什么下载的代码写在public InputStream getInputStream() throws Exception这个方法里呢?谁能解释一下?

解决方案 »

  1.   

    "Struts 2 下载示例".getBytes() 里的"Struts 2 下载示例" 是什么对象写在这无非有两个原因。
    1 可能是覆盖父类的方法
    2 只是一个普通的方法而已 供其他方法调用。
      

  2.   


    你可以看到action,就实现了ACTION接口,根本没有覆盖哪个方法。更没有其他地方调用 没有高手吗?
      

  3.   

    <param name="inputName">inputStream</param>
    这句话定义了在下载的ResultType中有一个setInputName的方法, 在struts2中重写ResultType需要重写方法:
         protected void doExecute(String arg0, ActionInvocation invocation) throws Exception通过定义的InputName得到Action的结果,如下:
    invocation.getStack().findString(conditionalParse(“配置设置的InputName的值”, invocation));
      

  4.   

    错了,上面不能用findString...应该是别的,具体看下struts2的下载的ResultType的源码
      

  5.   

    因为 在struts2做下载的时候, 需要返回stream类型的视图, 而这个视图需要指定一个类型为输入流的属性,
    也就是getInputStream()这个东东, 这个被认为是javaBean的属性,  所以必须单独提供.!
      

  6.   

    action name="download" class="com.learn.web.action.FileDownloadAction">
                <result name="success" type="stream">  
    <!-- 这里说明action返回类型为stream,这是struts2下载action强制约定的。-->
                    <param name="contentType">text/plain</param>
                    <param name="inputName">inputStream</param>
    <!-- 
    //这里说明stream流放在变量inputStream中,根据setter/getter规范,它对应的函数应该是
    //getInputStream()。当服务响应时,会去找这个函数获取输入流,实际并不管哪个属性变量是否存在。
    //故,真正实现文件下载是getInputStream()这个函数,当然,这个函数必须返回stream流。
    -->
                    <param name="contentDisposition">attachment;filename=${fileName}</param>
                    <param name="bufferSize">4096</param>
                </result>
            </action>
      

  7.   

    <param name="inputName">inputStream</param>
    这个地方是ognl表达式访问action中的属性inputStream.
    而ognl有点类似el会去找相应的getInputStream的方法! 
      

  8.   

    这个不是本质地~
    我把我写的一个将指定目录、文件打包zip的ResultType放上,以及配置:public class ZipResult extends StrutsResultSupport
    {
        /** Logger */
        private static final DebugLog logger = LogFactory.getDebugLog(ZipResult.class);
        
        /** 文件名参数 */
        private String fileNameParam = "fileName";
        
        /** zip压缩文件名参数 */
        private String zipFileNameParam = "zipFileName";
        
        /** 需要压缩的文件名 */
        private String filePath;
        
        /** zip压缩的文件名 */
        private String zipFileName = Constants.DEFAULT_ZIP_NAME;
        
        /** 打包完成后的回调函数 **/
        private String afterZip;
        
        public void setFileNameParam(String fileNameParam)
        {
            this.fileNameParam = fileNameParam;
        }
        
        public void setZipFileNameParam(String zipFileNameParam)
        {
            this.zipFileNameParam = zipFileNameParam;
        }
        
        public void setFileName(String fileName)
        {
            this.filePath = fileName;
        }
        
        public void setZipFileName(String zipFileName)
        {
            this.zipFileName = zipFileName;
        }
        
        public void setAfterZip(String afterZip)
        {
            this.afterZip = afterZip;
        }    /**
         * execute method
         * 
         * @param arg0 参数
         * @param invocation ActionInvocation对象
         * @throws Exception
         */
        protected void doExecute(String arg0, ActionInvocation invocation) throws Exception
        {
            filePath = invocation.getStack().findString(conditionalParse(fileNameParam, invocation));
            if (!StringUtils.hasText(filePath))
            {
                throw new IllegalArgumentException("can not find a java.lang.String width name[" + fileNameParam + "]");
            }
            
            zipFileName = invocation.getStack().findString(conditionalParse(zipFileNameParam, invocation));
            if (!StringUtils.hasText(zipFileName))
            {
                zipFileName = Constants.DEFAULT_ZIP_NAME;
            }
            zipFileName = zipFileName.replaceAll("\\.\\w*$", ".zip");     //更换后缀名为zip
            
            HttpServletResponse req = (HttpServletResponse)invocation.getInvocationContext().get(HTTP_RESPONSE);
            try
            {
                ZipUtils.newInstance(req.getOutputStream()).zip(filePath);
                
                if(StringUtils.hasText(afterZip))
                {
                    ReflectUtils.invokeMethod(invocation.getAction(),afterZip,new Object[]{});
                }
            }
            catch(IOException e)
            {
                logger.error("IOException error", e);
            }
            
            req.setContentType(conditionalParse("application/x-download", invocation));
            req.setHeader("Content-Disposition", "attachment; filename=\"" + zipFileName + "\"");
        }
    }。。
    <result id="success" type="zip">
            <param name="afterZip">updateDownloadCount</param>
            </result>
    。。
      

  9.   

    Action需要有
    public String getFileName() ...
    public String getZipFileName()...
    方法~~补充~~
      

  10.   

    我觉得也是javaBean
    你的配置<param name="inputName">inputStream</param>
    当读取配置文件的时候,就会去找名字叫getInputStream的方法。
    而且返回类型要是InputStream.
    其实你看struts的基础原理还是比较简单的。。
    就是读取配置文件 然后用代理反射这些东西。。