如何从JSF / Webflow应用程序提供二进制内容?

时间:2010-11-09 13:09:41

标签: java jsf streaming spring-webflow

我有一个需要提供二进制内容(图像)的JSF 1.2 / Spring Web flow 2.0.7应用程序。此内容作为Base64编码的字符串从Web服务(以及其他一些数据)中获取,并最终在bean中与其余数据一起结束。如何将图像显示在我的网页上?

注意:不,没有办法让Web服务直接传输数据,甚至没有其他所有东西从Web服务中获取二进制数据。

2 个答案:

答案 0 :(得分:6)

您希望最终在<h:graphicImage>组件中使用该图片,对吗?从理论上讲,您可以使用data URI format来实现此目的。

<h:graphicImage value="data:image/png;base64,#{bean.base64Image}" />

但是,您遇到的问题是它无法在所有当前浏览器中运行。例如,MSIE将data URI的长度限制为32KB。

如果这些图片通常较大,或者您也想支持过时的浏览器,那么您目前最好的选择是让它在所有之后指向一个完整的网址

<h:graphicImage value="images/filename.png" />

有两种方法可以让它发挥作用:

  1. 暂时将图像写入公共网页内容并以通常的方式引用它。

    this.uniqueImageFileName = getOrGenerateItSomehow();
    byte[] imageContent = convertBase64ToByteArraySomehow();
    ExternalContext ec = FacesContext.getCurrentInstance().getExternalContext();
    ServletContext sc = (ServletContext) ec.getContext();
    File image = new File(sc.getRealPath("/images"), uniqueImageFileName);
    // Write byte[] to FileOutputStream on that file the usual way (and close!)
    

    使用如下:

    <h:graphicImage value="images/#{bean.uniqueImageFileName}" />
    

    但是,只有在扩展WAR并且您具有磁盘文件系统的写权限时,此操作才有效。您还需要考虑清理。 HttpSessionListener可能会有所帮助。

  2. 将二进制数据存储在会话中并使用HttpServlet进行提供。假设您的bean是请求范围:

    this.uniqueImageFileName = getOrGenerateItSomehow();
    byte[] imageContent = convertBase64ToByteArraySomehow();
    ExternalContext ec = FacesContext.getCurrentInstance().getExternalContext();
    ec.getSessionMap().put(uniqueImageFileName, imageContent);
    

    并且视图如下所示:

    <h:graphicImage value="images/#{bean.uniqueImageFileName}" />
    

    创建HttpServlet映射到url-pattern /images/*的{​​{1}},并在doGet()方法中执行以下操作:

    String uniqueImageFileName = request.getPathInfo().substring(1);
    byte[] imageContent = (byte[]) request.getSession().getAttribute(uniqueImageFileName);
    response.setContentType("image/png"); // Assuming it's always PNG.
    response.setContentLength(imageContent.length);
    // Write byte[] to response.getOutputStream() the usual way. 
    

答案 1 :(得分:2)

  1. 获取响应对象(在jsf - FacesContext.getCurrentInstance().getExternalContext().getResponse()中,并转换为HttpServletResponse)或the OutputStream(JSF 2.0,上面的最后一个方法调用将是{{1} })

  2. 在回复的getResponseOutputStream()

  3. 上使用write方法
  4. 设置正确的OutputStream标题