HttpServletResponse.addHeader()和setHeader()在Spring控制器中不工作
我正在尝试使用SpringMVC、SpringBoot和SpringSecurity构建一个小型web应用程序。只使用一个控制器,其中一个服务端点是让用户下载由web应用程序生成的docx文件。我的逻辑代码工作得很好,问题是当我想向HttpServletResponse添加头时,addHeader()和setHeader()不起作用,我只想为下载文件指定一个名称。我打印了一些日志,但不知道为什么这不起作用 以下是我的控制器的部件代码:HttpServletResponse.addHeader()和setHeader()在Spring控制器中不工作,spring,spring-mvc,servlets,httpresponse,Spring,Spring Mvc,Servlets,Httpresponse,我正在尝试使用SpringMVC、SpringBoot和SpringSecurity构建一个小型web应用程序。只使用一个控制器,其中一个服务端点是让用户下载由web应用程序生成的docx文件。我的逻辑代码工作得很好,问题是当我想向HttpServletResponse添加头时,addHeader()和setHeader()不起作用,我只想为下载文件指定一个名称。我打印了一些日志,但不知道为什么这不起作用 以下是我的控制器的部件代码: @Controller public class Impor
@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();
}
}
}
这是我得到的日志,你们可以看到标题“contentdisposition”和“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
谢谢你的阅读。任何帮助都将不胜感激。事实证明,Spring Controller对所有响应都有默认标题,这样我就可以访问响应正文,但不能访问标题。要设置HttpHeader,返回一个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);
}
@RequestMapping(value=“/export”,method=RequestMethod.GET,products=“application/vnd.openxmlformats officedocument.wordprocessingml.document”)
公共HttpEntity导出(@RequestParam(value=“domainName”,required=true)字符串domainName,
@RequestParam(value=“projectName”,required=true)字符串projectName,
@RequestParam(value=“testFolderId”,required=true)int testFolderId){
字符串exportedFileName=“exportedTC”+域名+“\u”+项目名+“\u”
+整数.toString(testFolderId)+“.docx”;
SaveToZipFile saver=null;
ByteArrayOutputStream out=null;
HttpHeaders-responseHeaders=null;
字节[]documentBody=null;
试一试{
extendExpiredALMSession();
saver=wordProcessor.ExportToWord(域名、项目名、整数.toString(testFolderId));
out=新的ByteArrayOutputStream();
保存,保存(输出);
responseHeaders=新的HttpHeaders();
添加(“内容类型”,
“application/vnd.openxmlformatsofcedocument.wordprocessingml.document”);
添加(“内容处置”、“附件;文件名=\”“+exportedFileName+”\”);
documentBody=out.toByteArray();
}catch(RequestFailureException | RESTAPIException | InvalidDataException | UnLoginException
|未经授权的运营例外| IOException | Docx4jeException | URISyntaxException e){
e、 printStackTrace();
}
返回新的HttpEntity(文档主体、负责人);
}
这对我很有效。今天我也遇到了与这里描述的完全相同的问题。我看了一下,发现在内容之前必须设置标题。然后我换了台词,一切都很顺利 在你的情况下,我建议你推这条线
saver.save(response.getOutputStream())
在响应之前。flushBuffer()代码>在所有标题都已设置之后。可能是因为直到响应。flushBuffer()代码>它们实际上还没有被写入响应?我认为在那之前,它们都在缓冲区中,而不一定在对象本身的成员中。