2010-11-09 75 views
2

我有一个需要提供二进制内容(图像)的JSF 1.2/Spring Web流程2.0.7应用程序。这些内容是作为Base64编码的字符串从Web服务(连同其他一些数据)中提取的,并且与其余数据一起在bean中结束。我怎样才能让图像显示在我的网页上?如何从JSF/Webflow应用程序提供二进制内容?

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

回答

6

您想要以<h:graphicImage>组件中的图像结束,对吗?从理论上讲,你可以使用data URI format

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

但是,你有问题,它不适用于所有当前的浏览器。例如,MSIE将URI的长度限制为32KB。

如果这些图片通常较大,或者您希望支持过时的浏览器,那么您当前最好的选择是让它指向一个完整的URL ,毕竟

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

有两种方法可以得到这个工作:

  1. 暂时写入图像公共web内容,并引用它通常的方式。

    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}" /> 
    

    如果战争扩大,您有写权限的磁盘文件系统但是,这仅适用。您还需要考虑清理。 A 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}" /> 
    

    创建它映射在/images/*url-pattern并不会像在doGet()方法如下一个HttpServlet

    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. 
    
+0

非常感谢您的回答。最后一部分是我最终做的,除了包含数据的bean在WebFlows流程范围内,而不是在任何JSF范围内。所以我在流中将一些代码从SWFs流范围复制到会话中。然后我从Servlet中的会话中检索数据。这有点哈克,但我找不到更好的方法来做到这一点。 – mranders 2010-11-11 09:26:04

2
  1. 获取响应的对象(在JSF - FacesContext.getCurrentInstance().getExternalContext().getResponse(),并浇铸成HttpServletResponse)或the OutputStream(JSF 2.0,上述最后一个方法调用将getResponseOutputStream()

  2. 使用所述响应的OutputStreamwrite方法

  3. 设置适当Content-Type

+0

'print'? 'write'! 'ExternalContext#getResponseOutputStream()'只是简单的JSF 2.0。 – BalusC 2010-11-09 13:19:38

+0

啊,是的,写:) – Bozho 2010-11-09 13:21:08

+0

我会在哪里放这段代码?我没有JSF控制器或任何东西,只是一堆webflow XML。 – mranders 2010-11-09 13:32:12