Search code examples
javajsfseam

seam s:fileupload is always null


I'm trying to use s:fileUpload component, which causes trouble with setting to bean variable. It always returns null. Here's the xhtml:

            <h:form enctype="multipart/form-data">
                <s:fileUpload id="pictureproc" data="#{uploader.file}" />
            <h:commandButton id="doanything"
                action="#{uploader.filehash(pictureproc)}"
                value="Show file hash" />
            </h:form>

And the bean:

@Name("uploader")
@Scope(ScopeType.SESSION)
public class Uploader {
    byte[] file;

    public byte[] getFile() {
        return file;
    }

    public void setFile(byte[] file) {
        this.file = file;
        System.out.println("uploaded");
    }

    public void filehash(byte[] file) {
        System.out.println(file.hashCode()); // here goes the NPE
    }
}

I have included everything in web.xml and components.xml:

<filter>
    <filter-name>Seam Filter</filter-name>
    <filter-class>org.jboss.seam.servlet.SeamFilter</filter-class>
</filter>

<filter-mapping>
    <filter-name>Seam Filter</filter-name>
    <url-pattern>/*</url-pattern>
</filter-mapping>

And components:

    <web:multipart-filter create-temp-files="true"
    max-request-size="10485760" url-pattern="*.seam" />

    <component class="org.jboss.seam.web.MultipartFilter">
        <property name="createTempFiles">true</property>
        <property name="maxRequestSize">1000000</property>
    </component>

And log:

Caused by: javax.faces.el.EvaluationException: java.lang.NullPointerException at javax.faces.component.MethodBindingMethodExpressionAdapter.invoke(MethodBindingMethodExpressionAdapter.java:102) at com.sun.faces.application.ActionListenerImpl.processAction(ActionListenerImpl.java:102) ... 54 more Caused by: java.lang.NullPointerException at com.example.Uploader.filehash(Filter.java:57)

I also tried to log it right inside the setter but it also returns NULL. Seam 2.2, JSF 1.0


Solution

  • Your are sending a null value to your filehash method from you h:commandButton(pictureproc)

    Remove the parameter from your action method to

    <h:form enctype="multipart/form-data">
         <s:fileUpload id="pictureproc" data="#{uploader.file}" />
         <h:commandButton id="doanything"
             action="#{uploader.filehash()}"
             value="Show file hash" />
     </h:form>
    

    Then in your class remove the argument byte[] from the filehash method, and instead reference the class attribute with

    @Name("uploader")
    @Scope(ScopeType.SESSION)
    public class Uploader {
        byte[] file;
    
        public byte[] getFile() {
            return file;
        }
    
        public void setFile(byte[] file) {
            this.file = file;
            System.out.println("uploaded");
        }
    
        public void filehash() {
            System.out.println(this.file.hashCode()); // here goes the NPE
        }
    }
    

    Remember the file is being transferred and stored in the property referenced by your s:fileUpload data component, not by passing its id in your h:commandButton action