【问题标题】:Open ResponseEntity PDF in new browser tab在新的浏览器选项卡中打开 ResponseEntity PDF
【发布时间】:2014-03-19 05:04:58
【问题描述】:

我发现了一个有用的 PDF 生成代码,用于在 Spring MVC 应用程序中向客户端显示文件 ("Return generated PDF using Spring MVC"):

@RequestMapping(value = "/form/pdf", produces = "application/pdf")
public ResponseEntity<byte[]> showPdf(DomainModel domain, ModelMap model) {
    createPdf(domain, model);

    Path path = Paths.get(PATH_FILE);
    byte[] pdfContents = null;
    try {
        pdfContents = Files.readAllBytes(path);
    } catch (IOException e) {
        e.printStackTrace();
    }

    HttpHeaders headers = new HttpHeaders();
    headers.setContentType(MediaType.parseMediaType("application/pdf"));
    String filename = NAME_PDF;
    headers.setContentDispositionFormData(filename, filename);
    headers.setCacheControl("must-revalidate, post-check=0, pre-check=0");
    ResponseEntity<byte[]> response = new ResponseEntity<byte[]>(
            pdfContents, headers, HttpStatus.OK);
    return response;
}

我添加了该方法返回 PDF 文件 ("Spring 3.0 Java REST return PDF document") 的声明:produces = "application/pdf"

我的问题是,当上面的代码执行时,它立即要求客户端保存 PDF 文件。我希望先在浏览器中查看 PDF 文件,以便客户端决定是否保存。

我发现 "How to get PDF content (served from a Spring MVC controller method) to appear in a new window" 建议在 Spring 表单标签中添加 target="_blank"。我对其进行了测试,正如预期的那样,它显示了一个新选项卡,但再次出现了保存提示。

另一个是"I can't open a .pdf in my browser by Java" 的添加httpServletResponse.setHeader("Content-Disposition", "inline"); 的方法,但我不使用HttpServletRequest 来提供我的PDF 文件。

根据我的代码/情况,如何在新选项卡中打开 PDF 文件?

【问题讨论】:

    标签: java spring spring-mvc pdf


    【解决方案1】:

    试试

    httpServletResponse.setHeader("Content-Disposition", "inline");
    

    但使用 responseEntity 如下。

    HttpHeaders headers = new HttpHeaders();
    headers.add("content-disposition", "attachment; filename=" + fileName)
    ResponseEntity<byte[]> response = new ResponseEntity<byte[]>(
                pdfContents, headers, HttpStatus.OK);
    

    应该可以的

    对此不确定,但您似乎使用了错误的 setContentDispositionFormData,请尝试>

    headers.setContentDispositionFormData("attachment", fileName);
    

    让我知道这是否有效

    更新

    此行为取决于浏览器和您尝试访问的文件 服务。使用内联,浏览器将尝试在 浏览器。

    headers.setContentDispositionFormData("inline", fileName);
    

    或者

    headers.add("content-disposition", "inline;filename=" + fileName)
    

    阅读本文了解不同之处between inline and attachment

    【讨论】:

    • 您好!我添加了headers.add("content-disposition", "attachment; filename=" + fileName),它仍然要求保存 PDF :( 它没有在新的浏览器选项卡中显示 PDF 文件(感谢您的编辑,是的,我错过了那个)
    • 我在回答中添加了一个更新,尝试使用 inline insead of attachment 进行拍摄
    • headers.add("Content-Disposition", "inline;filename=" + fileName); 成功了(没有另一个)。谢谢!
    • response.setHeader("Content-Disposition:inline", "attachment; filename="+filename);为IE工作
    • 但是如何在headers.add("content-disposition", "inline;filename=" + fileName) 中“编码”fileName?因为"x.txt"; attachment; filename*=UTF-8''trick.exefileName 会混淆客户端对HTTP 标头的解释
    【解决方案2】:

    SpringBoot 2

    使用此代码在浏览器中显示 pdf。 (目录资源中的 PDF -> CLASSPATH) 使用响应实体>

        @GetMapping(value = "/showPDF")
    public ResponseEntity<?> exportarPDF( ){        
        
        InputStreamResource file = new InputStreamResource(service.exportPDF());
        
        return ResponseEntity.ok()
                .header(HttpHeaders.CONTENT_DISPOSITION, "inline;attachment; filename=ayuda.pdf")
                .contentType(MediaType.APPLICATION_PDF)
                .body(file);            
    }
    
    
    
    
    @Service
    public class AyudaServiceImpl implements AyudaService {
        private static final Logger LOGGER = LoggerFactory.getLogger(LoadPDF.class);
        
        LoadPDF  pdf = new LoadPDF();
        
        public InputStream exportPDF() {    
            LOGGER.info("Inicia metodo de negocio :: getPDF");                  
            return pdf.getPDF();
        }
    }
    

    ---分类

    import java.io.File;
    import java.io.FileInputStream;
    import java.io.IOException;
    import java.io.InputStream;
    
    import org.slf4j.Logger;
    import org.slf4j.LoggerFactory;
    import org.springframework.util.ResourceUtils;
    
    
    public class LoadPDF {
        
        private static final Logger LOGGER = LoggerFactory.getLogger(LoadPDF.class);
        public  InputStream getPDF(){        
                   
            try {
                File file = ResourceUtils.getFile("classpath:ayuda.pdf");
                LOGGER.debug("Ruta del archivo pdf: [" + file + "]");
                InputStream in = new FileInputStream(file);
                LOGGER.info("Encontro el archivo PDF");
                return in;
            } catch (IOException e) {
                LOGGER.error("No encontro el archivo PDF",e.getMessage());
                throw new AyudaException("No encontro el archivo PDF", e ); 
            }
        }
    }
    

    【讨论】:

      【解决方案3】:
      /* Here is a simple code that worked just fine to open pdf(byte stream) file 
      * in browser , Assuming you have a a method yourService.getPdfContent() that 
      * returns the bite stream for the pdf file
      */
      
      @GET
      @Path("/download/")
      @Produces("application/pdf")
      public byte[] getDownload() {
         byte[] pdfContents = yourService.getPdfContent();
         return pdfContents;
      }
      

      【讨论】:

      【解决方案4】:

      发生的情况是,由于您“手动”为响应提供了标头,因此 Spring 没有添加其他标头(例如,produces="application/pdf")。这是使用 Spring 在浏览器中显示 pdf 内联的最少代码:

      @GetMapping(value = "/form/pdf", produces = "application/pdf")
      public ResponseEntity<byte[]> showPdf() {
          // getPdfBytes() simply returns: byte[]
          return ResponseEntity.ok(getPdfBytes());
      }
      

      【讨论】:

        猜你喜欢
        • 2016-09-24
        • 2015-06-11
        • 2016-05-04
        • 2021-03-25
        • 2018-11-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多