3 Replies Latest reply on Oct 11, 2007 9:12 PM by jdbastin

    Possible MediaOutput Size Limitation

      I have a Seam application which takes an uploaded image via the s:fileUpload JSF tag and then renders it using the RF mediaOutput JSF tag. The problem that I am stuck at is that any image over 5K prevents the image renderer from being called. Everything works fine for images under 5K so I was wondering if there is a max image size setting that I should be configuring for the mediaOutput tag? I have tried using a custom serialized class instead of the byte array but the results are the same. There is no error thrown but the paint method just never gets called for anything above 5K. I determined the limit by outputting the array size of the picture after it was set in the backing bean post-upload. The disconnect has to be where the mediaOutput value is passed to the paint method as the second parameter. Any help would be appreciated. Thanks.

      Renderer definition in faces-config.xml
      
      <managed-bean>
       <managed-bean-name>paintBean</managed-bean-name>
       <managed-bean-class>com.company.kiosk.beans.PaintBean</managed-bean-class>
       <managed-bean-scope>session</managed-bean-scope>
      </managed-bean>
      

      Renderer Code
      
      public class PaintBean implements Serializable {
      
       public void paint(OutputStream out, Object data) throws IOException{
       System.out.println("in paint bean"); // NEVER OUTPUT FOR IMAGES OVER 5K
      
       byte byteArray[] = (byte[]) data;
       out.write(byteArray);
      
       }
      }
      


      Backing bean that stores the uploaded image
      @Name("fileService")
      @Scope(SESSION)
      public class FileService implements Serializable, SharedNamespace {
       protected byte[] picture;
       protected String pictureContentType;
       protected String fileName;
       ...
      }
      


      JSF tags used for uploading and rendering
      <s:fileUpload data="#{fileService.picture}" fileName="#{fileService.fileName}" contentType="#{fileService.pictureContentType}" accept="images/gif,images/jpg" id="logo" />
      
      <a:mediaOutput element="img" cacheable="false" session="true" createContent="#{paintBean.paint}" value="#{fileService.picture}" mimeType="image/jpeg, image/gif" />
      


        • 1. Re: Possible MediaOutput Size Limitation
          alexsmirnov

          "value" attribute for a mediaOutput component encoded as part of the image URL, and designed for a store small rendering parameters ( in this case, remdering method can be implemented with "lightweight" design pattern ).
          In your case, it can be name or ID of the uploaded image, to find it in session bin or database.
          Also, i have a second remark -, "mimeType " attribute define a http response header, and can't contain more then one value like "image/jpeg, image/gif".

          • 2. Re: Possible MediaOutput Size Limitation

            Thanks Alex. I updated the MIME type so that it is a single value. Also, according to the documentation for the value attribute:

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


            This makes me believe that the 5K limit is the threshold for "big objects" but how can I get the byte array into the PaintBean without using the value attribute to pass it in? Normally, I would use Seam's injection mechanism but PaintBean is special because it is declared in faces-config.xml. Do you have an example of how I can access the correct context for PaintBean to get data from my Seam based backing bean? Thanks again.

            • 3. Solution: Possible MediaOutput Size Limitation

              For anyone interested in the solution to this mediaOutput issue, I simply changed the JSF tag to use a key for the value instead of the entire byte array.


              .xhtml file
              
              <a:mediaOutput element="img" cacheable="false" session="true" createContent="#{paintBean.paint}" value="#{logo.pictureKey}" mimeType="image/jpeg" rendered="#{logo.picture ne null}" />
              


              Then, to get the actual byte array from the Seam managed backing bean into the PaintBean that was declared in the faces-config.xml file, I used the following code to set the newly uploaded image:

              Seam Backing Bean
              
              FacesContext.getCurrentInstance().getExternalContext().getSessionMap().put(getPictureKey(), picture);
              


              and to retrieve it within the PaintBean after the mediaOutput tag passed in the key, I used:

              PaintBean managed outside of Seam
              
               public void paint(OutputStream out, Object data) throws IOException{
              
               String pictureKey = (String) data;
               byte[] byteArray = (byte[]) FacesContext.getCurrentInstance().getExternalContext().getSessionMap().get(pictureKey);
               out.write(byteArray);
               }