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

mra*_*ers 2 java streaming jsf spring-webflow

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

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

Bal*_*usC 6

你想在<h:graphicImage>组件中得到那个图像,对吧?从理论上讲,您可以使用dataURI格式.

<h:graphicImage value="data:image/png;base64,#{bean.base64Image}" />
Run Code Online (Sandbox Code Playgroud)

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

如果这些图像是在一般较大,或者你想支持过时的浏览器为好,那么你现在最好的办法就是真正让它指向fullworthy URL 毕竟.

<h:graphicImage value="images/filename.png" />
Run Code Online (Sandbox Code Playgroud)

有两种方法可以使其工作:

  1. 暂时将图像写入公共webcontent并以通常的方式引用它.

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

    并使用如下:

    <h:graphicImage value="images/#{bean.uniqueImageFileName}" />
    
    Run Code Online (Sandbox Code Playgroud)

    但是,只有在扩展WAR且您具有磁盘文件系统的写权限时才能使用此功能.您还需要考虑清理.A HttpSessionListener可能对此有所帮助.

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

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

    并且视图看起来像这样:

    <h:graphicImage value="images/#{bean.uniqueImageFileName}" />
    
    Run Code Online (Sandbox Code Playgroud)

    创建一个HttpServlet映射到的url-pattern方法/images/*,并在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. 
    
    Run Code Online (Sandbox Code Playgroud)