6

I have this action class, this class takes care of my response

Update now passing response from DownloadStatus class, but it looks like it is null

public final class DownloadStatus extends ActionSupport implements ServletRequestAware,ServletResponseAware
{
    static Logger logger = Logger.getLogger(DownloadStatus.class);
    private HttpServletRequest request;
    private HttpServletResponse response;
    private File cfile;
    private String cfileFileName;

    @Override
    public String execute() 
    {

        logger.debug("Inside DownloadStatus.execute method")

        try {
            ChainsInvoker invoker = new ChainsInvoker()
            def executionResponse = invoker.invoke(request, MYChains.download, cfile, cfileFileName)
            if(executionResponse == null || ErrorHandler.checkIfError(executionResponse))
            {
                return ERROR
            }
            response.setContentType("APPLICATION/xml")

            logger.debug("filename: $cfileFileName")

            response.addHeader("Content-Disposition", "attachment; filename=\""+cfileFileName+"\"")
            response.getWriter().print(executionResponse)
            logger.debug("executionResponse :" + executionResponse)
            invoker.invoke(MYChains.clean)
        }catch (Exception exp) {

            logger.error("Exception while Creating Status ")
            logger.error(exp.printStackTrace())

        }
        return NONE
    }

    @Override
    public void setServletRequest(HttpServletRequest request) {     this.request = request; }

    @Override
    public void setServletResponse(HttpServletResponse response) {      this.response = response;   }

    public File getcfile()  {       cfile   }

    public void setcfile(File cfile)    {       this.cfile = cfile  }

    public String getcfileFileName()    {       cfileFileName   }

    public void setcfileFileName(String cfileFileName){     this.cfileFileName = cfileFileName  }
}

and below class to write stream into response

class DownloadStatusResponse implements Command {   

static Logger logger = Logger.getLogger(DownloadStatusResponse.class);
@Override
public boolean execute(Context ctx) throws Exception 
{
    logger.debug("Inside DownloadStatusResponse.execute() method")
    OutputStream response = null;

    if(ctx.get(ContextParams.absFileName) != null && ctx.get(ContextParams.absFileName).toString().trim().length() != 0 )
    {
HttpServletResponse resp = ctx.get(ContextParams.response)
/*I am trying to get Response here*/

        response=downloadStatusFile(ctx.get(ContextParams.absFileName).toString(),resp)
    }

    logger.debug("Response: " + response)
    ctx.put(ContextParams.response,response);   /*ContextParams is a enum of keywords, having response*/
    return false;
}

private OutputStream downloadStatusFile(String filename,HttpServletResponse resp)
{
    logger.info("Inside downloadStatusFile() method")

    File fname = new File(filename)
    if(!fname.exists())
    {   
        logger.info("$filename does not exists")
        return null
    }
    else
    {

        resp.setContentType("APPLICATION/xml")
/*Exception: cannot setContentType on null object*/

        resp.addHeader("Content-Disposition", "attachment; filename=\""+fname.getName()+"\"")

        FileInputStream istr = new FileInputStream(fname)
        OutputStream ostr = resp.getOutputStream()
        /*I need to use resp.getOutputStream() for ostr*/

        int curByte=-1;

        while( (curByte=istr.read()) !=-1)
            ostr.write(curByte)

        ostr.flush();           
    }               
    return ostr
}

}

My question is how can ostr be returned to the response in DownloadStatus class?

Update (working test servlet)

I have this below servlet which does the job of getting file content into a stream and giving it back to the HttpServletResponse, but i want to use it in above code

    public class DownloadServlet extends HttpServlet {


public void doGet(HttpServletRequest req, HttpServletResponse resp)
throws ServletException, IOException {

    String fileName = req.getParameter("zipFile");

    if(fileName == null)      return;

        File fname = new File(fileName);
        System.out.println("filename"); 
        if(!fname.exists())  {System.out.println("Does not exists");            return;}

        FileInputStream istr = null;
        OutputStream ostr = null;
        //resp.setContentType("application/x-download");
        resp.setContentType("APPLICATION/ZIP"); 
        resp.addHeader("Content-Disposition", "attachment; filename=\""+fname.getName()+"\"");
        System.out.println(fname.getName()); 
        try {  
          istr = new FileInputStream(fname);
          ostr = resp.getOutputStream();
          int curByte=-1;

                while( (curByte=istr.read()) !=-1)
                    ostr.write(curByte);

          ostr.flush();
        } catch(Exception ex){
          ex.printStackTrace(System.out);
        } finally{
          try {
            if(istr!=null)  istr.close();
            if(ostr!=null)  ostr.close();
          } catch(Exception ex){

              ex.printStackTrace();
            System.out.println(ex.getMessage());
          }
        }  
        try {
            resp.flushBuffer();
        } catch(Exception ex){
            ex.printStackTrace();
            System.out.println(ex.getMessage());
        }
    }
 }
10
  • why you playing around with streams and Servlet API directly while it can be done with stream result Commented Jan 12, 2012 at 7:19
  • ostr is OutputStream, but response is HttpServletResponse. Wha do you mean with ostr returned to response? Commented Jan 12, 2012 at 7:32
  • @Umesh: I am not familiar with downloading stuff! so what I came to work out @ first I am following it, help me out if there is a better way :) thanks Commented Jan 12, 2012 at 9:17
  • @splix: Hi, I updated my question to include my test servlet which does the job to download the file Commented Jan 12, 2012 at 9:18
  • here are few quick references (struts.apache.org/2.0.14/docs/stream-result.html) , (struts.apache.org/2.2.1/struts2-core/apidocs/org/apache/struts2/…) Commented Jan 12, 2012 at 9:19

1 Answer 1

3

As far as I understand all you require is how to download a file using Struts2.

You need something like this is your struts.xml file

<action name="downloadfile" class="DownloadAction">
           <result name="success" type="stream">
               <param name="contentType">application/pdf</param>
               <param name="inputName">inputStream</param>
               <param name="contentDisposition">attachment;filename="document.pdf"</param>
               <param name="bufferSize">1024</param>
           </result>
       </action>

Code:

public class DownloadAction extends ActionSupport {

  private InputStream inputStream;

  public InputStream getInputStream() {
    return inputStream;
  }

  public void setInputStream(InputStream inputStream) {
    this.inputStream = inputStream;
  }

  public String execute() throws FileNotFoundException {
    String filePath = ServletActionContext.getServletContext().getRealPath("/uploads");
    File f = new File(filePath + "/nn.pdf");
    System.out.println(f.exists());
    inputStream = new FileInputStream(f);
    return SUCCESS;
  }
}
Sign up to request clarification or add additional context in comments.

3 Comments

Prime example of why linking to external sources is generally frowned upon. Link is now dead, and this answer make little sense.
@thecoshman I've added action code, hope this makes sense now. Sorry for the broken link, I've removed it.
@XCodernice work man. Not sure how I got on this question, wasn't really what I was after, but got intrigued non the less and noticed your link was dead.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.