2

I am using spring MVC with REST service for one of my project. I am having a service to attach and download user files. I am using below service API for upload and save file into server directory

http://myrestserver/attachmentService/attach/userKey

And below service API for download files from server directory

http://myrestserver/attachmentService/download/userKey/fileKey

The issue is that when a file is downloaded, the downloaded URL shows the REST service API URL. To avoid this, I thought of write a controller for attach and download file.

I wrote a spring controller which handle file attachment process. Even I wrote a controller(say download.do) for download a file, but when a file downloaded, the file name shows as the same name of the controller(downloaded file name shows "download.do" always) instead of original file name.

Below code is from my download.do controller

WebResource resource = null;
resource = client.resource("http://myrestserver/attachmentService/download/userKey/fileKey");   
 clientResponse = resource.accept(MediaType.APPLICATION_OCTET_STREAM).get(
                    ClientResponse.class);
        InputStream inputStream = clientResponse.getEntityInputStream();
        if(inputStream != null){
              byteArrayOutputStream = new ByteArrayOutputStream();
              try {
              IOUtil.copyStream(inputStream, byteArrayOutputStream);
              } catch (IOException e) {

                  log.error("Exception in  download:"+ e);
              }
        }

And, in my service API, the code is

file = new File(directory, attachmentFileName);

                            fileOutputStream = new FileOutputStream(file);
                            fileOutputStream.write(attachmentContent);
                            fileOutputStream.close();
                            response = Response.ok((Object) file).type(MediaType.APPLICATION_OCTET_STREAM);
                            response.header("Content-Disposition", "attachment; filename=" + "\"" + attachmentFileName
                                    + "\"");
                            return response.build();

By analyzing the issue, I understood that, am not setting file header in downloaded file through download.do controller. If I am using outstream in download.do controller, I will not be able to set the file header.

Can any one help me to resolve this issue. My primary aim is to hide my rest service URL from downloaded file by stream through a MVC controller. I found a post (Downloading a file from spring controllers )in stack overflow almost like my question, but the file type is previously known. Please note that, in my application user can attach any type of file.

Community
  • 1
  • 1
Javad Shareef
  • 496
  • 7
  • 18

1 Answers1

3

You have to set the Content-Disposition prior to writing the file to the output stream. Once you start writing to the output stream, you cannot set headers any longer.

CodeChimp
  • 8,016
  • 5
  • 41
  • 79
  • This is the challenge I am looking for. Please provide if any architectural solution available. – Javad Shareef Aug 20 '13 at 09:25
  • Well, I can't say for certain, as you have omitted quite a bit of the relevant code, but it looks like you are setting your Content-Disposition after you start streaming your file. Once you get the OutputStream from the HttpServletResponse, you cannot set any more headers. The "fix" would be to re-order the code so that all the headers are sent, then you get the OS and write out the file. – CodeChimp Aug 20 '13 at 11:44