将ModelAndView Spring MVC PDF对象作为可保存附件返回

时间:2015-12-17 12:43:05

标签: java spring spring-mvc pdf

我没有太多的Spring MVC经验。我继承了一些RESTful控制器代码,用于在数据库中查找记录并使用

org.springframework.web.servlet.view.jasperreports.JasperReportsPdfView to create a PDF view of the record.

以下是方法:

@RequestMapping(value = "/profile/{uniqueId}.pdf", method = RequestMethod.GET)
@ResponseBody
public ModelAndView getProfilePdf(HttpServletRequest request, @PathVariable("uniqueId") String uniqueId {
    Profile profile = getProfileByUniqueId(request, uniqueId);
    Map<String, Object> reportData = buildReportData(profile);
    return new ModelAndView(profileReport, reportData);
}

有很多支持对象和方法,但由于我无法剪切和粘贴代码,所以我暂时将其删除。

这是问题所在。调用URL时,将生成PDF并在浏览器中弹出。如果我编辑浏览器首选项,我可以在Adobe Acrobat中弹出PDF。但我需要的是弹出窗口,询问您是否要打开或保存要显示的文件。

我认为实现这一目标的唯一方法是将Content-disposition设置为附件。

所以我在方法参数中添加了“HttpServletResponse response”并将其添加到代码中:

response.setHeader("Content-disposition", "attachment; filename=profile.pdf");

没有运气。我还尝试添加内容类型:

response.setContentType("application/pdf");

仍然没有运气。

我需要学习如何将ModelAndView对象作为文件附件发回,或者将其转换为字节流并手动将其转发回来?这里没有任何线索。任何想法都将不胜感激。

3 个答案:

答案 0 :(得分:1)

默认情况下,JasperReportsPdfView会将Content-Disposition设置为inline,但前提是标题未预先配置为其他内容。

JasperReportsPdfView有一个名为headers的属性,您可以在其中配置或覆盖要与生成的PDF一起发送的标头。如果您要在其中加入Content-Disposition标题,则可以将其设置为其他内容,例如attachment

<bean id="yourreport" class="org.springframework.web.servlet.view.jasperreports.JasperReportsPdfView">
    <property name="headers">
        <map>
            <entry key="Content-Disposition" value="attachment; profile.pdf" />
        </map>
    <property>
</bean>

这样的事情可以解决问题(而不是map你还可以使用props元素。)

答案 1 :(得分:0)

您需要做的是将PDF文件的字节直接流式传输到输出流并刷新响应。在Spring中你可以这样做:

@RequestMapping(value="/displayProcessFile/{processInstanceId}", method=RequestMethod.GET)
public ResponseEntity<byte[]> displayProcessFile(@PathVariable String processInstanceId) throws UnauthorizedUserAccessException{
    Document processFile=null;
    try {
        processFile = documentService.retrieveProcessFile(Long.parseLong(processInstanceId));
    } catch (ProcessFileNotFoundExpection e) {
        e.printStackTrace();
    }
    HttpHeaders headers = new HttpHeaders();
    headers.setContentType(MediaType.parseMediaType("application/pdf"));
    headers.add("content-disposition", "inline;filename=" + processFile.getDocName());
    ResponseEntity<byte[]> response = new ResponseEntity<byte[]>(processFile.getContent(), headers, HttpStatus.OK);
    return response;
}

答案 2 :(得分:-6)

也许您必须更改浏览器设置,以便在直接打开文件之前每次都会询问。

请找到链接:http://malektips.com/google-chrome-prompt-download-file.html#.VnLAgbiGRHw

此外,您还必须设置:

response.setContentType( “应用程序/下载”);

response.setHeader(“Content-disposition”,“attachment; filename = profile.pdf”);