-2

更新到 struts2-core-2.3.14.2 后,在下载 Stream 结果时出现以下错误:

堆栈跟踪

Servlet.service() for servlet [default] in context with path [] threw exception [Filter execution threw an exception] with root cause
    java.lang.AbstractMethodError: org.apache.struts2.dispatcher.StrutsResultSupport$1.evaluate(Ljava/lang/Object;)Ljava/lang/Object;
        at com.opensymphony.xwork2.util.TextParseUtil.translateVariables(TextParseUtil.java:187)
        at com.opensymphony.xwork2.util.TextParseUtil.translateVariables(TextParseUtil.java:118)
        at com.opensymphony.xwork2.util.TextParseUtil.translateVariables(TextParseUtil.java:62)
        at org.apache.struts2.dispatcher.StrutsResultSupport.conditionalParse(StrutsResultSupport.java:198)
        at org.apache.struts2.dispatcher.StreamResult.doExecute(StreamResult.java:270)
        at org.apache.struts2.dispatcher.StrutsResultSupport.execute(StrutsResultSupport.java:186)
        at com.opensymphony.xwork2.DefaultActionInvocation.executeResult(DefaultActionInvocation.java:361)
        at com.opensymphony.xwork2.DefaultActionInvocation.invoke(DefaultActionInvocation.java:265)
        at org.apache.struts2.interceptor.debugging.DebuggingInterceptor.intercept(DebuggingInterceptor.java:256)
        at com.opensymphony.xwork2.DefaultActionInvocation.invoke(DefaultActionInvocation.java:236)
        at com.opensymphony.xwork2.interceptor.DefaultWorkflowInterceptor.doIntercept(DefaultWorkflowInterceptor.java:163)
        at com.opensymphony.xwork2.interceptor.MethodFilterInterceptor.intercept(MethodFilterInterceptor.java:87)
        at com.opensymphony.xwork2.DefaultActionInvocation.invoke(DefaultActionInvocation.java:236)
        at com.opensymphony.xwork2.validator.ValidationInterceptor.doIntercept(ValidationInterceptor.java:251)
        at org.apache.struts2.interceptor.validation.AnnotationValidationInterceptor.doIntercept(AnnotationValidationInterceptor.java:68)
        at com.opensymphony.xwork2.interceptor.MethodFilterInterceptor.intercept(MethodFilterInterceptor.java:87)
        at com.opensymphony.xwork2.DefaultActionInvocation.invoke(DefaultActionInvocation.java:236)
        at com.opensymphony.xwork2.interceptor.ConversionErrorInterceptor.intercept(ConversionErrorInterceptor.java:122)
        at com.opensymphony.xwork2.DefaultActionInvocation.invoke(DefaultActionInvocation.java:236)
        at com.opensymphony.xwork2.interceptor.ParametersInterceptor.doIntercept(ParametersInterceptor.java:195)
        at com.opensymphony.xwork2.interceptor.MethodFilterInterceptor.intercept(MethodFilterInterceptor.java:87)
        at com.opensymphony.xwork2.DefaultActionInvocation.invoke(DefaultActionInvocation.java:236)
        at com.opensymphony.xwork2.interceptor.ParametersInterceptor.doIntercept(ParametersInterceptor.java:195)
        at com.opensymphony.xwork2.interceptor.MethodFilterInterceptor.intercept(MethodFilterInterceptor.java:87)
        at com.opensymphony.xwork2.DefaultActionInvocation.invoke(DefaultActionInvocation.java:236)
        at com.opensymphony.xwork2.interceptor.StaticParametersInterceptor.intercept(StaticParametersInterceptor.java:148)
        at com.opensymphony.xwork2.DefaultActionInvocation.invoke(DefaultActionInvocation.java:236)
        at org.apache.struts2.interceptor.MultiselectInterceptor.intercept(MultiselectInterceptor.java:73)
        at com.opensymphony.xwork2.DefaultActionInvocation.invoke(DefaultActionInvocation.java:236)
        at org.apache.struts2.interceptor.CheckboxInterceptor.intercept(CheckboxInterceptor.java:91)
        at com.opensymphony.xwork2.DefaultActionInvocation.invoke(DefaultActionInvocation.java:236)
        at org.apache.struts2.interceptor.FileUploadInterceptor.intercept(FileUploadInterceptor.java:252)
        at com.opensymphony.xwork2.DefaultActionInvocation.invoke(DefaultActionInvocation.java:236)
        at com.opensymphony.xwork2.interceptor.ModelDrivenInterceptor.intercept(ModelDrivenInterceptor.java:89)
        at com.opensymphony.xwork2.DefaultActionInvocation.invoke(DefaultActionInvocation.java:236)
        at com.opensymphony.xwork2.interceptor.ScopedModelDrivenInterceptor.intercept(ScopedModelDrivenInterceptor.java:128)
        at com.opensymphony.xwork2.DefaultActionInvocation.invoke(DefaultActionInvocation.java:236)
        at com.opensymphony.xwork2.interceptor.ChainingInterceptor.intercept(ChainingInterceptor.java:126)
        at com.opensymphony.xwork2.DefaultActionInvocation.invoke(DefaultActionInvocation.java:236)
        at com.opensymphony.xwork2.interceptor.PrepareInterceptor.doIntercept(PrepareInterceptor.java:138)
        at com.opensymphony.xwork2.interceptor.MethodFilterInterceptor.intercept(MethodFilterInterceptor.java:87)
        at com.opensymphony.xwork2.DefaultActionInvocation.invoke(DefaultActionInvocation.java:236)
        at com.opensymphony.xwork2.interceptor.I18nInterceptor.intercept(I18nInterceptor.java:164)
        at com.opensymphony.xwork2.DefaultActionInvocation.invoke(DefaultActionInvocation.java:236)
        at org.apache.struts2.interceptor.ServletConfigInterceptor.intercept(ServletConfigInterceptor.java:164)
        at com.opensymphony.xwork2.DefaultActionInvocation.invoke(DefaultActionInvocation.java:236)
        at com.opensymphony.xwork2.interceptor.AliasInterceptor.intercept(AliasInterceptor.java:128)
        at com.opensymphony.xwork2.DefaultActionInvocation.invoke(DefaultActionInvocation.java:236)
        at com.opensymphony.xwork2.interceptor.ExceptionMappingInterceptor.intercept(ExceptionMappingInterceptor.java:176)
        at com.opensymphony.xwork2.DefaultActionInvocation.invoke(DefaultActionInvocation.java:236)
        at org.apache.struts2.impl.StrutsActionProxy.execute(StrutsActionProxy.java:54)
        at org.apache.struts2.dispatcher.Dispatcher.serviceAction(Dispatcher.java:546)
        at org.apache.struts2.dispatcher.FilterDispatcher.doFilter(FilterDispatcher.java:434)
        at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:243)
        at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:210)
        at org.springframework.security.util.FilterChainProxy.doFilter(FilterChainProxy.java:168)
        at org.springframework.web.filter.DelegatingFilterProxy.invokeDelegate(DelegatingFilterProxy.java:183)
        at org.springframework.web.filter.DelegatingFilterProxy.doFilter(DelegatingFilterProxy.java:138)
        at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:243)
        at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:210)
        at org.springframework.web.filter.CharacterEncodingFilter.doFilterInternal(CharacterEncodingFilter.java:96)
        at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:75)
        at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:243)
        at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:210)
        at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:224)
        at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:169)
        at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:472)
        at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:168)
        at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:98)
        at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:118)
        at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:407)
        at org.apache.coyote.http11.AbstractHttp11Processor.process(AbstractHttp11Processor.java:987)
        at org.apache.coyote.AbstractProtocol$AbstractConnectionHandler.process(AbstractProtocol.java:579)
        at org.apache.tomcat.util.net.JIoEndpoint$SocketProcessor.run(JIoEndpoint.java:307)
        at java.util.concurrent.ThreadPoolExecutor$Worker.runTask(ThreadPoolExecutor.java:886)
        at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:908)
        at java.lang.Thread.run(Thread.java:662)

Struts.xml

 <action name="download"  
        class="ab.action.DownloadAction"
        method="download">
        <result name="success" type="stream">
           <param name="contentDisposition">attachment;filename="${fileName}"</param>
           <param name="inputName">downloadFile</param>
        </result>
    </action>

行动

 //filePathName is example
    Strin filePathName="/home/download/aaa.txt";
    public String getFileName()
    {
       File f = new File(filePathName);
       String fileRealName = new String(f.getName()); //get filename
       return fileRealName;
    }

    public InputStream getDownloadFile() 
    {
        File file  =   new  File(filePathName);  
        //get inputstream
        InputStream fis  =   new  BufferedInputStream( new  FileInputStream(filePathName));  
        return fis;
    }

    public String download() throws Exception 
    {
       return SUCCESS; //just return ok
    }

图书馆

xwork-core-2.3.14.2.jar
struts2-core-2.3.14.2.jar
commons-fileupload-1.2.2.jar
4

1 回答 1

0

看起来不错,除了以下几点:

  1. 指定内容类型:

    <result name="success" type="stream">
       <param name="contentType">text/plain</param>
       <param name="contentDisposition">attachment;filename="${fileName}"</param>
       <param name="inputName">downloadFile</param>
    </result>
    

    text/plain 是默认值,在您的示例中,您有一个 txt 文件,但最好在配置中明确说明它;

  2. 遵循JavaBeans 约定;getter 不应该有逻辑,并且名称应该与返回的私有变量之一匹配:

    例如,

    String foo;
    public String getBar(){ 
        return this.foo; 
    }
    

    无效并且可能导致 Struts2 出现问题(内部使用反射)

    然后尝试像这样更改您的操作代码:

    String filePathName="/home/download/aaa.txt";
    String fileName;
    InputStream donwloadFile;
    
    public String getFileName() {
       return this.fileName;
    }
    
    public InputStream getDownloadFile() {
        return this.downloadFile;
    }
    
    public String download() throws Exception {
       File file = new File(filePathName);       
       this.fileName = file.getName();
       this.downloadFile = new BufferedInputStream(new FileInputStream(file));
       return SUCCESS;
    }
    
于 2013-06-05T08:38:38.363 回答