1 2 3 Previous Next 36 Replies Latest reply on Jul 10, 2007 5:27 PM by evl123

    Simplest <s:fileUpload> usage

    yuwono

      I've been hanging around for almost two weeks just to make <s:fileUpload> working.
      Simply want to add upload file capability to seam-registration. I'm using seam-space
      sample as reference and adapt it into stateless version. Not refering to wiki's
      samples cause it using tomahawk, I just want to have it plain and simple.

      Environment used :
      - JBoss AS 4.0.5.GA
      - JBoss Seam 1.2.0.Patch1
      - JBoss IDE for Eclipse
      - default JBoss Seam (upload) jars - no tomahawk.jar, no icefaces, no commons-upload.
      - jboss-seam-ui.jar included

      components.xml :

      <?xml version="1.0" encoding="UTF-8"?>
      <components xmlns="http://jboss.com/products/seam/components"
       xmlns:core="http://jboss.com/products/seam/core"
       xmlns:web="http://jboss.com/products/seam/web"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xsi:schemaLocation=
       "http://jboss.com/products/seam/core http://jboss.com/products/seam/core-1.2.xsd
       http://jboss.com/products/seam/web http://jboss.com/products/seam/web-1.2.xsd
       http://jboss.com/products/seam/components http://jboss.com/products/seam/components-1.2.xsd">
      
       <core:init jndi-pattern="@jndiPattern@"/>
       <core:ejb installed="@embeddedEjb@"/>
      
       <web:multipart-filter create-temp-files="true"
       max-request-size="1000000"
       url-pattern="*.seam"/>
      
      </components>



      web.xml :

      <?xml version="1.0" encoding="UTF-8"?>
      
      <web-app version="2.5"
       xmlns="http://java.sun.com/xml/ns/javaee"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd">
      
       <!-- Seam -->
      
       <listener>
       <listener-class>org.jboss.seam.servlet.SeamListener</listener-class>
       </listener>
      
       <filter>
       <filter-name>Seam Filter</filter-name>
       <filter-class>org.jboss.seam.web.SeamFilter</filter-class>
       </filter>
      
       <filter-mapping>
       <filter-name>Seam Filter</filter-name>
       <url-pattern>/*</url-pattern>
       </filter-mapping>
      
       <!-- MyFaces -->
      
       <listener>
       <listener-class>org.apache.myfaces.webapp.StartupServletContextListener</listener-class>
       </listener>
      
       <context-param>
       <param-name>javax.faces.STATE_SAVING_METHOD</param-name>
       <param-value>client</param-value>
       </context-param>
      
       <context-param>
       <param-name>javax.faces.DEFAULT_SUFFIX</param-name>
       <param-value>.jspx</param-value>
       </context-param>
      
       <servlet>
       <servlet-name>Faces Servlet</servlet-name>
       <servlet-class>javax.faces.webapp.FacesServlet</servlet-class>
       <load-on-startup>1</load-on-startup>
       </servlet>
      
       <!-- Faces Servlet Mapping -->
       <servlet-mapping>
       <servlet-name>Faces Servlet</servlet-name>
       <url-pattern>*.seam</url-pattern>
       </servlet-mapping>
      </web-app>



      application.xml :

      <?xml version="1.0" encoding="UTF-8"?>
      <application xmlns="http://java.sun.com/xml/ns/javaee"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/application_5.xsd"
       version="5">
      
       <display-name>Myapp</display-name>
      
       <module>
       <web>
       <web-uri>seam-myapp.war</web-uri>
       <context-root>/myapp</context-root>
       </web>
       </module>
       <module>
       <ejb>seam-myapp.jar</ejb>
       </module>
       <module>
       <java>jboss-seam.jar</java>
       </module>
       <module>
       <java>el-api.jar</java>
       </module>
       <module>
       <java>el-ri.jar</java>
       </module>
      
      </application>



      jboss-app.xml :

      <jboss-app>
       <loader-repository>
       seam.jboss.org:loader=myapp
       </loader-repository>
      </jboss-app>



      the view .................

      index.jspx :

      <?xml version="1.0"?>
      <jsp:root xmlns:jsp="http://java.sun.com/JSP/Page"
       xmlns:h="http://java.sun.com/jsf/html"
       xmlns:f="http://java.sun.com/jsf/core"
       xmlns:s="http://jboss.com/products/seam/taglib"
       xmlns="http://www.w3.org/1999/xhtml"
       version="2.0">
      <jsp:output doctype-root-element="html"
       doctype-public="-//W3C//DTD XHTML 1.0 Transitional//EN"
       doctype-system="http://www.w3c.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"/>
      <jsp:directive.page contentType="text/html"/>
      <html>
      <body>
      <f:view>
      <h:form enctype="multipart/form-data">
       <table width="100%" border="0" cellspacing="0" cellpadding="0">
       <tr>
       <td>Upload Tasks</td>
       </tr>
       <tr>
       <td width="100%"><br/>File to upload:
       <s:fileUpload data="#{admin.uploadedFile}"/>
       </td>
       </tr>
       <tr>
       <td>
       <h:commandButton value="Submit" action="#{admin.parse}"/>
       </td>
       </tr>
       </table>
      </h:form>
      </f:view>
      </body>
      </html>
      </jsp:root>



      and the code ..................

      Admin.java :

      package myapp;
      
      import javax.ejb.Stateless;
      import org.jboss.seam.annotations.Name;
      
      @Stateless
      @Name("admin")
      public class Admin implements AdminI {
       private byte[] uploadedFile;
      
       public void setUploadedFile(byte[] uploadedFile)
       {
       this.uploadedFile = uploadedFile;
       }
      
       public byte[] getUploadedFile()
       {
       return uploadedFile;
       }
      
       public void parse() throws Exception {
       if(uploadedFile != null)
       System.out.println("size = " + uploadedFile.length);
       else
       System.out.println("uploadedFile is null");
       }
      }



      AdminI.java :

      package myapp;
      
      import javax.ejb.Local;
      
      @Local
      public interface AdminI {
       public void parse() throws Exception;
       public byte[] getUploadedFile();
       public void setUploadedFile(byte[] uploadedFile);
      }



      No error, but it always print "uploadedFile is null". What requirements I might missed?
      Any help will be appreciated.

        • 1. Re: Simplest <s:fileUpload> usage
          pmuir

          This is the nature of a SLSB

          The contents of instance variables are not guaranteed to be preserved across method calls.


          or

          This means that everything a stateless session bean method needs to know has to be passed via the method's parameters.


          • 2. Re: Simplest <s:fileUpload> usage
            yuwono

            Hello petemuir,

            I've tried the SFSB version too, no error but still the same. Can U help?

            package myapp;
            
            import javax.ejb.Remove;
            import javax.ejb.Stateful;
            
            import org.jboss.seam.annotations.Begin;
            import org.jboss.seam.annotations.Destroy;
            import org.jboss.seam.annotations.End;
            import org.jboss.seam.annotations.Name;
            
            @Stateful
            @Name("admin")
            public class Admin implements AdminI {
             private byte[] uploadedFile;
            
             public void setUploadedFile(byte[] uploadedFile)
             {
             this.uploadedFile = uploadedFile;
             }
            
             public byte[] getUploadedFile()
             {
             return uploadedFile;
             }
            
             @Begin
             public void start()
             {
             System.out.println("Start conversation");
             }
            
             @End
             public void parse() throws Exception
             {
             if(uploadedFile != null)
             System.out.println("size = " + uploadedFile.length);
             else
             System.out.println("picture is null");
             }
            
             @Destroy @Remove
             public void destroy() {}
            }


            • 3. Re: Simplest <s:fileUpload> usage
              shane.bryzak

              Does it work with a facelets page instead of a jsp?

              • 4. Re: Simplest <s:fileUpload> usage
                yuwono

                Yes, it works for both SLSB and SFSB above. So, I can't use JSPs or it should be a TODO task for seam (to work along with JSP)?

                Thanks Shane.

                • 5. Re: Simplest <s:fileUpload> usage
                  shane.bryzak

                   

                  "yuwono" wrote:
                  Yes, it works for both SLSB and SFSB above. So, I can't use JSPs or it should be a TODO task for seam (to work along with JSP)?

                  Thanks Shane.


                  I thought JSP's would have been extinct by now, but I guess you could go ahead and raise it in JIRA :)

                  • 6. Re: Simplest <s:fileUpload> usage
                    yuwono

                    I think I will use jsf myself, but its nice to see seam comply with jsp.
                    Raise it on JIRA : http://jira.jboss.org/jira/browse/JBSEAM-1244.

                    Thanks everybody.

                    • 7. Re: Simplest <s:fileUpload> usage

                      This solution of reading uploaded file thru byte[] works. Thank you for sharing.

                      However, I wanted to use a different approach using Backing Bean wrapping org.apache.myfaces.custom.fileupload.UploadedFile component.

                      In my attempt as stated, I found that the Backing Bean was instantiated ok, the file upload Browse and Submit buttons were generated ok but when Submit is clicked, the JSF failed to inject the multipart UploadedFile to it, so the Action listener class received Backing Bean with a null UploadedFile object.
                      The Backing Bean is a Seam component but the UploadedFile is JSF multipart/form-data component.

                      I would appreciate any help shed some light in this.
                      Thanks - landrew.

                      Code snippets as shown:

                      fileUpload.xhtml:
                      ..
                      <h:form enctype="multipart/form-data" >

                      Browse and Pick a File
                      <t:inputFileUpload value="#{uploadBean.uploadedFile}" storage="file" />
                      <h:commandButton value="Submit" action="#{uploader.upload}" />

                      </h:form>
                      ..

                      UploadBean.java (Backing Bean)
                      ..
                      @Name("uploadBean")
                      @Scope(SESSION)
                      public class UploadBean
                      {
                      @In(required=false)
                      private UploadedFile uploadedFile;
                      ..

                      UploadAction.java (Action class JSF Listener)
                      ..
                      @Name("uploader")
                      @Scope(EVENT)
                      public class UploadAction implements UploadActionIF
                      {
                      private final String CLAZZ = this.getClass().toString();

                      /**
                      * Uploaded file wrapper object.
                      */
                      @In(required = false)
                      private UploadBean uploadBean;
                      ..
                      public String upload()
                      {
                      ..

                      Other components:
                      - jboss-4.0.5.GA Server
                      - WEB-INF/tomahawk.taglib.xml
                      - tomahawk-1.1.5.jar
                      - jboss-seam.jar thru Seam-Version: 1.2.0.PATCH1
                      - jsf-facelets.jar Implementation-Version: 1.1.12

                      • 8. Re: Simplest <s:fileUpload> usage
                        hispeedsurfer

                        It's exactly the same behaviour in my app.

                        But I use Facelets(*.xhtml).
                        The strange thing I found out: If I comment s:fileUpload tag, the fields are entered

                        <!--s:fileUpload id="fileupload" data="#{specialreleaseeditor.file}" accept="*/*" fileName="#{specialreleaseeditor.fileName}" contentType="#{specialreleaseeditor.fileContentType}"/-->


                        Without the comment the getter/setter of the fields file, fileName and fileContentType are not called in debug mode.

                        Use Seam 1.2.1 and have configured the app as discriped. No exception is thrown.

                        What can I do, get this working.



                        • 9. Re: Simplest <s:fileUpload> usage
                          shane.bryzak

                           

                          "hispeedsurfer" wrote:
                          It's exactly the same behaviour in my app.


                          Can you please create a minimal, working test case in JIRA so that I can reproduce this issue. I need something that I can easily deploy with minimal effort.

                          • 10. Re: Simplest <s:fileUpload> usage
                            evl123

                            Shane,
                            From my code snippets, can you tell what I did wrong that resulted in null injection of org.apache.myfaces.custom.fileupload.UploadedFile component?
                            Could it be some incompatible issue in the jar files - tomahawk-1.1.5, commons-fileupload-1.1.jar, and commons-io-1.2.jar?
                            I tried switch to tomahawk (1.1.1) but it did not change the outcome. It would be very nice to see UploadedFile created so the file attributes like file name, type, etc. would be available.
                            Please shed some light - Thanks.

                            • 11. Re: Simplest <s:fileUpload> usage
                              shane.bryzak

                               

                              "evl123" wrote:

                              From my code snippets, can you tell what I did wrong that resulted in null injection of org.apache.myfaces.custom.fileupload.UploadedFile component?
                              Could it be some incompatible issue in the jar files - tomahawk-1.1.5, commons-fileupload-1.1.jar, and commons-io-1.2.jar?
                              I tried switch to tomahawk (1.1.1) but it did not change the outcome. It would be very nice to see UploadedFile created so the file attributes like file name, type, etc. would be available.
                              Please shed some light - Thanks.


                              We recommend that you don't use the Tomahawk components. If you use the file upload control provided by Seam then you get all the things you mentioned (file name, content type, etc).

                              • 12. Re: Simplest <s:fileUpload> usage

                                Hi Shane (or anyone),
                                From my configuration and code snippets, can you tell what I missed or what mistakes I made that causes JSF to inject NULL into org.apache.myfaces.custom.fileupload.UploadedFile component?

                                Any advice would be greatly appreciated.

                                Thanks,
                                landrew

                                • 13. Re: Simplest <s:fileUpload> usage
                                  hispeedsurfer

                                  Hi Shane,

                                  have create a report to JIRA.
                                  http://jira.jboss.org/jira/browse/JBSEAM-1360

                                  I never have done this before. Hope is ok.


                                  Thanks

                                  • 14. Re: Simplest <s:fileUpload> usage
                                    hispeedsurfer

                                    Hello Shane,

                                    have you an explanation for this problem?

                                    After press "save" in my example all fields should be accessed.
                                    But the fields still have null values.


                                    Hope you can help.


                                    Thanks

                                    1 2 3 Previous Next