4 Replies Latest reply on Mar 12, 2010 8:22 PM by Charles Akalugwu

    Problems with file upload

    Charles Akalugwu Newbie

      Hi,

       

      I have a minor or major issue depending on how you choose to look at it. On my app, i have file upload functionality. Everything works fine with the uploads, no errors whatsoever. My uploaded images are stored in BLOBs in a database. The issue arises when I retrieve these blobs and try to display them on the page. There are no errors but the images do not show up! I have tried various things and it seems there is a slight correlation between how big the image is and if it is able to get displayed on the page. So far, only very very small images show up on the page (sometimes) while the larger ones never get showed. Below is my code.

       

      Web.xml

          <filter>

       

              <display-name>RichFaces Filter</display-name>

       

              <filter-name>richfaces</filter-name>

       

              <filter-class>org.ajax4jsf.Filter</filter-class>
             
              <init-param>
                  <param-name>createTempFiles</param-name>
                  <param-value>false</param-value>
              </init-param>
              <init-param>
                  <param-name>maxRequestSize</param-name>
                  <param-value>1048576</param-value>
              </init-param>

       

          </filter>

       

       

      My Photo Entity Bean:

       

      @Entity
      @Table(name="Photos")
      @Name("photo")
      @Scope(ScopeType.SESSION)
      public class Photo implements Serializable {

       

          private static final long serialVersionUID = 5764974061144989689L;
         
          private Long id;
         
          private Integer version;
         
          private String caption;
         
          private Date modified;
         
          private String mimeType;
         
          private Integer fileSize;
         
          private byte[] content;
         
          private User user;
         
          public Photo(){
             
          }
         
         
          @Id
          @GeneratedValue
          @Column(name="photo_id")
          public Long getId() {
              return id;
          }

       

          public void setId(Long id) {
              this.id = id;
          }
         
          @Version
          public Integer getVersion() {
              return version;
          }

       

          public void setVersion(Integer version) {
              this.version = version;
          }

       

          public String getCaption() {
              return caption;
          }

       

          public void setCaption(String caption) {
              this.caption = caption;
          }

       

          public Date getModified() {
              return modified;
          }

       

          public void setModified(Date modified) {
              this.modified = modified;
          }
         
          public void setMimeType(String mimeType) {
              this.mimeType = mimeType;
          }

       


          public void setFileSize(Integer fileSize) {
              this.fileSize = fileSize;
          }

       


          public Integer getFileSize() {
              return fileSize;
          }

       


          public String getMimeType() {
              return mimeType;
          }

       


          @Lob
          @Basic(optional=false, fetch=FetchType.LAZY)
          public byte[] getContent() {
              return content;
          }

       

          public void setContent(byte[] content) {
              this.content = content;
          }

       

          @ManyToOne(fetch = FetchType.LAZY)
          @JoinColumn(name="user_id")
          public User getUser() {
              return user;
          }

       


          public void setUser(User user) {
              this.user = user;
          }
      }

       

       

      My Facelets Page (sections for uploading and displaying the uploaded images)

       

       


      <h:panelGrid rows="2" rowClasses="rich-fileupload-list-decor , rich-fileupload-list-decor" >
                          <rich:fileUpload fileUploadListener="#{photoUpload.uploadListener}"
                              maxFilesQuantity="#{photoUpload.uploadsAvailable}"
                              id="upload"
                              immediateUpload="#{photoUpload.autoUpload}"
                              acceptedTypes="#{photoUpload.acceptedTypes}" allowFlash="#{photoUpload.useFlash}">
                                  <a4j:support event="onuploadcomplete" reRender="picpanel" />
                          </rich:fileUpload>
                         
                          <rich:panel style="width: 935px; height: 100%; vertical-align: top;" id="picpanel">
                         
                              <f:facet name="header">
                                  <h:outputText value="Uploaded Photos" />
                              </f:facet>
                             
                              <h:outputText value="No files currently uploaded"
                                  rendered="#{photoUpload.size == 0}" />
                                 
                              <rich:dataGrid columns="1" value="#{photoUpload.files}"
                                  var="photo" rowKeyVar="row" elements="10" id="picdata" style="width: 910px;">
                                 
                                  <rich:panel style="width: 900px; height: 80px">
                                 
                                      <h:panelGrid columns="2">
                                     
                                          <a4j:mediaOutput element="img" mimeType="#{photo.mimeType}"
                                              createContent="#{photoUpload.paintPhoto}" value="#{photo}"
                                              style="width:60px; height:60px;" cacheable="true" session="true" />
                                             
                                          <h:panelGrid columns="2">
                                              <h:outputText value="File Name:" />
                                              <h:outputText value="#{photo.caption}" />
                                              <h:outputText value="Photo Size:" />
                                              <h:outputText value="#{photo.fileSize} bytes" />
                                          </h:panelGrid>
                                      </h:panelGrid>
                                  </rich:panel>
                                  <f:facet name="footer" rendered="#{photoUpload.size > 0}">
                                      <rich:datascroller rendered="#{photoUpload.size > 0}"/>
                                  </f:facet>
                              </rich:dataGrid>
                          </rich:panel>
                      </h:panelGrid>

       

       

       

      My Stateful Session Bean which handles the uploads

       

      @Stateful
      @Name("photoUpload")
      @Synchronized( timeout=1000000000)
      @Scope(ScopeType.SESSION)
      public class PhotoUploadBean implements PhotoUpload, Serializable {

       

          private static final long serialVersionUID = 1627470298195374254L;

       

          @Logger
          private Log log;

       

          @PersistenceContext(type = PersistenceContextType.EXTENDED)
          EntityManager em;

       

          @In(required = true, scope = ScopeType.SESSION)
          @Out(scope = ScopeType.SESSION)
          User currentUser;

       

          private List<Photo> files = new ArrayList<Photo>();

       

          private int uploadsAvailable = 10;

       

          private boolean autoUpload = false;

       

          private boolean useFlash = false;

       

          private String acceptedTypes = "jpg, gif, png, bmp";

       

          public List<Photo> getFiles() {
              return files;
          }

       

          public void setFiles(List<Photo> files) {
              this.files = files;
          }

       

          public int getUploadsAvailable() {
              return uploadsAvailable;
          }

       

          public void setUploadsAvailable(int uploadsAvailable) {
              this.uploadsAvailable = uploadsAvailable;
          }

       

          public boolean getAutoUpload() {
              return autoUpload;
          }

       

          public void setAutoUpload(boolean autoUpload) {
              this.autoUpload = autoUpload;
          }

       

          public boolean getUseFlash() {
              return useFlash;
          }

       

          public void setUseFlash(boolean useFlash) {
              this.useFlash = useFlash;
          }

       

          public String getAcceptedTypes() {
              return acceptedTypes;
          }

       

          public void setAcceptedTypes(String acceptedTypes) {
              this.acceptedTypes = acceptedTypes;
          }

       

          public int getSize() {
              if (getFiles().size() > 0) {
                  return getFiles().size();
              } else {
                  return 0;
              }
          }

       

          public PhotoUploadBean() {

       

          }
         
         
          public void paintPhoto(OutputStream stream, Object object) {
             
              log.info( "paintPhoto() called");
             
              boolean rescale = false;
              int width = 0;
              ImageIcon icon = null;
              byte[] data = null;

       

              try {
                  // check if image needs to be resized
                  data = ((Photo) object).getContent();
                  icon = new ImageIcon(data);
                  width = icon.getIconWidth();

       

                  if (  width > 50 ) {
                      width = 50;
                      rescale = true;
                  }

       

                  // rescale if required
                  if (rescale) {
                     
                      double ratio = (double) width / icon.getIconWidth();
                      int height = (int) ( icon.getIconHeight() * ratio );

       

                      int imageType = BufferedImage.TYPE_INT_ARGB;
                      BufferedImage bufferedImage = new BufferedImage(width, height, imageType);
                      Graphics2D g2d = bufferedImage.createGraphics();
                      g2d.setRenderingHint(RenderingHints.KEY_INTERPOLATION, RenderingHints.VALUE_INTERPOLATION_BICUBIC);
                      g2d.drawImage(icon.getImage(), 0, 0, width, height, null);
                      g2d.dispose();

       

                      String formatName = "png";

       

                      ImageIO.write( bufferedImage, formatName, stream);
                  } else {
                      stream.write(data);
                  }

       

              } catch (IOException e) {
                  log.error("I/O exception occurred while generating photo");
              }
          }

       

          public void uploadListener(UploadEvent event) {

       

              UploadItem item = event.getUploadItem();
              Photo newPhoto = new Photo();

       

              try {
                  if (item != null) {
                      newPhoto = new Photo();

       

                      newPhoto.setCaption(item.getFileName());
                      newPhoto.setContent(item.getData());
                      newPhoto.setModified(new Date());
                      newPhoto.setMimeType(item.getContentType());
                      newPhoto.setFileSize(item.getFileSize());
                      newPhoto.setUser(currentUser);

       

                      em.persist(newPhoto);
                      files.add(newPhoto);
                      uploadsAvailable--;

       

                      em.flush();

       

                  }
              } catch (Exception e) {
                  log.info("error: " + e.getMessage());

       

              }

       

          }

       

          @Create
          public void init() {
              log.info("Bean Initialized");
          }

       

          @Destroy
          @Remove
          public void destroy() {
              log.info("Bean Destroyed");
          }

       

      }

       

       

       

      Please any help would be greatly appreciated! Thanks.

       

      Charles.

        • 1. Re: Problems with file upload
          Jay Balunas Master

          Hi Charles,

           

          Great post with lots of details!  I'm going to move this to the user forum because this is just for development/design discussions of the project itself.  General usage questions are in the user forum.

           

          It also means that more people will get a look at your issue, and perhaps have solutions.

           

          Thanks,

          Jay

          • 3. Re: Problems with file upload
            Charles Akalugwu Newbie

            Thanks Nick. I was quite hopeful for a bit. After making all the required changes, and tried to access my facelets page, I got the following error:

             

            /ui/media/addPhoto.xhtml @49,105  value="#{sdh:storeDataAndGetKey(photo)}" Function  'sdh:storeDataAndGetKey' not found

             

            any ideas?

             

            btw, i'm using Richfaces 3.3.3.CR1 and JBoss AS 5.1.0 GA if it helps. Thanks so much.

            • 4. Re: Problems with file upload
              Charles Akalugwu Newbie

              and oh, according to the article referred in the link, "........ 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.........."

               

               

              but when I look at my stack trace, things still seem dependent on JBoss EL.

               

              javax.el.ELException: Function 'sdh:storeDataAndGetKey' not found
                  at org.jboss.el.lang.ExpressionBuilder.visit(ExpressionBuilder.java:187)
                  at org.jboss.el.parser.SimpleNode.accept(SimpleNode.java:129)
                  at org.jboss.el.lang.ExpressionBuilder.prepare(ExpressionBuilder.java:138)
                  at org.jboss.el.lang.ExpressionBuilder.build(ExpressionBuilder.java:152)
                  at org.jboss.el.lang.ExpressionBuilder.createValueExpression(ExpressionBuilder.java:206)
                  at org.jboss.el.ExpressionFactoryImpl.createValueExpression(ExpressionFactoryImpl.java:68)
                  at org.jboss.seam.el.SeamExpressionFactory.createValueExpression(SeamExpressionFactory.java:98)
                  at com.sun.facelets.tag.TagAttribute.getValueExpression(TagAttribute.java:256)

               

               

              hmmm