Search code examples
javajspjbossstruts2weblogic

Getting the jsp source code appended with the file content when I download files


I am working on a File upload/download functionality, in Java using Struts2 framework, where we are uploading to and downloading from a remote server path. All seems to work fine when I check the functionality at my local machine with a local path as the destined path from where i am downloading and to which am uploading the files of any format. The development environment has JBoss server. But when I run the same over at the prod env, where the application is deployed in Weblogic server, files of .txt,.csv,.html (basically text format files) have my jsp source code appended to the file content. Below is the code that I have used for downloading:

BufferedOutputStream bout=null;
FileInputStream inStream = null;
byte[] buffer = null;

try {   
    inStream = new FileInputStream(path+File.separator+filename);       
    buffer = new byte[8192];
    String extension = "";
    int pos = filename.lastIndexOf(".");
    if (pos > 0) 
        extension = filename.substring(pos+1);

    int bytesRead = 0, bytesBuffered = 0;   

    response.setContentType("application/octet-stream");
    response.setHeader("content-disposition", "attachment; filename="+ filename);               
    bout = new BufferedOutputStream(response.getOutputStream());

    while((bytesRead = fistrm.read(buffer)) > -1){                  
        bout.write(buffer, 0, bytesRead);
        bytesBuffered += bytesRead;
        if(bytesBuffered > 1048576){
            bytesBuffered = 0;
            bout.flush();
        }

    }           
} catch (IOException e) {
    log.error(Logger.getStackTrace(e));         
} finally {             
    if(bout!=null){
        bout.flush();
        bout.close();
    }
    if(inStream!=null)
        inStream.close();               

}   

I have tried using different response content types with respect to the extension, but it was of no help. Seems like the outputstream has the jsp source code in it even before writing from the inputstream.

Can anyone please suggest a solution and explain why is this happening ?


Solution

  • It is happening because you are writing directly in the outputstream, and then returning a struts result, that is your JSP. You are using an action as if it would be a servlet, which is not.

    In Struts2, to achieve your goal, you need to use the Stream result type, as described in the following answers:

    Otherwise, if you want to bypass the framework mechanisms and manually write to the outputStream by yourself (there are very rare cases in which it is useful, like downloading dynamically created ZIP), then you must return the NONE result.

    Returning ActionSupport.NONE (or null) from an Action class method causes the results processing to be skipped. This is useful if the action fully handles the result processing such as writing directly to the HttpServletResponse OutputStream.

    But I strongly suggest you to go with the Stream result, the standard way.