如何将字节 [] 作为 pdf 发送到 Java Web 应用程序中的浏览器?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/3592058/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-14 02:18:57  来源:igfitidea点击:

How to send byte[] as pdf to browser in java web application?

javafilejsfdownload

提问by marioosh

In action method (JSF) i have something like below:

在操作方法(JSF)中,我有如下内容:

public String getFile() {
  byte[] pdfData = ...
  // how to return byte[] as file to web browser user ?
}

How to send byte[] as pdf to browser ?

如何将 byte[] 作为 pdf 发送到浏览器?

采纳答案by BalusC

In the action method you can obtain the HTTP servlet response from under the JSF hoods by ExternalContext#getResponse(). Then you need to set at least the HTTP Content-Typeheader to application/pdfand the HTTP Content-Dispositionheader to attachment(when you want to pop a Save Asdialogue) or to inline(when you want to let the webbrowser handle the display itself). Finally, you need to ensure that you call FacesContext#responseComplete()afterwards to avoid IllegalStateExceptions flying around.

在 action 方法中,您可以通过ExternalContext#getResponse(). 然后,您至少需要将 HTTPContent-Type标头设置为application/pdf并将 HTTPContent-Disposition标头设置为attachment(当您想要弹出另存为对话框时)或inline(当您想让网络浏览器处理显示本身时)。最后,你需要确保你FacesContext#responseComplete()事后调用以避免IllegalStateExceptions飞来飞去。

Kickoff example:

开场示例:

public void download() throws IOException {
    // Prepare.
    byte[] pdfData = getItSomehow();
    FacesContext facesContext = FacesContext.getCurrentInstance();
    ExternalContext externalContext = facesContext.getExternalContext();
    HttpServletResponse response = (HttpServletResponse) externalContext.getResponse();

    // Initialize response.
    response.reset(); // Some JSF component library or some Filter might have set some headers in the buffer beforehand. We want to get rid of them, else it may collide.
    response.setContentType("application/pdf"); // Check http://www.iana.org/assignments/media-types for all types. Use if necessary ServletContext#getMimeType() for auto-detection based on filename.
    response.setHeader("Content-disposition", "attachment; filename=\"name.pdf\""); // The Save As popup magic is done here. You can give it any filename you want, this only won't work in MSIE, it will use current request URL as filename instead.

    // Write file to response.
    OutputStream output = response.getOutputStream();
    output.write(pdfData);
    output.close();

    // Inform JSF to not take the response in hands.
    facesContext.responseComplete(); // Important! Else JSF will attempt to render the response which obviously will fail since it's already written with a file and closed.
}

That said, if you have the possibility to get the PDF content as an InputStreamrather than a byte[], I would recommend to use that instead to save the webapp from memory hogs. You then just write it in the well-known InputStream-OutputStreamloop the usual Java IO way.

也就是说,如果您有可能将 PDF 内容作为一个InputStream而不是一个byte[],我会建议使用它来从内存猪中保存 web 应用程序。然后,您只需以众所周知的方式编写它InputStream-OutputStream以通常的 Java IO 方式循环。

回答by Colin Hebert

You just have to set the mime type to application/x-pdfinto your response. You can use the setContentType(String contentType)method to do this in the servlet case.
In JSF/JSP you could use this, before writing your response:

您只需将 mime 类型设置application/x-pdf为您的响应。您可以使用setContentType(String contentType)方法在 servlet 情况下执行此操作。
在 JSF/JSP 中,您可以在编写响应之前使用它:

<%@ page contentType="application/x-pdf" %>

and response.write(yourPDFDataAsBytes());to write your data.
But I really advise you to use servlets in this case. JSF is used to render HTML views, not PDF or binary files.

response.write(yourPDFDataAsBytes());写入您的数据。
但我真的建议您在这种情况下使用 servlet。JSF 用于呈现 HTML 视图,而不是 PDF 或二进制文件。

With servlets you can use this :

使用 servlet,您可以使用它:

public MyPdfServlet extends HttpServlet {
    protected doGet(HttpServletRequest req, HttpServletResponse resp){
         OutputStream os = resp.getOutputStream();
         resp.setContentType("Application/x-pdf");
         os.write(yourMethodToGetPdfAsByteArray());
    } 
}


Resources :

资源 :

回答by Vivien Barousse

When sending raw data to the browser using JSF, you need to extract the HttpServletResponsefrom the FacesContext.

使用 JSF 向浏览器发送原始数据时,您需要HttpServletResponseFacesContext.

Using the HttpServletResponse, you can send raw data to the browser using the standard IO API.

使用HttpServletResponse,您可以使用标准 IO API 将原始数据发送到浏览器。

Here is a code sample:

这是一个代码示例:

public String getFile() {
    byte[] pdfData = ...

    FacesContext context = FacesContext.getCurrentInstance();
    HttpServletResponse response = (HttpServletResponse) context.getExternalContext().getResponse();
    OutputStream out = response.getOutputStream();
    // Send data to out (ie, out.write(pdfData)).
}

Also, here are some other things you might want to consider:

此外,您可能还需要考虑以下一些其他事项:

  • Set the content type in the HttpServletResponse to inform the browser you're sending PDF data: response.setContentType("application/pdf");
  • Inform the FacesContext that you sent data directly to the user, using the context.responseComplete() method. This prevents JSF from performing additional processing that is unnecessary.
  • 在 HttpServletResponse 中设置内容类型以通知浏览器您正在发送 PDF 数据: response.setContentType("application/pdf");
  • 使用 context.responseComplete() 方法通知 FacesContext 您将数据直接发送给用户。这可以防止 JSF 执行不必要的额外处理。