2013-08-05 42 views
2

我正在爲我的項目之一使用Spring MVC和REST服務。我有一項服務來附加和下載用戶文件。 我使用以下服務API上傳和保存文件到服務器目錄通過Spring MVC控制器使用流下載文件

http://myrestserver/attachmentService/attach/userKey 

及以下從服務器目錄服務API下載文件

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

的問題是,當一個文件被下載時,下載的URL顯示REST服務API URL。爲了避免這種情況,我想爲連接和下載文件編寫一個控制器。

我寫了一個處理文件附件過程的彈簧控制器。即使我編寫了一個用於下載文件的控制器(如download.do),但是當下載一個文件時,文件名顯示爲與控制器相同的名稱(下載的文件名始終顯示爲"download.do"),而不是原始文件名。

下面的代碼是從我download.do控制器

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); 
       } 
     } 

而且,在我服務的API,代碼

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(); 

通過分析這個問題,我明白了,我不是設置文件頭中通過download.do控制器下載文件。 如果我在download.do控制器中使用流出,我將無法設置文件頭。

任何人都可以幫助我解決這個問題。我的主要目標是通過MVC控制器通過流下載我的休息服務URL。 我發現堆棧溢出的帖子(Downloading a file from spring controllers)與我的問題差不多,但文件類型是以前已知的。請注意,在我的應用程序中,用戶可以附加任何類型的文件。

回答

3

在將文件寫入輸出流之前,您必須設置Content-Disposition。一旦開始寫入輸出流,就不能再設置標題了。

+0

這是我正在尋找的挑戰。請提供是否有可用的架構解決方案。 –

+0

嗯,我不能肯定地說,因爲您已經省略了相當多的相關代碼,但是看起來您在開始流式傳輸文件後正在設置Content-Disposition。一旦從HttpServletResponse中獲得OutputStream,就不能再設置任何頭文件。 「修復」將重新排序代碼,以便發送所有頭文件,然後獲取操作系統並寫出文件。 – CodeChimp