CommandButton does not fire action when <h:form> includes enctype=“multipart/form-data”

和自甴很熟 提交于 2019-12-12 04:24:10

问题


I have already posted a question regarding p:fileuploada few days ago. After digging deeper into this problem I realized that my main issue seems to be of a different origin and I therefore opened up a new question.

I am developing a web app (JSF2.2) for mobile devices where a user can upload a file at several occasions. I want to use Primefaces' p:fileuploadcomponent for this job which does not seem to work. I discovered that the problem seems to be connected with the enctype="multipart/form-data" attribute of <h:form>. Whenever I have this attribute in my form, commandButton does not call the bean method specified in its action=""attribute (neither when using actionListener=""). When I delete the enctype="multipart/form-data" attribute everything works as it should except for the file upload obiously.

For testing and debugging purposes I created an uploadTest.xhtmlpage that looks currently as follows:

<?xml version='1.0' encoding='UTF-8' ?>
<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml"         
      xmlns:p="http://primefaces.org/ui"
      xmlns:f="http://xmlns.jcp.org/jsf/core"
      xmlns:h="http://xmlns.jcp.org/jsf/html">

    <f:view renderKitId="PRIMEFACES_MOBILE" />

    <h:head>
    </h:head>

    <h:body>
        <h:form id="dasistmeineform" enctype="multipart/form-data">
            <p:fileUpload value="#{uploadBean.uploadedFile}" mode="simple"/>
            <p:commandButton action="#{uploadBean.upload}" ajax="false" value="upload" />
        </h:form>
    </h:body>

</html>

To exclude Primefaces from the list of possible error causes I created another test page as well where I only used <h:inputFile> and <h:commandButton> and no primefaces components. This gives me the same result.

Here is my UploadBean.java:

import javax.faces.bean.RequestScoped;
import javax.faces.bean.ManagedBean;
import org.primefaces.model.UploadedFile;

@ManagedBean
@RequestSoped
public class UploadBean {

    private UploadedFile uploadedFile;

    public UploadedFile getUploadedFile() {
        return uploadedFile;
    }

    public void setUploadedFile(UploadedFile uploadedFile) {
        this.uploadedFile = uploadedFile;
    }

    public void upload() {
        if (this.getUploadedFile() != null) {
            System.out.println("Hurray!");
        }
    }



}

My personal guess is that this issue has something to do with the way the application is set up or how JSF is implemented in the app. To troubleshoot this I followed the JSF set up guide by @BalusC. Moreover I followed some of his other troubleshooting guides, including how to troubleshoot p:fileupload and a list of possible causes why a bean method is not invoked when pressing h:commandButton. Nothing has helped so far unfortunately.

I get no error in the Netbeans console and neither in Chrome's developer console. After I press the upload button I can see the HTTP request with the developer tools. The Response has the code 200 so everything should have worked correctly on the HTTP side, right?

The web application uses the following components:

JSF 2.2.13 (Mojarra)

Spring Webflow

Spring MVC

Primefaces 5.3

Omnifaces 1.3

Bootsfaces 0.9.1

The application is deployed and tested on a Jetty 8.1.5 Server directly via Netbeans.

To check if I have all the necessary dependencies downloaded, I'll include the relevant party of my pom.xml (I use maven):

 <dependencies>

        <dependency>
            <groupId>org.glassfish</groupId>
            <artifactId>javax.faces</artifactId>
            <version>2.2.13</version>
        </dependency>


        <dependency>
            <groupId>javax.servlet</groupId>
            <artifactId>javax.servlet-api</artifactId>
            <version>3.0.1</version>
            <scope>provided</scope>
        </dependency>

         <dependency>
            <groupId>javax.servlet</groupId>
            <artifactId>jstl</artifactId>
            <version>1.2</version>
        </dependency>

        <dependency>
            <groupId>commons-io</groupId>
            <artifactId>commons-io</artifactId>
            <version>2.2</version>
        </dependency>

         <dependency>
            <groupId>commons-fileupload</groupId>
            <artifactId>commons-fileupload</artifactId>
            <version>1.3</version>
        </dependency>
</dependencies>

I included commons-io and commons-fileupload to test if p:fileupload would work with the old (prior to Servlet 3.0) way, which it didn't.

Here is my web.xml: (please note that I also tested without the context-param and filter entries for p:fileupload without success):

-->
<web-app 
    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_3_0.xsd"
    version="3.0">

    <description>Webflow Archetype</description>
    <context-param>
        <param-name>primefaces.UPLOADER</param-name>
        <param-value>auto</param-value>
    </context-param>

    <context-param>
        <param-name>contextConfigLocation</param-name>
        <param-value>classpath*:/spring/applicationContext.xml,/WEB-INF/config/web-application-config.xml
        </param-value>
    </context-param>
    <!-- Causes Facelets to refresh templates during development -->
    <context-param>
        <param-name>javax.faces.FACELETS_REFRESH_PERIOD</param-name>
        <param-value>1</param-value>
    </context-param>
    <context-param>
        <param-name>com.sun.faces.expressionFactory</param-name>
        <param-value>org.jboss.el.ExpressionFactoryImpl</param-value>
    </context-param>

    <context-param>
        <param-name>com.sun.faces.sendPoweredByHeader</param-name>
        <param-value>false</param-value>
    </context-param>

    <!-- Disable/Enable PF/M default theme:   -->
    <!--    <context-param>
        <param-name>primefaces.mobile.THEME</param-name>
        <param-value>none</param-value>
    </context-param>-->

    <context-param>
        <param-name>primefaces.THEME</param-name>
        <param-value>cupertino</param-value>
    </context-param>
    <context-param>
        <param-name>primefaces.FONT_AWESOME</param-name>
        <param-value>true</param-value>
    </context-param>
    <context-param>
        <description>Define partial state saving as true/false.</description>
        <param-name>javax.faces.PARTIAL_STATE_SAVING_METHOD</param-name>
        <param-value>false</param-value>
    </context-param>
    <context-param>
        <param-name>javax.faces.DATETIMECONVERTER_DEFAULT_TIMEZONE_IS_SYSTEM_TIMEZONE</param-name>
        <param-value>true</param-value>
    </context-param>
    <context-param>
        <param-name>javax.faces.PROJECT_STAGE</param-name>
        <param-value>Development</param-value>
    </context-param>

    <!-- Custom MarqueeComponent -->
    <context-param>
        <param-name>javax.faces.FACELETS_LIBRARIES</param-name>
        <param-value>/WEB-INF/marquee-taglib.xml</param-value>
    </context-param>
    <context-param>
        <param-name>BootsFaces_USETHEME</param-name>
        <param-value>true</param-value>
    </context-param>

     <servlet>
        <servlet-name>Spring MVC Dispatcher Servlet</servlet-name>
        <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
        <init-param>
            <param-name>contextConfigLocation</param-name>
            <param-value/>
        </init-param>
        <load-on-startup>2</load-on-startup>
        <!--        <multipart-config>
            <max-file-size>10485760</max-file-size>
            <max-request-size>20971520</max-request-size>
            <file-size-threshold>5242880</file-size-threshold>
        </multipart-config>-->
    </servlet>
    <!-- Map all /spring requests to the Dispatcher Servlet for handling -->
    <servlet>
        <servlet-name>Jersey Spring Servlet</servlet-name>
        <servlet-class>com.sun.jersey.spi.spring.container.servlet.SpringServlet</servlet-class>
        <init-param>
            <param-name>com.sun.jersey.config.property.packages</param-name>
            <param-value>at.managementpartners.icosysmobile.rest</param-value>
        </init-param>
    </servlet>



    <servlet>
        <servlet-name>FileServlet</servlet-name>
        <servlet-class>at.managementpartners.icosysmobile.web.util.FileServlet</servlet-class>
    </servlet>



    <servlet-mapping>
        <servlet-name>Spring MVC Dispatcher Servlet</servlet-name>
        <url-pattern>/spring/ *</url-pattern>
    </servlet-mapping>

    <servlet>
        <servlet-name>ImageServlet</servlet-name>
        <servlet-class>at.managementpartners.icosysmobile.web.util.ImageServlet</servlet-class>
    </servlet>
    <!-- Serves static resource content from .jar files such as spring-faces.jar -->
    <!-- Map all /resources requests to the Resource Servlet for handling -->
    <!-- Faces Servlet -->
    <servlet>
        <servlet-name>Faces Servlet</servlet-name>
        <servlet-class>javax.faces.webapp.FacesServlet</servlet-class>
        <load-on-startup>1</load-on-startup> 
        <!--        <multipart-config>
            <max-file-size>10485760</max-file-size>
            <max-request-size>20971520</max-request-size>
            <file-size-threshold>5242880</file-size-threshold>
        </multipart-config>-->
    </servlet>
    <!-- Faces Servlet Mapping -->
     <servlet-mapping>
        <servlet-name>Faces Servlet</servlet-name>
        <url-pattern>/faces/ *</url-pattern>
    </servlet-mapping>

    <servlet-mapping>
        <servlet-name>Faces Servlet</servlet-name>
        <url-pattern>/javax.faces.resource/ *</url-pattern>
    </servlet-mapping>

    <!--   
    <servlet-mapping>
        <servlet-name>Faces Servlet</servlet-name>
        <url-pattern>*.xhtml</url-pattern>
    </servlet-mapping>
    <servlet-mapping>
        <servlet-name>Faces Servlet</servlet-name>
        <url-pattern>*.do</url-pattern>
    </servlet-mapping>

        <servlet-mapping>
            <servlet-name>Faces Servlet</servlet-name>
            <url-pattern>/do/ *</url-pattern>
        </servlet-mapping>
    -->    

    <servlet-mapping>
        <servlet-name>Faces Servlet</servlet-name>
        <url-pattern>*.jsf</url-pattern>
    </servlet-mapping>


    <!-- servlet>
        <servlet-name>Primefaces Resource Servlet</servlet-name>
        <servlet-class>
            org.primefaces.resource.ResourceServlet
        </servlet-class>
    </servlet>
    <servlet-mapping>
        <servlet-name>Primefaces Resource Servlet</servlet-name>
        <url-pattern>/primefaces_resource/*</url-pattern>
    </servlet-mapping -->
    <!-- Welcome files -->
    <servlet-mapping>
        <servlet-name>Jersey Spring Servlet</servlet-name>
        <url-pattern>/rest</url-pattern>
    </servlet-mapping>
    <servlet-mapping>
        <servlet-name>Jersey Spring Servlet</servlet-name>
        <url-pattern>/rest/*</url-pattern>
    </servlet-mapping>
    <!--<servlet-mapping>
        <servlet-name>GetClientHostnameServlet</servlet-name>        
        <url-pattern>/GetClientHostnameServlet</url-pattern>
    </servlet-mapping> -->

    <servlet-mapping>
        <servlet-name>FileServlet</servlet-name>
        <url-pattern>/files/*</url-pattern>
    </servlet-mapping>

    <filter>
        <filter-name>PrimeFaces FileUpload Filter</filter-name>
        <filter-class>org.primefaces.webapp.filter.FileUploadFilter</filter-class>
    </filter>

    <filter-mapping>
        <filter-name>PrimeFaces FileUpload Filter</filter-name>
        <servlet-name>Faces Servlet</servlet-name>
        <dispatcher>FORWARD</dispatcher>
    </filter-mapping>

    <filter>
        <filter-name>ClickjackFilterSameOrigin</filter-name>
        <filter-class>at.managementpartners.icosysmobile.web.util.ClickjackFilter</filter-class>
        <init-param>
            <param-name>mode</param-name>
            <param-value>SAMEORIGIN</param-value>
        </init-param>
    </filter>

    <filter-mapping>
        <filter-name>ClickjackFilterSameOrigin</filter-name>
        <url-pattern>/ *</url-pattern>
    </filter-mapping>

    <filter>
        <filter-name>charEncodingFilter</filter-name>
        <filter-class>org.springframework.web.filter.CharacterEncodingFilter</filter-class>
        <init-param>
            <param-name>encoding</param-name>
            <param-value>UTF-8</param-value>
        </init-param>
        <init-param>
            <param-name>forceEncoding</param-name>
            <param-value>true</param-value>
        </init-param>
    </filter>
    <filter-mapping>
        <filter-name>charEncodingFilter</filter-name>
        <url-pattern>/ *</url-pattern>
    </filter-mapping>

    <listener>
        <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
    </listener>
    <!-- Allows Jetty to serve Faces applications -->
    <listener>
        <listener-class>com.sun.faces.config.ConfigureListener</listener-class>
    </listener>

    <!--    <filter>
        <filter-name>PrimeFaces FileUpload Filter</filter-name>
        <filter-class>
            org.primefaces.webapp.filter.FileUploadFilter
        </filter-class>
    </filter>
    <filter-mapping>
        <filter-name>PrimeFaces FileUpload Filter</filter-name>
        <servlet-name>Spring MVC Dispatcher Servlet</servlet-name>
    </filter-mapping>-->

    <filter>
        <filter-name>springSecurityFilterChain</filter-name>
        <filter-class>org.springframework.web.filter.DelegatingFilterProxy</filter-class>
    </filter>
    <filter-mapping>
        <filter-name>springSecurityFilterChain</filter-name>
        <url-pattern>/ *</url-pattern>
    </filter-mapping>


    <!-- Lebenszeit der Session in Minuten (480 min = 8 Stunden; 180 min = 3 Stunden)    -->
    <session-config>
        <session-timeout>180</session-timeout>
        <cookie-config>
            <secure>true</secure>
        </cookie-config>
    </session-config>

    <mime-mapping>
        <extension>ttf</extension>
        <mime-type>application/x-font-ttf</mime-type>
    </mime-mapping>
    <mime-mapping>
        <extension>woff</extension>
        <mime-type>application/x-font-woff</mime-type>
    </mime-mapping>
    <mime-mapping>
        <extension>woff2</extension>
        <mime-type>application/font-woff2</mime-type>
    </mime-mapping>
    <mime-mapping>
        <extension>eot</extension>
        <mime-type>application/vnd.ms-fontobject</mime-type>
    </mime-mapping>
    <!-- The front controller of this Spring Web application, responsible for handling all application requests -->



    <welcome-file-list>
        <welcome-file>index.jsp</welcome-file>
        <welcome-file>index.html</welcome-file>
    </welcome-file-list>

    <jsp-config>
        <jsp-property-group>
            <url-pattern>*.jsp</url-pattern>
            <trim-directive-whitespaces>false</trim-directive-whitespaces>
        </jsp-property-group>
    </jsp-config>

    <error-page>
        <error-code>500</error-code>
        <location>/WEB-INF/errors/error.xhtml</location>
    </error-page>

    <error-page>
        <error-code>404</error-code>
        <location>/WEB-INF/errors/error.xhtml</location>
    </error-page>

    <error-page>
        <error-code>403</error-code>
        <location>/WEB-INF/errors/error.xhtml</location>
    </error-page>

    <error-page>
        <error-code>402</error-code>
        <location>/WEB-INF/errors/error.xhtml</location>
    </error-page>

    <error-page>
        <error-code>401</error-code>
        <location>/WEB-INF/errors/error.xhtml</location>
    </error-page>

    <error-page>
        <error-code>400</error-code>
        <location>/WEB-INF/errors/error.xhtml</location>
    </error-page>

</web-app>

Please note that I had to seperate ´/*´ with a space (´/ *´) so that the rest of my code wouldn't get formatted as a comment. (If there is a smarter way to do this please don't hesitate to tell me)

Could Spring's MVC Dispatcher Servlet somehow interfere with the upload functionality of Servlet 3.0?

Am I using other components that break the standard behaviour of Servlet 3.0 file upload?

Is my project even set up correctly?

Thank you very much. Even a little hint would be greatly appreciated.

来源:https://stackoverflow.com/questions/39391056/commandbutton-does-not-fire-action-when-hform-includes-enctype-multipart-for

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!