2013-11-09 36 views
1

您好像寫了如下的控制器類。我正在嘗試從mongo db獲取文件並嘗試下載它。如何在Spring mvc和mongodb中下載文件

organizationFileAttachmentService.setUser(getUser()); 
    GridFSDBFile file = organizationFileAttachmentService.getGridFSDBFileById(new ObjectId(id), "File"); 
    if (file != null) { 
     byte[] content = organizationFileAttachmentService.findByIdAndBucket(new ObjectId(id), "File"); 
     try { 
      int size = content.length; 
      InputStream is = null; 
      byte[] b = new byte[size]; 
      try { 
       is = new ByteArrayInputStream(content); 
       is.read(b); 
      } catch (IOException e) { 
       e.printStackTrace(); 
      } finally { 
       try { 
        if (is != null) 
         is.close(); 
       } catch (Exception ex) { 

       } 
      } 
      response.setContentType(file.getContentType()); 
      // String attachment = 
      // "attachment; filename=\""+file.getFilename()+"\""; 
      String attachment = "attachment; filename=" + file.getFilename(); 
      // response.setContentLength(new 
      // Long(file.getLength()).intValue()); 
      response.setCharacterEncoding(file.getMD5()); 
      response.setHeader("content-Disposition", attachment);// "attachment;filename=test.xls" 
      // copy it to response's OutputStream 
      // FileCopyUtils.copy(is, response.getOutputStream()); 
      IOUtils.copy(is, response.getOutputStream()); 
      response.flushBuffer(); 
      is.close(); 
     } catch (IOException ex) { 
      _logger.info("Error writing file to output stream. Filename was '" + id + "'"); 
      throw new RuntimeException("IOError writing file to output stream"); 
     } 

但我無法下載文件。誰能幫我。

+0

行'response.setCharacterEncoding(file.getMD5());'是INCrecr。 CharacterEncoding必須是「UTF-8」或其他類似的。 –

回答

1

我已經改變了我的請求作爲GET,並添加請求錨定標記在HTML中。 Aslo更改我的代碼爲

@RequestMapping(value = "/getFileById/{id}", method = RequestMethod.GET) 
public @ResponseBody 
void download(@PathVariable String id, HttpServletRequest request, HttpServletResponse response) throws IOException { 
    organizationFileAttachmentService.setUser(getUser()); 
    GridFSDBFile file = organizationFileAttachmentService.getGridFSDBFileById(new ObjectId(id), "File"); 
    if (file != null) { 
     try { 
      response.setContentType(file.getContentType()); 
      response.setContentLength((new Long(file.getLength()).intValue())); 
      response.setHeader("content-Disposition", "attachment; filename=" + file.getFilename());// "attachment;filename=test.xls" 
      // copy it to response's OutputStream 
      IOUtils.copyLarge(file.getInputStream(), response.getOutputStream()); 
     } catch (IOException ex) { 
      _logger.info("Error writing file to output stream. Filename was '" + id + "'"); 
      throw new RuntimeException("IOError writing file to output stream"); 
     } 
    } 
} 

現在它對我來說工作正常。

4

如果你錯過了,Spring提供了各種內置的資源處理程序。

http://docs.spring.io/spring/docs/3.2.5.RELEASE/spring-framework-reference/html/resources.html#resources-implementations

如果你的方法返回其中之一(也許在你的情況下,使用ByteArrayResource),那麼你只需要幾個註釋的接口上,像這樣:

@RequestMapping(value = "/foo/bar/{fileId}", 
    method = RequestMethod.GET, 
    produces = { MediaType.APPLICATION_OCTET_STREAM_VALUE }) 
@ResponseBody FileSystemResource downloadFile(Long fileId); 

沒有與編碼擺弄和標題爲你這樣。我建議在滾動自己之前嘗試一下。

編輯:上面在Spring 3.1.4中運行良好。它不再適用於3.2.x或4.x.而之前的產品= {MediaType.APPLICATION_OCTET_STREAM_VALUE}會導致Spring添加適當的頭文件,現在將其視爲限制。如果使用標準Web瀏覽器訪問URL,則不會發送「application/octet-stream」的接受標頭。 Spring將因此返回一個406錯誤。爲了再次使用它,這種方法需要重寫而沒有「產生」屬性。相反,將HttpServletResponse添加到方法參數並在方法內添加頭部。即:

@RequestMapping(value = "/foo/bar/{fileId}", 
    method = RequestMethod.GET) 
@ResponseBody FileSystemResource downloadFile(
      Long fileId, HttpServletResponse response) { 
    ... 
    response.setHeader("Content-Disposition", "attachment;filename=" + fileName); 
    ... 
} 

編輯終極版: 現在通過Spring 1.1.8啓動使用Spring 4.0.7。看來設置produces = { MediaType.APPLICATION_OCTET_STREAM_VALUE }指令現在可以再次運行。只要有這樣的指示,對於我嘗試過的所有瀏覽器來說就足夠了。但請注意,我還發現它不會設置Content-Disposition,它保留爲application/json。儘管這對瀏覽器來說似乎沒有問題,但我遇到了PHP客戶端應用程序中的錯誤,這些錯誤似乎僅基於Content-Disposition。因此,目前的解決方案似乎是做到以上兩點!

相關問題