如何在java web应用程序中将byte []作为pdf发送到浏览器?

mar*_*osh 18 java jsf file download

在动作方法(JSF)中我有类似下面的内容:

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

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

Bal*_*usC 53

在action方法中,您可以从JSF hoods下获取HTTP servlet响应ExternalContext#getResponse().然后,您需要至少设置HTTP Content-Type标头application/pdf和HTTP Content-Disposition标头attachment(当您想要弹出另存为对话框时)或inline(当您想让webbrowser处理显示本身时).最后,您需要确保FacesContext#responseComplete()事后打电话以避免IllegalStateException飞来飞去.

开球示例:

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.
}
Run Code Online (Sandbox Code Playgroud)

也就是说,如果你有可能将PDF内容作为一个InputStream而不是一个byte[],我建议使用它来代替从内存中保存webapp.然后你就可以用众所周知的方式编写它InputStream- OutputStream循环使用通常的Java IO方式.


Col*_*ert 5

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

<%@ page contentType="application/x-pdf" %>
Run Code Online (Sandbox Code Playgroud)

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

使用servlet,您可以使用:

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

资源: