简体   繁体   English

如何在Struts2应用程序中下载zip文件

[英]How to download a zip file in a struts2 application

I am facing a problem while enabling zip file download in struts2 application. 在struts2应用程序中启用zip文件下载时,我遇到了一个问题。

here is my jsp page 这是我的jsp页面

<%@ taglib prefix="s" uri="/struts-tags"%>
<s:url id="fileDownload" namespace="/" action="Download" ></s:url>

<h4>Download file - <s:a href="%{fileDownload}">MyFile.zip</s:a>
</h4>

and here is my action class 这是我的动作课

public class DownloadAction implements Action
{
    List<String> fileList = new ArrayList<String>();
    private String OUTPUT_ZIP_FILE = "C:\\Users\\Ankush\\Desktop\\MyFile.zip";
    private String SOURCE_FOLDER ;
    private FileOutputStream fos;
    private InputStream fileInputStream;
    public FileOutputStream getFos() {
        return fos;
    }

    public void setFos(FileOutputStream fos) {
        this.fos = fos;
    }

    private ZipOutputStream zos;
    public String  execute()
    {
        Map<String, Object> session = ActionContext.getContext().getSession();

        System.out.println("DOWNLOAD ACTION path="+(session.get("BASIC_PATH").toString()+session.get("username").toString()+"\\"+session.get("course_Name").toString()));
        this.setSOURCE_FOLDER(session.get("BASIC_PATH").toString()+session.get("username").toString()+"\\"+session.get("course_Name").toString());
        System.out.println("ORIGINOL PATH="+"E:\\Z800\\WebAuthoringData\\EMMRC\\Ankush\\Raag_Durga");
        this.generateFileList(new File(this.getSOURCE_FOLDER()));
        this.zipIt(OUTPUT_ZIP_FILE);
        return SUCCESS;
    }

    public InputStream getFileInputStream() {
        return fileInputStream;
    }



    public ZipOutputStream getZos() {
        return zos;
    }

    public void setZos(ZipOutputStream zos) {
        this.zos = zos;
    }

    /**
     * Zip it
     * @param zipFile output ZIP file location
     */
    public void zipIt(String zipFile){

     byte[] buffer = new byte[1024];

     try{

        fos = new FileOutputStream(zipFile);
        zos = new ZipOutputStream(fos);

        System.out.println("Output to Zip : " + zipFile);

        for(String file : this.fileList){

            System.out.println("File Added : " + file);
            ZipEntry ze= new ZipEntry(file);
            zos.putNextEntry(ze);

            fileInputStream = 
                       new FileInputStream(SOURCE_FOLDER + File.separator + file);

            int len;
            while ((len = fileInputStream.read(buffer)) > 0) {
                zos.write(buffer, 0, len);
            }
        }
         fileInputStream.close();
        fos.flush();
        zos.flush();

        zos.closeEntry();
        //remember close it
        zos.close();
        fos.close();
        System.out.println("Done");
    }catch(IOException ex){
       ex.printStackTrace();   
    }

   }

and my struts.xml for this 还有我的struts.xml

<action name="Download" class="com.cdac.action.DownloadAction">

            <result name="error">/WEB-INF/jsps/error.jsp</result>


    <result name="success" type="stream">
      <param name="contentType">application/zip</param>
      <param name="inputName">fileInputStream</param>
      <param name="contentDisposition">attachment;filename="MyFile.zip"</param>
      <param name="bufferSize">2048</param>
    </result>
    </action>

and error log 和错误日志

SEVERE: Servlet.service() for servlet jsp threw exception
java.lang.IllegalStateException: getOutputStream() has already been called for this response
    at org.apache.catalina.connector.Response.getWriter(Response.java:626)
    at org.apache.catalina.connector.ResponseFacade.getWriter(ResponseFacade.java:215)
    at javax.servlet.ServletResponseWrapper.getWriter(ServletResponseWrapper.java:105)
    at org.apache.jasper.runtime.JspWriterImpl.initOut(JspWriterImpl.java:125)
    at org.apache.jasper.runtime.JspWriterImpl.flushBuffer(JspWriterImpl.java:118)
    at org.apache.jasper.runtime.PageContextImpl.release(PageContextImpl.java:182)
    at org.apache.jasper.runtime.JspFactoryImpl.internalReleasePageContext(JspFactoryImpl.java:123)
    at org.apache.jasper.runtime.JspFactoryImpl.releasePageContext(JspFactoryImpl.java:80)
    at org.apache.jsp.WEB_002dINF.jsps.error_jsp._jspService(error_jsp.java:82)
    at org.apache.jasper.runtime.HttpJspBase.service(HttpJspBase.java:70)
    at javax.servlet.http.HttpServlet.service(HttpServlet.java:722)
    at org.apache.jasper.servlet.JspServletWrapper.service(JspServletWrapper.java:419)
    at org.apache.jasper.servlet.JspServlet.serviceJspFile(JspServlet.java:391)
    at org.apache.jasper.servlet.JspServlet.service(JspServlet.java:334)
    at javax.servlet.http.HttpServlet.service(HttpServlet.java:722)
    at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:304)
    at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:210)
    at org.apache.catalina.core.ApplicationDispatcher.invoke(ApplicationDispatcher.java:684)
    at org.apache.catalina.core.ApplicationDispatcher.doInclude(ApplicationDispatcher.java:593)
    at org.apache.catalina.core.ApplicationDispatcher.include(ApplicationDispatcher.java:530)
    at org.apache.struts2.dispatcher.ServletDispatcherResult.doExecute(ServletDispatcherResult.java:166)
    at org.apache.struts2.dispatcher.StrutsResultSupport.execute(StrutsResultSupport.java:186)
    at com.opensymphony.xwork2.DefaultActionInvocation.executeResult(DefaultActionInvocation.java:371)
    at com.opensymphony.xwork2.DefaultActionInvocation.invoke(DefaultActionInvocation.java:275)
    at org.apache.struts2.impl.StrutsActionProxy.execute(StrutsActionProxy.java:54)
    at org.apache.struts2.dispatcher.Dispatcher.serviceAction(Dispatcher.java:562)
    at org.apache.struts2.dispatcher.ng.ExecuteOperations.executeAction(ExecuteOperations.java:77)
    at org.apache.struts2.dispatcher.ng.filter.StrutsPrepareAndExecuteFilter.doFilter(StrutsPrepareAndExecuteFilter.java:99)
    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:240)
    at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:164)
    at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:462)
    at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:164)
    at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:100)
    at org.apache.catalina.valves.AccessLogValve.invoke(AccessLogValve.java:562)
    at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:118)
    at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:395)
    at org.apache.coyote.http11.Http11Processor.process(Http11Processor.java:250)
    at org.apache.coyote.http11.Http11Protocol$Http11ConnectionHandler.process(Http11Protocol.java:188)
    at org.apache.tomcat.util.net.JIoEndpoint$SocketProcessor.run(JIoEndpoint.java:302)
    at java.util.concurrent.ThreadPoolExecutor.runWorker(Unknown Source)
    at java.util.concurrent.ThreadPoolExecutor$Worker.run(Unknown Source)
    at java.lang.Thread.run(Unknown Source)

Nov 18, 2014 3:54:05 PM com.opensymphony.xwork2.util.logging.commons.CommonsLogger error
SEVERE: Exception occurred during processing request: java.lang.IllegalStateException: getOutputStream() has already been called for this response
org.apache.jasper.JasperException: java.lang.IllegalStateException: getOutputStream() has already been called for this response
    at org.apache.jasper.servlet.JspServletWrapper.handleJspException(JspServletWrapper.java:534)
    at org.apache.jasper.servlet.JspServletWrapper.service(JspServletWrapper.java:452)
    at org.apache.jasper.servlet.JspServlet.serviceJspFile(JspServlet.java:391)
    at org.apache.jasper.servlet.JspServlet.service(JspServlet.java:334)
    at javax.servlet.http.HttpServlet.service(HttpServlet.java:722)
    at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:304)
    at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:210)
    at org.apache.catalina.core.ApplicationDispatcher.invoke(ApplicationDispatcher.java:684)
    at org.apache.catalina.core.ApplicationDispatcher.doInclude(ApplicationDispatcher.java:593)
    at org.apache.catalina.core.ApplicationDispatcher.include(ApplicationDispatcher.java:530)
    at org.apache.struts2.dispatcher.ServletDispatcherResult.doExecute(ServletDispatcherResult.java:166)
    at org.apache.struts2.dispatcher.StrutsResultSupport.execute(StrutsResultSupport.java:186)
    at com.opensymphony.xwork2.DefaultActionInvocation.executeResult(DefaultActionInvocation.java:371)
    at com.opensymphony.xwork2.DefaultActionInvocation.invoke(DefaultActionInvocation.java:275)
    at org.apache.struts2.impl.StrutsActionProxy.execute(StrutsActionProxy.java:54)
    at org.apache.struts2.dispatcher.Dispatcher.serviceAction(Dispatcher.java:562)
    at org.apache.struts2.dispatcher.ng.ExecuteOperations.executeAction(ExecuteOperations.java:77)
    at org.apache.struts2.dispatcher.ng.filter.StrutsPrepareAndExecuteFilter.doFilter(StrutsPrepareAndExecuteFilter.java:99)
    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:240)
    at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:164)
    at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:462)
    at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:164)
    at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:100)
    at org.apache.catalina.valves.AccessLogValve.invoke(AccessLogValve.java:562)
    at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:118)
    at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:395)
    at org.apache.coyote.http11.Http11Processor.process(Http11Processor.java:250)
    at org.apache.coyote.http11.Http11Protocol$Http11ConnectionHandler.process(Http11Protocol.java:188)
    at org.apache.tomcat.util.net.JIoEndpoint$SocketProcessor.run(JIoEndpoint.java:302)
    at java.util.concurrent.ThreadPoolExecutor.runWorker(Unknown Source)
    at java.util.concurrent.ThreadPoolExecutor$Worker.run(Unknown Source)
    at java.lang.Thread.run(Unknown Source)
Caused by: java.lang.IllegalStateException: getOutputStream() has already been called for this response
    at org.apache.catalina.connector.Response.getWriter(Response.java:626)
    at org.apache.catalina.connector.ResponseFacade.getWriter(ResponseFacade.java:215)
    at javax.servlet.ServletResponseWrapper.getWriter(ServletResponseWrapper.java:105)
    at org.apache.jasper.runtime.JspWriterImpl.initOut(JspWriterImpl.java:125)
    at org.apache.jasper.runtime.JspWriterImpl.flushBuffer(JspWriterImpl.java:118)
    at org.apache.jasper.runtime.PageContextImpl.release(PageContextImpl.java:182)
    at org.apache.jasper.runtime.JspFactoryImpl.internalReleasePageContext(JspFactoryImpl.java:123)
    at org.apache.jasper.runtime.JspFactoryImpl.releasePageContext(JspFactoryImpl.java:80)
    at org.apache.jsp.WEB_002dINF.jsps.error_jsp._jspService(error_jsp.java:82)
    at org.apache.jasper.runtime.HttpJspBase.service(HttpJspBase.java:70)
    at javax.servlet.http.HttpServlet.service(HttpServlet.java:722)
    at org.apache.jasper.servlet.JspServletWrapper.service(JspServletWrapper.java:419)
    ... 32 more

Nov 18, 2014 3:54:05 PM org.apache.catalina.core.StandardWrapperValve invoke
SEVERE: Servlet.service() for servlet [default] in context with path [/web-authoring-tool] threw exception
java.lang.IllegalStateException
    at org.apache.catalina.connector.ResponseFacade.sendError(ResponseFacade.java:443)
    at org.apache.struts2.dispatcher.Dispatcher.sendError(Dispatcher.java:914)
    at org.apache.struts2.dispatcher.Dispatcher.serviceAction(Dispatcher.java:574)
    at org.apache.struts2.dispatcher.ng.ExecuteOperations.executeAction(ExecuteOperations.java:77)
    at org.apache.struts2.dispatcher.ng.filter.StrutsPrepareAndExecuteFilter.doFilter(StrutsPrepareAndExecuteFilter.java:99)
    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:240)
    at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:164)
    at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:462)
    at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:164)
    at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:100)
    at org.apache.catalina.valves.AccessLogValve.invoke(AccessLogValve.java:562)
    at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:118)
    at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:395)
    at org.apache.coyote.http11.Http11Processor.process(Http11Processor.java:250)
    at org.apache.coyote.http11.Http11Protocol$Http11ConnectionHandler.process(Http11Protocol.java:188)
    at org.apache.tomcat.util.net.JIoEndpoint$SocketProcessor.run(JIoEndpoint.java:302)
    at java.util.concurrent.ThreadPoolExecutor.runWorker(Unknown Source)
    at java.util.concurrent.ThreadPoolExecutor$Worker.run(Unknown Source)
    at java.lang.Thread.run(Unknown Source)

Please anybody help me as i don't know how to fix this issue and probably i may be doing some silly mistake but i can't figure it out. 请有人帮助我,因为我不知道如何解决此问题,也许我可能在犯一些愚蠢的错误,但我无法弄清楚。 Please help me . 请帮我 。 i will be very thankful to you! 我将非常感谢您!

You can't write in the client File System like that; 您不能像这样在客户端文件系统中编写代码; in your case, your server is in your machine, but don't get fooled, it's a server path, not a client one. 在您的情况下,您的服务器在您的计算机中,但不要上当,它是服务器路径,而不是客户端路径。 You need to write on the response. 您需要在响应上写。

You can't use both Struts2 result and writing in the OutputStream together: when manually forging the response, you must bypass the framework convention, and return the result by yourself. 您不能同时使用Struts2结果和一起写入OutputStream:手动伪造响应时,必须绕过框架约定,并自行返回结果。 The correct result for this case is is Action.NONE : 在这种情况下,正确的结果是Action.NONE

<action name="Download" class="com.cdac.action.DownloadAction" />
public String execute(){
    /* 
    do your stuff
    */
    return NONE;
}

You're lucky, here is a kick off example I've written long time ago, explaining the whole thing (including the need to deal with duplicate filenames in the same ZIP). 您很幸运, 这是我很久以前写的一个启动示例 ,解释了整个过程(包括需要处理同一ZIP中的重复文件名)。

Also try using Content-Length properly (to let the browser draw a realistic progress-bar). 另外,请尝试正确使用Content-Length (以使浏览器绘制逼真的进度条)。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM