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

Unstable Primefaces fileupload listener call

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

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

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

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

在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>

页面上的文件上传组件:

<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>

我在父页面中有 ,如下所示:How to use PrimeFaces p:fileUpload? Listener method is never invoked or UploadedFile is null / throws an error / not usable

和 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的顺序:

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

指定

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

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

但是在指定之后:

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

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