Primefaces FileUpload is not working with PrettyFaces and Spring Boot

匿名 (未验证) 提交于 2019-12-03 00:59:01

问题:

i am using springboot 1.5.2.RELEASE with JSF 2.2.14 and primefaces 6.1 and prettyfaces 3.4.1.Final my pom file is as follows:

<?xml version="1.0" encoding="UTF-8"?> <project xmlns="http://maven.apache.org/POM/4.0.0"     xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd"     xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">     <modelVersion>4.0.0</modelVersion>      <groupId>org.springframework</groupId>     <artifactId>myapp</artifactId>     <version>1</version>      <parent>         <groupId>org.springframework.boot</groupId>         <artifactId>spring-boot-starter-parent</artifactId>         <version>1.5.2.RELEASE</version>     </parent>      <properties>         <java.version>1.8</java.version>     </properties>      <packaging>war</packaging>      <dependencies>           <dependency>             <groupId>org.springframework.boot</groupId>             <artifactId>spring-boot-starter-actuator</artifactId>         </dependency>            <dependency>             <groupId>org.springframework.boot</groupId>             <artifactId>spring-boot-starter-test</artifactId>             <scope>test</scope>         </dependency>          <dependency>             <groupId>org.springframework.boot</groupId>             <artifactId>spring-boot-starter-web</artifactId>         </dependency>          <dependency>             <groupId>org.springframework.boot</groupId>             <artifactId>spring-boot-starter-data-jpa</artifactId>         </dependency>          <dependency>             <groupId>org.springframework.boot</groupId>             <artifactId>spring-boot-starter-security</artifactId>         </dependency>            <dependency>             <groupId>mysql</groupId>             <artifactId>mysql-connector-java</artifactId>         </dependency>          <dependency>             <groupId>com.sun.faces</groupId>             <artifactId>jsf-api</artifactId>             <version>2.2.14</version>         </dependency>          <dependency>             <groupId>com.sun.faces</groupId>             <artifactId>jsf-impl</artifactId>             <version>2.2.14</version>         </dependency>          <dependency>             <groupId>javax.servlet</groupId>             <artifactId>jstl</artifactId>         </dependency>          <dependency>             <groupId>org.primefaces</groupId>             <artifactId>primefaces</artifactId>             <version>6.1</version>         </dependency>          <dependency>             <groupId>org.ocpsoft.rewrite</groupId>             <artifactId>rewrite-servlet</artifactId>             <version>3.4.1.Final</version>         </dependency>          <dependency>             <groupId>org.ocpsoft.rewrite</groupId>             <artifactId>rewrite-config-prettyfaces</artifactId>             <version>3.4.1.Final</version>         </dependency>           <dependency>             <groupId>org.springframework.boot</groupId>             <artifactId>spring-boot-starter-tomcat</artifactId>             <scope>provided</scope>         </dependency>           <dependency>             <groupId>org.apache.tomcat.embed</groupId>             <artifactId>tomcat-embed-jasper</artifactId>             <scope>provided</scope>         </dependency>          <dependency>             <groupId>org.springframework.boot</groupId>             <artifactId>spring-boot-starter-jersey</artifactId>         </dependency>         <!-- https://mvnrepository.com/artifact/bouncycastle/bcprov-jdk15 -->         <dependency>             <groupId>bouncycastle</groupId>             <artifactId>bcprov-jdk15</artifactId>             <version>140</version>         </dependency>         <!-- https://mvnrepository.com/artifact/commons-codec/commons-codec -->         <dependency>             <groupId>commons-codec</groupId>             <artifactId>commons-codec</artifactId>             <version>1.10</version>         </dependency>           <!-- https://mvnrepository.com/artifact/org.apache.commons/commons-lang3 -->         <dependency>             <groupId>org.apache.commons</groupId>             <artifactId>commons-lang3</artifactId>             <version>3.5</version>         </dependency>         <!-- https://mvnrepository.com/artifact/javax.mail/mail -->         <dependency>             <groupId>javax.mail</groupId>             <artifactId>mail</artifactId>             <version>1.4.7</version>         </dependency>           <!-- https://mvnrepository.com/artifact/javax.jcr/jcr -->         <dependency>             <groupId>javax.jcr</groupId>             <artifactId>jcr</artifactId>             <version>2.0</version>             <scope>provided</scope>         </dependency>         <!-- https://mvnrepository.com/artifact/org.apache.jackrabbit/jackrabbit-core -->         <dependency>             <groupId>org.apache.jackrabbit</groupId>             <artifactId>jackrabbit-core</artifactId>             <version>2.15.2</version>         </dependency>          <!-- https://mvnrepository.com/artifact/org.apache.jackrabbit/jackrabbit-api -->         <dependency>             <groupId>org.apache.jackrabbit</groupId>             <artifactId>jackrabbit-api</artifactId>             <version>2.15.2</version>         </dependency>          <!-- https://mvnrepository.com/artifact/org.apache.jackrabbit/jackrabbit-jcr-commons -->         <dependency>             <groupId>org.apache.jackrabbit</groupId>             <artifactId>jackrabbit-jcr-commons</artifactId>             <version>2.15.2</version>         </dependency>         <!-- https://mvnrepository.com/artifact/org.apache.jackrabbit/jackrabbit-jcr2dav -->         <dependency>             <groupId>org.apache.jackrabbit</groupId>             <artifactId>jackrabbit-jcr2dav</artifactId>             <version>2.15.2</version>             <scope>provided</scope>         </dependency>           <dependency>             <groupId>org.apache.jackrabbit</groupId>             <artifactId>jackrabbit-jcr-rmi</artifactId>             <version>2.15.2</version>         </dependency>          <dependency>             <groupId>commons-validator</groupId>             <artifactId>commons-validator</artifactId>             <version>1.6</version>         </dependency>          <dependency>             <groupId>commons-fileupload</groupId>             <artifactId>commons-fileupload</artifactId>             <version>1.3.3</version>         </dependency>         <dependency>             <groupId>commons-io</groupId>             <artifactId>commons-io</artifactId>             <version>2.5</version>         </dependency>       </dependencies>      <build>         <finalName>myapp</finalName>         <plugins>             <!-- <plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-compiler-plugin</artifactId>                  <configuration> <source>1.6</source> <target>1.6</target> </configuration>                  </plugin> -->              <plugin>                <groupId>org.apache.maven.plugins</groupId>                <artifactId>maven-surefire-plugin</artifactId>                <configuration>                   <argLine>-Dfile.encoding=UTF8</argLine>                </configuration>             </plugin>          </plugins>     </build>      <repositories>         <repository>             <id>spring-releases</id>             <name>Spring Releases</name>             <url>https://repo.spring.io/libs-release</url>         </repository>         <repository>             <id>org.jboss.repository.releases</id>             <name>JBoss Maven Release Repository</name>             <url>https://repository.jboss.org/nexus/content/repositories/releases</url>         </repository>       </repositories>      <pluginRepositories>         <pluginRepository>             <id>spring-releases</id>             <name>Spring Releases</name>             <url>https://repo.spring.io/libs-release</url>         </pluginRepository>     </pluginRepositories>  </project> 

my springboot configuration class is as follows:

package com.myapp;  import java.util.Collections;  import javax.faces.webapp.FacesServlet; import javax.servlet.DispatcherType; import javax.servlet.ServletContext; import javax.servlet.ServletException;  import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.beans.factory.annotation.Qualifier; import org.springframework.beans.factory.config.CustomScopeConfigurer; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; import org.springframework.boot.builder.SpringApplicationBuilder; import org.springframework.boot.web.servlet.FilterRegistrationBean; import org.springframework.boot.web.servlet.ServletContextInitializer; import org.springframework.boot.web.servlet.ServletRegistrationBean; import org.springframework.boot.web.support.SpringBootServletInitializer; import org.springframework.context.annotation.Bean; import org.springframework.web.filter.HiddenHttpMethodFilter;  import com.ocpsoft.pretty.faces.annotation.URLMapping; import com.ocpsoft.pretty.faces.annotation.URLMappings;  @SpringBootApplication @URLMappings(mappings = { @URLMapping(id = "login", pattern = "/login", viewId = "/faces/public/login.xhtml")}) public class Application extends SpringBootServletInitializer {      private static final Logger log = LoggerFactory.getLogger(Application.class);      public static void main(String[] args) {         SpringApplication.run(Application.class);     }      @Override     protected SpringApplicationBuilder configure(SpringApplicationBuilder application) {         return application.sources(Application.class);     }      @Bean     public ServletContextInitializer servletContextCustomizer() {         return new ServletContextInitializer() {             @Override             public void onStartup(ServletContext servletContext) throws ServletException {                 servletContext.setInitParameter("com.sun.faces.forceLoadConfiguration", Boolean.TRUE.toString());                 servletContext.setInitParameter("primefaces.CLIENT_SIDE_VALIDATION", Boolean.TRUE.toString());                 servletContext.setInitParameter("javax.faces.FACELETS_SKIP_COMMENTS", Boolean.TRUE.toString());                 servletContext.setInitParameter("primefaces.FONT_AWESOME", Boolean.TRUE.toString());                 servletContext.setInitParameter("primefaces.UPLOADER", "commons");             }         };     }      @Bean     public static CustomScopeConfigurer customScopeConfigurer() {         CustomScopeConfigurer configurer = new CustomScopeConfigurer();         configurer.setScopes(Collections.<String, Object>singletonMap(FacesViewScope.NAME, new FacesViewScope()));         return configurer;     }      @Bean     public ServletRegistrationBean servletRegistrationBean() {         FacesServlet servlet = new FacesServlet();         ServletRegistrationBean servletRegistrationBean = new ServletRegistrationBean(servlet, "*.jsf");         return servletRegistrationBean;     }      @Bean     public FilterRegistrationBean FileUploadFilter() {         FilterRegistrationBean registration = new FilterRegistrationBean();         registration.setFilter(new org.primefaces.webapp.filter.FileUploadFilter());         registration.setName("PrimeFaces FileUpload Filter");         registration.addUrlPatterns("/*");         registration.setDispatcherTypes(DispatcherType.FORWARD, DispatcherType.REQUEST);         registration.addServletRegistrationBeans(servletRegistrationBean());         registration.setOrder(2);         return registration;     }      @Bean     public FilterRegistrationBean hiddenHttpMethodFilterDisabled(             @Qualifier("hiddenHttpMethodFilter") HiddenHttpMethodFilter filter) {         FilterRegistrationBean filterRegistrationBean = new FilterRegistrationBean(filter);         filterRegistrationBean.setEnabled(false);         return filterRegistrationBean;     }  } 

the xhtml page for upload:

<?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> <html xmlns="http://www.w3.org/1999/xhtml"       xmlns:h="http://java.sun.com/jsf/html"       xmlns:ui="http://java.sun.com/jsf/facelets"       xmlns:p="http://primefaces.org/ui"       xmlns:f="http://xmlns.jcp.org/jsf/core"       xmlns:a="http://xmlns.jcp.org/jsf/passthrough">     <h:body>          <ui:composition template="/template/commonLayout.xhtml">                 <ui:define name="content">                               <h:form enctype="multipart/form-data">                    <p:commandButton value="test" action="#{testBean.test}"/>                    <p:fileUpload fileUploadListener="#{testBean.handleFileUpload}" mode="advanced" dragDropSupport="false"                   multiple="true"  update="messages" />                   <h:messages id="messages"></h:messages>                 </h:form>                        </ui:define>            </ui:composition>      </h:body>  </html> 

the fileupload backing bean is as follows:

package com.myapp.beans;  import java.io.Serializable;  import javax.annotation.PostConstruct;  import org.primefaces.event.FileUploadEvent; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.context.annotation.Scope; import org.springframework.stereotype.Component;   @Component("testBean") @Scope("view") public class TestBean implements Serializable {      private static final long serialVersionUID = -3568561158943789169L;      private static final Logger log = LoggerFactory.getLogger(TestBean.class);      public void handleFileUpload(FileUploadEvent event) {         log.info("####### handleFileUpload,file: " + event.getFile().getFileName());     }     } 

i am running on tomcat 9.0.0.M21 and when choosing the file and clicking upload i get no client side errors and no server side errors and the file is not getting uploaded, although when i turned on primefaces debugging it prints that the file was uploaded:

2017-06-27 07:32:04,926 DEBUG o.p.webapp.filter.FileUploadFilter - Parsing file upload request 2017-06-27 07:32:04,969 DEBUG o.p.webapp.filter.FileUploadFilter - File upload request parsed succesfully, continuing with filter chain with a wrapped multipart request 

but the code in the listener in the backing bean was not invoked.

it seems that the issue is because of prettyfaces, when i remove it from the project, the filter works fine.

i also tried the context.xml solution for the prettyfaces issue:

<?xml version="1.0" encoding="UTF-8"?> <Context allowCasualMultipartParsing="true"> </Context> 

and the problem is not solved.

please advise how to fix this.

回答1:

i figured it out, there are two solutions:

1- Make the DispatcherType for primefaces upload filter FORWARD ONLY

    @Bean     public FilterRegistrationBean FileUploadFilter() {         FilterRegistrationBean registration = new FilterRegistrationBean();         registration.setFilter(new org.primefaces.webapp.filter.FileUploadFilter());         registration.setName("PrimeFaces FileUpload Filter");         registration.setDispatcherTypes(DispatcherType.FORWARD);         return registration;     }      @Bean     public FilterRegistrationBean hiddenHttpMethodFilterDisabled(             @Qualifier("hiddenHttpMethodFilter") HiddenHttpMethodFilter filter) {         FilterRegistrationBean filterRegistrationBean = new FilterRegistrationBean(filter);         filterRegistrationBean.setEnabled(false);         return filterRegistrationBean;     } 

2- If you want the primefaces upload filter dispatcher type to be FORWARD and REQUEST you have to explicitly define the pretty faces rewrite filter:

    @Bean     public FilterRegistrationBean prettyFilter() {         FilterRegistrationBean prettyFilter = new FilterRegistrationBean(new RewriteFilter());         return prettyFilter;     }      @Bean     public FilterRegistrationBean FileUploadFilter() {         FilterRegistrationBean registration = new FilterRegistrationBean();         registration.setFilter(new org.primefaces.webapp.filter.FileUploadFilter());         registration.setName("PrimeFaces FileUpload Filter");         registration.setDispatcherTypes(DispatcherType.FORWARD, DispatcherType.REQUEST);         return registration;     }      @Bean     public FilterRegistrationBean hiddenHttpMethodFilterDisabled(             @Qualifier("hiddenHttpMethodFilter") HiddenHttpMethodFilter filter) {         FilterRegistrationBean filterRegistrationBean = new FilterRegistrationBean(filter);         filterRegistrationBean.setEnabled(false);         return filterRegistrationBean;     } 


回答2:

I might be late on this one but i know it will save someone some time, i had a similar problem with file upload recently using primefaces6.1 and springboot. My solution was to explicitly set the MultipartConfigElement within the ServletRegistrationBean. The compete working configuration is as follows:

@Configuration public class JsfConfig extends SpringBootServletInitializer implements ServletContextAware {      @Override     public void onStartup(ServletContext servletContext) throws ServletException {         super.onStartup(servletContext);         servletContext.setInitParameter("primefaces.CLIENT_SIDE_VALIDATION", "true");         servletContext.setInitParameter("javax.faces.FACELETS_REFRESH_PERIOD", "0");         servletContext.setInitParameter("javax.faces.PROJECT_STAGE", "Development");         servletContext.setInitParameter("javax.faces.FACELETS_SKIP_COMMENTS", Boolean.TRUE.toString());         servletContext.setInitParameter("primefaces.FONT_AWESOME", Boolean.TRUE.toString());         servletContext.setInitParameter("primefaces.UPLOADER", "commons");         servletContext.setInitParameter("facelets.DEVELOPMENT", "true");         servletContext.setInitParameter("primefaces.THEME", "bootstrap");     }      @Bean     public ServletRegistrationBean facesServlet() {         FacesServlet servlet = new FacesServlet();         ServletRegistrationBean registration = new ServletRegistrationBean(servlet, "*.xhtml");         registration.setName("Faces Servlet");         registration.setLoadOnStartup(1);         registration.setMultipartConfig(new                 MultipartConfigElement((String) null));         return registration;     }      @Bean     public ServletListenerRegistrationBean<ConfigureListener> jsfConfigureListener() {         return new ServletListenerRegistrationBean<ConfigureListener>(new ConfigureListener());     }      @Override     public void setServletContext(ServletContext servletContext) {         servletContext.setInitParameter("com.sun.faces.forceLoadConfiguration", Boolean.TRUE.toString());     }      @Bean     public FilterRegistrationBean facesUploadFilterRegistration() {         FilterRegistrationBean registrationBean = new FilterRegistrationBean(new FileUploadFilter(), facesServlet());         registrationBean.setName("PrimeFaces FileUpload Filter");         registrationBean.addUrlPatterns("Faces Servlet");         registrationBean.setDispatcherTypes(DispatcherType.FORWARD, DispatcherType.REQUEST);         return registrationBean;     }      @Bean     public static CustomScopeConfigurer customScopeConfigurer(){         CustomScopeConfigurer configurer = new CustomScopeConfigurer();         Map<String, Object> scopes = new HashMap<String, Object>();         scopes.put("view", new ViewScope());         configurer.setScopes(scopes);         return configurer;     } } 

I hope that helps.



回答3:

In regardless of Spring Boot, I had this problem before between PrettyFaces and PrimeFaces, it can be solved by configuring the right filters mapping in web.xml as the following:

<servlet>     <servlet-name>Faces Servlet</servlet-name>     <servlet-class>javax.faces.webapp.FacesServlet</servlet-class>     <load-on-startup>1</load-on-startup> </servlet>  <servlet-mapping>     <servlet-name>Faces Servlet</servlet-name>     <url-pattern>*.xhtml</url-pattern> </servlet-mapping>       <filter>     <filter-name>Pretty Filter</filter-name>     <filter-class>com.ocpsoft.pretty.PrettyFilter</filter-class> </filter>  <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> 

I'm not sure if this answer would be helpful in your Spring Boot environment, as I don't have a lot of experience in that stack.



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