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

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

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

你想在组件中得到那个图像,对吧? 理论上,您可以使用data URI格式 。

  

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

如果这些图片通常较大或者您也想支持过时的浏览器,那么您目前最好的选择就是让它指向一个值得信赖的URL。

  

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

  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!) 

    并使用如下:

      

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

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

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

    并且视图看起来像这样:

      

    创建一个映射在/images/*url-pattern上的HttpServlet ,并在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. 获取响应对象(在jsf – FacesContext.getCurrentInstance().getExternalContext().getResponse() ,并转换为HttpServletResponse )或the OutputStream (JSF 2.0,上面的最后一个方法调用将是getResponseOutputStream()

  2. 在响应的OutputStream上使用write方法

  3. 设置正确的Content-Type标头