a4j:mediaOutput and large objects as value

Version 3

    As you know from tld documentation of media output for value attribute:

     

     

    IMPORTANT: Since serialized data stored in URI, avoid using big objects"
    

     

    But in real applications data objects for output could be really huge so we created sample of working with them using the component,.

     

    The solution uses special session scoped object which will handle objects by short keys. So the URI will not contains the whole object anymore. In order not depend on Seam and jboss EL we also created simple facelet function which could be used in facelets templates to refer to the object by the key.

     

    Attached is Maven application that shows this in action.

     

    And here is the overview of what should be done to add the solution to your application:

     

    1) Put data-helper-taglib.xml into WEB-INF folder

    2) Copy Java classes from org.richfaces.datahelper package to application code

    3) Register function in web.xml:

     

    <context-param>
    <param-name>javax.faces.FACELETS_LIBRARIES</param-name>
    <param-value>/WEB-INF/data-helper.taglib.xml</param-value>
    </context-param>
    

     

     

    Usage in application

     

    1) 1. Declare xmlns:sdh="http://richfaces.org/session-data-helper" namespace in Facelets files like this:

    <ui:composition xmlns="http://www.w3.org/1999/xhtml"
       xmlns:ui="http://java.sun.com/jsf/facelets"
       xmlns:h="http://java.sun.com/jsf/html"
       xmlns:f="http://java.sun.com/jsf/core"
       xmlns:sdh="http://richfaces.org/session-data-helper"
       xmlns:a4j="http://richfaces.org/a4j">
       ...
    

    2. Enclose data expressions in function call:

    Was:

    <a4j:mediaOutput element="img" cacheable="false" session="true"
                   createContent="#{graphBean.paint}"
                   value="#{bean.selectedImageData}"
                   mimeType="image/png" />
    

    Will be:

    <a4j:mediaOutput element="img" cacheable="false" session="true"
                   createContent="#{graphBean.paint}"
                   value="#{sdh:storeDataAndGetKey(bean.selectedImageData)}"
                   mimeType="image/png" />
    
     

    3. Unwrap data in "createContent" method before using:

       public void paint(OutputStream out, Object data) throws IOException {
           Object restoredData = SessionDataHelper.getDataByKey(data); 
           //use restored data
           //render image from stored bytes
           //...
           byte[] pictureData = ((Data) restoredData).getPictureData();
           out.write(pictureData);
       }