2014-05-07 47 views
0

我試圖用spring-mvc,spring-boot和spring安全構建一個小的web應用程序。只使用一個控制器,其中一個服務端點是讓用戶下載由Web應用程序生成的docx文件。我的邏輯代碼工作正常,問題是,當我想將Headers添加到HttpServletResponse時,addHeader()和setHeader()不起作用,我只想爲下載文件指定一個名稱。我打印了一些日誌,並沒有理解爲什麼這不起作用。HttpServletResponse.addHeader()和setHeader()在彈簧控制器中不工作

這裏是我的控制器的一部分代碼:

@Controller 
public class ImportExportController { 

    private final static Logger LOGGER = LoggerFactory.getLogger(ImportExportController.class); 

    @Autowired 
    private WordProcessor wordProcessor; 

    @RequestMapping("/export") 
    public void export(@RequestParam(value = "domainName", required = true) String domainName, 
         @RequestParam(value = "projectName", required = true) String projectName, 
         @RequestParam(value = "testFolderId", required = true) int testFolderId, 
         HttpServletRequest request, HttpServletResponse response) { 

     String exportedFileName = "exportedTC_" + domainName + "_" + projectName + "_" 
       + Integer.toString(testFolderId) + ".docx"; 

     try { 
      extendExpiredALMSession(); 
      SaveToZipFile saver = wordProcessor.ExportToWord(domainName, projectName, 
                  Integer.toString(testFolderId)); 
      saver.save(response.getOutputStream()); 
      response.setContentType("application/vnd.openxmlformats-officedocument.wordprocessingml.document"); 
      LOGGER.info("exportedFileName: " + exportedFileName); 
      LOGGER.info("contains: " + response.containsHeader("Content-Disposition")); 
      response.addHeader("Content-Disposition", "attachment; filename=\"" + exportedFileName + "\""); 
      for (String name : response.getHeaderNames()) { 
       LOGGER.info("Header: " + name); 
      } 
      LOGGER.info("Date Header:" + response.getHeader("Date")); 
      LOGGER.info("Content-Disposition header: " + response.getHeader("Content-Disposition")); 
      LOGGER.info("ContentType: " + response.getHeader("ContentType")); 
      response.flushBuffer(); 
     } catch (RequestFailureException | RESTAPIException | InvalidDataException | UnLoginException 
       | UnAuthorizedOperationException | IOException | Docx4JException | URISyntaxException e) { 
      e.printStackTrace(); 
     } 
    } 
} 

而且這裏是日誌我得到了,你可以看到頭「內容處置」和「的ContentType」均爲零。

2014-05-07_13:35:05.646 INFO c.c.p.a.w.w.ImportExportController - exportedFileName: exportedTC_DEFAULT_JIRA_Test_CPL5_4520.docx 
2014-05-07_13:35:05.646 INFO c.c.p.a.w.w.ImportExportController - contains: false 
2014-05-07_13:35:05.646 INFO c.c.p.a.w.w.ImportExportController - Header: X-Content-Type-Options 
2014-05-07_13:35:05.646 INFO c.c.p.a.w.w.ImportExportController - Header: X-XSS-Protection 
2014-05-07_13:35:05.646 INFO c.c.p.a.w.w.ImportExportController - Header: Cache-Control 
2014-05-07_13:35:05.647 INFO c.c.p.a.w.w.ImportExportController - Header: Pragma 
2014-05-07_13:35:05.647 INFO c.c.p.a.w.w.ImportExportController - Header: Expires 
2014-05-07_13:35:05.647 INFO c.c.p.a.w.w.ImportExportController - Header: X-Frame-Options 
2014-05-07_13:35:05.647 INFO c.c.p.a.w.w.ImportExportController - Header: X-Application-Context 
2014-05-07_13:35:05.647 INFO c.c.p.a.w.w.ImportExportController - Header: Transfer-Encoding 
2014-05-07_13:35:05.647 INFO c.c.p.a.w.w.ImportExportController - Header: Date 
2014-05-07_13:35:05.647 INFO c.c.p.a.w.w.ImportExportController - Date Header:Wed, 07 May 2014 17:35:05 GMT 
2014-05-07_13:35:05.647 INFO c.c.p.a.w.w.ImportExportController - Content-Disposition header: null 
2014-05-07_13:35:05.647 INFO c.c.p.a.w.w.ImportExportController - ContentType: null 

感謝您的閱讀。任何幫助將不勝感激。

+0

也許是因爲直到'response.flushBuffer();'它們還沒有被寫入響應呢? – developerwjk

+0

嗯..那是什麼? –

+0

我認爲在那之前它的所有內容都在緩衝區中,而不一定在對象本身的成員中。 – developerwjk

回答

1

事實證明,Spring Controller對所有的響應都有默認的頭文件,所以我可以訪問響應體而不是頭文件。要設置HttpHeaders,返回一個HttpEntity將會起作用。以下解決方案代碼:

@RequestMapping(value = "/export", method = RequestMethod.GET, produces = "application/vnd.openxmlformats-officedocument.wordprocessingml.document") 
    public HttpEntity<byte[]> export(@RequestParam(value = "domainName", required = true) String domainName, 
            @RequestParam(value = "projectName", required = true) String projectName, 
            @RequestParam(value = "testFolderId", required = true) int testFolderId) { 

    String exportedFileName = "exportedTC_" + domainName + "_" + projectName + "_" 
      + Integer.toString(testFolderId) + ".docx"; 
    SaveToZipFile saver = null; 
    ByteArrayOutputStream out = null; 
    HttpHeaders responseHeaders = null; 
    byte[] documentBody = null; 
    try { 
     extendExpiredALMSession(); 
     saver = wordProcessor.ExportToWord(domainName, projectName, Integer.toString(testFolderId)); 
     out = new ByteArrayOutputStream(); 
     saver.save(out); 
     responseHeaders = new HttpHeaders(); 
     responseHeaders.add("Content-Type", 
          "application/vnd.openxmlformats-officedocument.wordprocessingml.document"); 
     responseHeaders.add("Content-Disposition", "attachment; filename=\"" + exportedFileName + "\""); 
     documentBody = out.toByteArray(); 
    } catch (RequestFailureException | RESTAPIException | InvalidDataException | UnLoginException 
      | UnAuthorizedOperationException | IOException | Docx4JException | URISyntaxException e) { 
     e.printStackTrace(); 
    } 
    return new HttpEntity<byte[]>(documentBody, responseHeaders); 
    } 

這適用於我。

1

今天我也有像這裏描述的完全相同的問題。我有點暈了一下,在this tutorial中發現,標題必須在內容之前設置。然後,我切換了線條,一切運作良好,就像一個魅力。

在你的情況下,我會建議推行 saver.save(response.getOutputStream());response.flushBuffer();之前,所有頭已經設置。