2013-08-05 40 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