不稳定的 Primefaces 文件上传侦听器调用

问题描述 投票:0回答:2

拥有一个使用 JDK11、Primefaces 8.0、Spring Boot 2.3.0 的 Spring Boot 项目。 将其部署在 tomcat 9.0.35 上。在某些部署中,我的文件上传组件能够很好地触发侦听器方法。在其他情况下,它无法触发它,不会留下任何错误消息或日志。

我尝试过一些重新启动,每次使用相同的版本都会产生相同的结果(上传失败)。但尽管没有触及源代码,另一个构建可以使其工作。

在另一项测试中,我使用完全相同的源代码构建和部署了 4-5 次项目,看到上传在所有项目中都正常工作。对于最后一个测试,我只是在 java 语句的“;”后面添加了一个空格字符更改二进制文件并重新构建、重新部署并注意到文件上传不起作用。

我无法找出行为不稳定的原因。 我被困住了,不知道如何调试它,找出问题所在。有任何建议都欢迎

在 pom.xml 中具有:

    <dependency>
        <groupId>commons-fileupload</groupId>
        <artifactId>commons-fileupload</artifactId>
        <version>1.4</version>
    </dependency>


    <dependency>
       <groupId>com.sun.faces</groupId>
       <artifactId>jsf-api</artifactId>
       <version>2.2.20</version>
    </dependency>
    <dependency>
       <groupId>com.sun.faces</groupId>
       <artifactId>jsf-impl</artifactId>
       <version>2.2.20</version>
    </dependency>

    <dependency>
       <groupId>org.primefaces</groupId>
       <artifactId>primefaces</artifactId>
       <version>8.0</version>
    </dependency>

    <dependency>
        <groupId>com.google.code</groupId>
        <artifactId>kaptcha</artifactId>
        <version>2.3.0</version>
    </dependency>

页面上的FileUpload组件:

<h:form id="bulkDataInsertForm" enctype="multipart/form-data">
  .
  .
    <p:fileUpload id="datafileuploader"
        listener="#{bulkDataInsertBean.handleFileUpload}"
        uploadLabel="upload file"
        cancelLabel="cancel"
        label="choose file"
        update=":bulkDataInsertForm:bulkDataInsertgrowl :bulkDataInsertForm:listFileUploadPanel :bulkDataInsertForm:errorText"
        allowTypes="/(\.|\/)(xlsx)$/"
        sizeLimit="10485760" 
        multiple="false"
        invalidFileMessage="file type error"
        mode="advanced" dragDropSupport="true"
        ajax="true">
    </p:fileUpload>
.
.
</h:form>

我在父页面中有,如下所示:如何使用 PrimeFaces p:fileUpload?监听器方法永远不会被调用或 UploadedFile 为空/抛出错误/不可用

和ServletInitializer:

@EnableEncryptableProperties
@SpringBootApplication
@ComponentScan({ "com.myapp"  })
public class WebApplication extends SpringBootServletInitializer {  

  @Bean
  public ServletRegistrationBean kaptchaServletRegistration() {
    ServletRegistrationBean bean = new ServletRegistrationBean(new KaptchaServlet(), "/kaptcha.jpg");
    return bean;
  }

  @Bean
  public ServletRegistrationBean facesServletRegistration() {
    ServletRegistrationBean registration = new ServletRegistrationBean<>(new FacesServlet(), "*.xhtml");
    registration.setLoadOnStartup(1);
    return registration;
  }

  @Bean
  public ServletContextInitializer servletContextInitializer() {
    return servletContext -> {
        servletContext.setInitParameter("com.sun.faces.forceLoadConfiguration", Boolean.TRUE.toString());
        servletContext.setInitParameter("primefaces.THEME", "blitzer");
        
        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("javax.faces.ENABLE_CDI_RESOLVER_CHAIN", Boolean.TRUE.toString());
      };


  @Bean
  public ServletListenerRegistrationBean<ConfigureListener> jsfConfigureListener() {
    return new ServletListenerRegistrationBean<>(new ConfigureListener()); 
  }


//for setting fileUploadFilter to in front of filterChain - so uploaded file not consumed by other filter
  @Bean
  public FilterRegistrationBean primeFacesFileUploadFilter() {

     FilterRegistrationBean registration = new FilterRegistrationBean(new org.primefaces.webapp.filter.FileUploadFilter(), facesServletRegistration());
    
     registration.addUrlPatterns("/*"); 
    
     registration.setDispatcherTypes(DispatcherType.REQUEST, DispatcherType.FORWARD);
     registration.setName("primeFacesFileUploadFilter");
     registration.setOrder(1);
     return registration;
    }
  }

注意:在一些论坛上,我读到 fileupload 过滤器顺序可以更改,因此其他一些过滤器可能会消耗正在上传的文件流,使 fileupload 过滤器没有输入。 它还必须接受转发的请求。所以我添加了上面显示的“primeFacesFileUploadFilter”,但它没有帮助:

这是添加代码后 ServletContextInitializer 期间过滤器链的顺序:

按顺序在 FilterChain 中过滤名称:[requestContextFilter、Tomcat WebSocket (JSR356) Filter、errorPageFilter、primeFacesFileUploadFilter、characterEncodingFilter、springSecurityFilterChain、formContentFilter]

spring-boot file-upload primefaces
2个回答
1
投票

指定

servletContext.setInitParameter("primefaces.UPLOADER", "native");    

servletContextInitializer 导致文件上传有时成功有时失败(侦听器未触发)。

但是指定之后:

servletContext.setInitParameter("primefaces.UPLOADER", "commons"); 

我没有使用“原生”,而是进行了近 10 次构建、部署和测试,其中所有文件上传均正确触发。当然我仍然不能保证它是绝对的解决方案但是 可能性很大。


0
投票

我还遇到了上传侦听器 bean 根本没有被调用的问题,即使在遵循此处的所有建议之后我也无法使其运行。我使用了 Primefaces 13 和 SpringBoot 3.2.3。

最后我使用了Joinfaces项目,并且fileUpload开始工作,可能还有一些针对Primefaces和Spring的额外设置。

我刚刚将其添加到 pom.xml 中:

<dependencyManagement>
  <dependencies>
    <dependency>
        <groupId>org.joinfaces</groupId>
        <artifactId>joinfaces-bom</artifactId>
        <version>5.2.5</version>
        <type>pom</type>
        <scope>import</scope>
    </dependency>
  </dependencies>
</dependencyManagement>

<dependencies>
  <dependency>
    <groupId>org.joinfaces</groupId>
    <artifactId>primefaces-spring-boot-starter</artifactId>
  </dependency>
© www.soinside.com 2019 - 2024. All rights reserved.